]> git.saurik.com Git - apple/icu.git/blob - icuSources/layoutex/plruns.cpp
ICU-511.35.tar.gz
[apple/icu.git] / icuSources / layoutex / plruns.cpp
1 /*
2 *
3 * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
4 *
5 */
6
7 #include "layout/LETypes.h"
8 #include "layout/loengine.h"
9 #include "layout/plruns.h"
10
11 #include "unicode/locid.h"
12
13 #include "layout/LayoutEngine.h"
14 #include "layout/RunArrays.h"
15
16 U_NAMESPACE_USE
17
18 U_CAPI pl_fontRuns * U_EXPORT2
19 pl_openFontRuns(const le_font **fonts,
20 const le_int32 *limits,
21 le_int32 count)
22 {
23 return (pl_fontRuns *) new FontRuns((const LEFontInstance **) fonts, limits, count);
24 }
25
26 U_CAPI pl_fontRuns * U_EXPORT2
27 pl_openEmptyFontRuns(le_int32 initialCapacity)
28 {
29 return (pl_fontRuns *) new FontRuns(initialCapacity);
30 }
31
32 U_CAPI void U_EXPORT2
33 pl_closeFontRuns(pl_fontRuns *fontRuns)
34 {
35 FontRuns *fr = (FontRuns *) fontRuns;
36
37 delete fr;
38 }
39
40 U_CAPI le_int32 U_EXPORT2
41 pl_getFontRunCount(const pl_fontRuns *fontRuns)
42 {
43 const FontRuns *fr = (const FontRuns *) fontRuns;
44
45 if (fr == NULL) {
46 return -1;
47 }
48
49 return fr->getCount();
50 }
51
52 U_CAPI void U_EXPORT2
53 pl_resetFontRuns(pl_fontRuns *fontRuns)
54 {
55 FontRuns *fr = (FontRuns *) fontRuns;
56
57 if (fr != NULL) {
58 fr->reset();
59 }
60 }
61
62 U_CAPI le_int32 U_EXPORT2
63 pl_getFontRunLastLimit(const pl_fontRuns *fontRuns)
64 {
65 const FontRuns *fr = (const FontRuns *) fontRuns;
66
67 if (fr == NULL) {
68 return -1;
69 }
70
71 return fr->getLimit();
72 }
73
74 U_CAPI le_int32 U_EXPORT2
75 pl_getFontRunLimit(const pl_fontRuns *fontRuns,
76 le_int32 run)
77 {
78 const FontRuns *fr = (const FontRuns *) fontRuns;
79
80 if (fr == NULL) {
81 return -1;
82 }
83
84 return fr->getLimit(run);
85 }
86
87 U_CAPI const le_font * U_EXPORT2
88 pl_getFontRunFont(const pl_fontRuns *fontRuns,
89 le_int32 run)
90 {
91 const FontRuns *fr = (const FontRuns *) fontRuns;
92
93 if (fr == NULL) {
94 return NULL;
95 }
96
97 return (const le_font *) fr->getFont(run);
98 }
99
100 U_CAPI le_int32 U_EXPORT2
101 pl_addFontRun(pl_fontRuns *fontRuns,
102 const le_font *font,
103 le_int32 limit)
104 {
105 FontRuns *fr = (FontRuns *) fontRuns;
106
107 if (fr == NULL) {
108 return -1;
109 }
110
111 return fr->add((const LEFontInstance *) font, limit);
112 }
113
114 U_CAPI pl_valueRuns * U_EXPORT2
115 pl_openValueRuns(const le_int32 *values,
116 const le_int32 *limits,
117 le_int32 count)
118 {
119 return (pl_valueRuns *) new ValueRuns(values, limits, count);
120 }
121
122 U_CAPI pl_valueRuns * U_EXPORT2
123 pl_openEmptyValueRuns(le_int32 initialCapacity)
124 {
125 return (pl_valueRuns *) new ValueRuns(initialCapacity);
126 }
127
128 U_CAPI void U_EXPORT2
129 pl_closeValueRuns(pl_valueRuns *valueRuns)
130 {
131 ValueRuns *vr = (ValueRuns *) valueRuns;
132
133 delete vr;
134 }
135
136 U_CAPI le_int32 U_EXPORT2
137 pl_getValueRunCount(const pl_valueRuns *valueRuns)
138 {
139 const ValueRuns *vr = (const ValueRuns *) valueRuns;
140
141 if (vr == NULL) {
142 return -1;
143 }
144
145 return vr->getCount();
146 }
147
148 U_CAPI void U_EXPORT2
149 pl_resetValueRuns(pl_valueRuns *valueRuns)
150 {
151 ValueRuns *vr = (ValueRuns *) valueRuns;
152
153 if (vr != NULL) {
154 vr->reset();
155 }
156 }
157
158 U_CAPI le_int32 U_EXPORT2
159 pl_getValueRunLastLimit(const pl_valueRuns *valueRuns)
160 {
161 const ValueRuns *vr = (const ValueRuns *) valueRuns;
162
163 if (vr == NULL) {
164 return -1;
165 }
166
167 return vr->getLimit();
168 }
169
170 U_CAPI le_int32 U_EXPORT2
171 pl_getValueRunLimit(const pl_valueRuns *valueRuns,
172 le_int32 run)
173 {
174 const ValueRuns *vr = (const ValueRuns *) valueRuns;
175
176 if (vr == NULL) {
177 return -1;
178 }
179
180 return vr->getLimit(run);
181 }
182
183 U_CAPI le_int32 U_EXPORT2
184 pl_getValueRunValue(const pl_valueRuns *valueRuns,
185 le_int32 run)
186 {
187 const ValueRuns *vr = (const ValueRuns *) valueRuns;
188
189 if (vr == NULL) {
190 return -1;
191 }
192
193 return vr->getValue(run);
194 }
195
196 U_CAPI le_int32 U_EXPORT2
197 pl_addValueRun(pl_valueRuns *valueRuns,
198 le_int32 value,
199 le_int32 limit)
200 {
201 ValueRuns *vr = (ValueRuns *) valueRuns;
202
203 if (vr == NULL) {
204 return -1;
205 }
206
207 return vr->add(value, limit);
208 }
209
210 U_NAMESPACE_BEGIN
211 class ULocRuns : public LocaleRuns
212 {
213 public:
214 /**
215 * Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales
216 * and limit indices.
217 *
218 * @param locales is the address of an array of locale name strings. This array,
219 * and the <code>Locale</code> objects to which it points, must remain valid until
220 * the <code>LocaleRuns</code> object is destroyed.
221 *
222 * @param limits is the address of an array of limit indices. This array must remain valid until the
223 * <code>LocaleRuns</code> object is destroyed.
224 *
225 * @param count is the number of entries in the two arrays.
226 *
227 * @draft ICU 3.8
228 */
229 ULocRuns(const char **locales, const le_int32 *limits, le_int32 count);
230
231 /**
232 * Construct an empty <code>LoIDRuns</code> object. Clients can add locale and limit
233 * indices arrays using the <code>add</code> method.
234 *
235 * @param initialCapacity is the initial size of the locale and limit indices arrays. If
236 * this value is zero, no arrays will be allocated.
237 *
238 * @see add
239 *
240 * @draft ICU 3.8
241 */
242 ULocRuns(le_int32 initialCapacity);
243
244 /**
245 * The destructor; virtual so that subclass destructors are invoked as well.
246 *
247 * @draft ICU 3.8
248 */
249 virtual ~ULocRuns();
250
251 /**
252 * Get the name of the locale assoicated with the given run
253 * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
254 * limit index.
255 *
256 * @param run is the index into the font and limit indices arrays.
257 *
258 * @return the locale name associated with the given text run.
259 *
260 * @see RunArray::getLimit
261 *
262 * @draft ICU 3.8
263 */
264 const char *getLocaleName(le_int32 run) const;
265
266 /**
267 * Add a <code>Locale</code> and limit index pair to the data arrays and return
268 * the run index where the data was stored. This method calls
269 * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
270 *
271 * If the <code>ULocRuns</code> object was created with a client-supplied
272 * locale and limit indices arrays, this method will return a run index of -1.
273 *
274 * Subclasses should not override this method. Rather they should provide a new <code>add</code>
275 * method which takes a locale name and a limit index along with whatever other data they implement.
276 * The new <code>add</code> method should first call this method to grow the font and limit indices
277 * arrays, and use the returned run index to store data their own arrays.
278 *
279 * @param locale is the name of the locale to add. This object must remain valid
280 * until the <code>ULocRuns</code> object is destroyed.
281 *
282 * @param limit is the limit index to add
283 *
284 * @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored.
285 *
286 * @draft ICU 3.8
287 */
288 le_int32 add(const char *locale, le_int32 limit);
289
290 /**
291 * ICU "poor man's RTTI", returns a UClassID for this class.
292 *
293 * @draft ICU 3.8
294 */
295 static inline UClassID getStaticClassID();
296
297 /**
298 * ICU "poor man's RTTI", returns a UClassID for the actual class.
299 *
300 * @draft ICU 3.8
301 */
302 virtual inline UClassID getDynamicClassID() const;
303
304 protected:
305 virtual void init(le_int32 capacity);
306 virtual void grow(le_int32 capacity);
307
308 private:
309
310 inline ULocRuns();
311 inline ULocRuns(const ULocRuns &other);
312 inline ULocRuns &operator=(const ULocRuns & /*other*/) { return *this; };
313 const char **fLocaleNames;
314 Locale **fLocalesCopy;
315 };
316
317 inline ULocRuns::ULocRuns()
318 : LocaleRuns(0), fLocaleNames(NULL)
319 {
320 // nothing else to do...
321 }
322
323 inline ULocRuns::ULocRuns(const ULocRuns & /*other*/)
324 : LocaleRuns(0), fLocaleNames(NULL)
325 {
326 // nothing else to do...
327 }
328
329 static const Locale **getLocales(const char **localeNames, le_int32 count)
330 {
331 Locale **locales = LE_NEW_ARRAY(Locale *, count);
332
333 for (int i = 0; i < count; i += 1) {
334 locales[i] = new Locale(Locale::createFromName(localeNames[i]));
335 }
336
337 return (const Locale **) locales;
338 }
339
340 ULocRuns::ULocRuns(const char **locales, const le_int32 *limits, le_int32 count)
341 : LocaleRuns(getLocales(locales, count), limits, count), fLocaleNames(locales)
342 {
343 // nothing else to do...
344 }
345
346 ULocRuns::ULocRuns(le_int32 initialCapacity)
347 : LocaleRuns(initialCapacity), fLocaleNames(NULL)
348 {
349 if(initialCapacity > 0) {
350 fLocaleNames = LE_NEW_ARRAY(const char *, initialCapacity);
351 }
352 }
353
354 ULocRuns::~ULocRuns()
355 {
356 le_int32 count = getCount();
357
358 for(int i = 0; i < count; i += 1) {
359 delete fLocales[i];
360 }
361
362 if (fClientArrays) {
363 LE_DELETE_ARRAY(fLocales);
364 fLocales = NULL;
365 } else {
366 LE_DELETE_ARRAY(fLocaleNames);
367 fLocaleNames = NULL;
368 }
369 }
370
371 void ULocRuns::init(le_int32 capacity)
372 {
373 LocaleRuns::init(capacity);
374 fLocaleNames = LE_NEW_ARRAY(const char *, capacity);
375 }
376
377 void ULocRuns::grow(le_int32 capacity)
378 {
379 LocaleRuns::grow(capacity);
380 fLocaleNames = (const char **) LE_GROW_ARRAY(fLocaleNames, capacity);
381 }
382
383 le_int32 ULocRuns::add(const char *locale, le_int32 limit)
384 {
385 Locale *loc = new Locale(Locale::createFromName(locale));
386 le_int32 index = LocaleRuns::add(loc, limit);
387
388 if (index >= 0) {
389 char **localeNames = (char **) fLocaleNames;
390
391 localeNames[index] = (char *) locale;
392 }
393
394 return index;
395 }
396
397 const char *ULocRuns::getLocaleName(le_int32 run) const
398 {
399 if (run < 0 || run >= getCount()) {
400 return NULL;
401 }
402
403 return fLocaleNames[run];
404 }
405 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ULocRuns)
406 U_NAMESPACE_END
407
408 U_CAPI pl_localeRuns * U_EXPORT2
409 pl_openLocaleRuns(const char **locales,
410 const le_int32 *limits,
411 le_int32 count)
412 {
413 return (pl_localeRuns *) new ULocRuns(locales, limits, count);
414 }
415
416 U_CAPI pl_localeRuns * U_EXPORT2
417 pl_openEmptyLocaleRuns(le_int32 initialCapacity)
418 {
419 return (pl_localeRuns *) new ULocRuns(initialCapacity);
420 }
421
422 U_CAPI void U_EXPORT2
423 pl_closeLocaleRuns(pl_localeRuns *localeRuns)
424 {
425 ULocRuns *lr = (ULocRuns *) localeRuns;
426
427 delete lr;
428 }
429
430 U_CAPI le_int32 U_EXPORT2
431 pl_getLocaleRunCount(const pl_localeRuns *localeRuns)
432 {
433 const ULocRuns *lr = (const ULocRuns *) localeRuns;
434
435 if (lr == NULL) {
436 return -1;
437 }
438
439 return lr->getCount();
440 }
441
442 U_CAPI void U_EXPORT2
443 pl_resetLocaleRuns(pl_localeRuns *localeRuns)
444 {
445 ULocRuns *lr = (ULocRuns *) localeRuns;
446
447 if (lr != NULL) {
448 lr->reset();
449 }
450 }
451
452 U_CAPI le_int32 U_EXPORT2
453 pl_getLocaleRunLastLimit(const pl_localeRuns *localeRuns)
454 {
455 const ULocRuns *lr = (const ULocRuns *) localeRuns;
456
457 if (lr == NULL) {
458 return -1;
459 }
460
461 return lr->getLimit();
462 }
463
464 U_CAPI le_int32 U_EXPORT2
465 pl_getLocaleRunLimit(const pl_localeRuns *localeRuns,
466 le_int32 run)
467 {
468 const ULocRuns *lr = (const ULocRuns *) localeRuns;
469
470 if (lr == NULL) {
471 return -1;
472 }
473
474 return lr->getLimit(run);
475 }
476
477 U_CAPI const char * U_EXPORT2
478 pl_getLocaleRunLocale(const pl_localeRuns *localeRuns,
479 le_int32 run)
480 {
481 const ULocRuns *lr = (const ULocRuns *) localeRuns;
482
483 if (lr == NULL) {
484 return NULL;
485 }
486
487 return lr->getLocaleName(run);
488 }
489
490 U_CAPI le_int32 U_EXPORT2
491 pl_addLocaleRun(pl_localeRuns *localeRuns,
492 const char *locale,
493 le_int32 limit)
494 {
495 ULocRuns *lr = (ULocRuns *) localeRuns;
496
497 if (lr == NULL) {
498 return -1;
499 }
500
501 return lr->add(locale, limit);
502 }