1 /*
2 **********************************************************************
3 * Copyright (C) 2003-2008, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 */
7
8 #ifndef __RUNARRAYS_H
9
10 #define __RUNARRAYS_H
11
12 #include "layout/LETypes.h"
13 #include "layout/LEFontInstance.h"
14
15 #include "unicode/utypes.h"
16 #include "unicode/locid.h"
17
18 /**
19 * \file
20 * \brief C++ API: base class for building classes which represent data that is associated with runs of text.
21 */
22
23 U_NAMESPACE_BEGIN
24
25 /**
26 * The initial size of an array if it is unspecified.
27 *
28 * @stable ICU 3.2
29 */
30 #define INITIAL_CAPACITY 16
31
32 /**
33 * When an array needs to grow, it will double in size until
34 * it becomes this large, then it will grow by this amount.
35 *
36 * @stable ICU 3.2
37 */
38 #define CAPACITY_GROW_LIMIT 128
39
40 /**
41 * The <code>RunArray</code> class is a base class for building classes
42 * which represent data that is associated with runs of text. This class
43 * maintains an array of limit indices into the text, subclasses
44 * provide one or more arrays of data.
45 *
46 * @stable ICU 3.2
47 */
48 class U_LAYOUTEX_API RunArray : public UObject
49 {
50 public:
51 /**
52 * Construct a <code>RunArray</code> object from a pre-existing
53 * array of limit indices.
54 *
55 * @param limits is an array of limit indices. This array must remain
56 * valid until the <code>RunArray</code> object is destroyed.
57 *
58 * @param count is the number of entries in the limit array.
59 *
60 * @stable ICU 3.2
61 */
62 inline RunArray(const le_int32 *limits, le_int32 count);
63
64 /**
65 * Construct an empty <code>RunArray</code> object. Clients can add limit
66 * indices array using the <code>add</code> method.
67 *
68 * @param initialCapacity is the initial size of the limit indices array. If
69 * this value is zero, no array will be allocated.
70 *
71 * @see add
72 *
73 * @stable ICU 3.2
74 */
75 RunArray(le_int32 initialCapacity);
76
77 /**
78 * The destructor; virtual so that subclass destructors are invoked as well.
79 *
80 * @stable ICU 3.2
81 */
82 virtual ~RunArray();
83
84 /**
85 * Get the number of entries in the limit indices array.
86 *
87 * @return the number of entries in the limit indices array.
88 *
89 * @stable ICU 3.2
90 */
91 inline le_int32 getCount() const;
92
93 /**
94 * Reset the limit indices array. This method sets the number of entries in the
95 * limit indices array to zero. It does not delete the array.
96 *
97 * Note: Subclass arrays will also be reset and not deleted.
98 *
99 * @stable ICU 3.6
100 */
101 inline void reset();
102
103 /**
104 * Get the last limit index. This is the number of characters in
105 * the text.
106 *
107 * @return the last limit index.
108 *
109 * @stable ICU 3.2
110 */
111 inline le_int32 getLimit() const;
112
113 /**
114 * Get the limit index for a particular run of text.
115 *
116 * @param run is the run. This is an index into the limit index array.
117 *
118 * @return the limit index for the run, or -1 if <code>run</code> is out of bounds.
119 *
120 * @stable ICU 3.2
121 */
122 inline le_int32 getLimit(le_int32 run) const;
123
124 /**
125 * Add a limit index to the limit indices array and return the run index
126 * where it was stored. If the array does not exist, it will be created by
127 * calling the <code>init</code> method. If it is full, it will be grown by
128 * calling the <code>grow</code> method.
129 *
130 * If the <code>RunArray</code> object was created with a client-supplied
131 * limit indices array, this method will return a run index of -1.
132 *
133 * Subclasses should not override this method. Rather they should provide
134 * a new <code>add</code> method which takes a limit index along with whatever
135 * other data they implement. The new <code>add</code> method should
136 * first call this method to grow the data arrays, and use the return value
137 * to store the data in their own arrays.
138 *
139 * @param limit is the limit index to add to the array.
140 *
141 * @return the run index where the limit index was stored, or -1 if the limit index cannt be stored.
142 *
143 * @see init
144 * @see grow
145 *
146 * @stable ICU 3.2
147 */
148 le_int32 add(le_int32 limit);
149
150 /**
151 * ICU "poor man's RTTI", returns a UClassID for this class.
152 *
153 * @stable ICU 3.2
154 */
getStaticClassID()155 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
156
157 /**
158 * ICU "poor man's RTTI", returns a UClassID for the actual class.
159 *
160 * @stable ICU 3.2
161 */
getDynamicClassID()162 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
163
164 protected:
165 /**
166 * Create a data array with the given initial size. This method will be
167 * called by the <code>add</code> method if there is no limit indices
168 * array. Subclasses which override this method must also call it from
169 * the overriding method to create the limit indices array.
170 *
171 * @param capacity is the initial size of the data array.
172 *
173 * @see add
174 *
175 * @stable ICU 3.2
176 */
177 virtual void init(le_int32 capacity);
178
179 /**
180 * Grow a data array to the given initial size. This method will be
181 * called by the <code>add</code> method if the limit indices
182 * array is full. Subclasses which override this method must also call it from
183 * the overriding method to grow the limit indices array.
184 *
185 * @param capacity is the initial size of the data array.
186 *
187 * @see add
188 *
189 * @stable ICU 3.2
190 */
191 virtual void grow(le_int32 capacity);
192
193 /**
194 * Set by the constructors to indicate whether
195 * or not the client supplied the data arrays.
196 * If they were supplied by the client, the
197 * <code>add</code> method won't change the arrays
198 * and the destructor won't delete them.
199 *
200 * @stable ICU 3.2
201 */
202 le_bool fClientArrays;
203
204 private:
205 /**
206 * The address of this static class variable serves as this class's ID
207 * for ICU "poor man's RTTI".
208 */
209 static const char fgClassID;
210
211 le_int32 ensureCapacity();
212
213 inline RunArray();
214 inline RunArray(const RunArray & /*other*/);
215 inline RunArray &operator=(const RunArray & /*other*/) { return *this; };
216
217 const le_int32 *fLimits;
218 le_int32 fCount;
219 le_int32 fCapacity;
220 };
221
RunArray()222 inline RunArray::RunArray()
223 : UObject(), fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(0)
224 {
225 // nothing else to do...
226 }
227
RunArray(const RunArray &)228 inline RunArray::RunArray(const RunArray & /*other*/)
229 : UObject(), fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(0)
230 {
231 // nothing else to do...
232 }
233
RunArray(const le_int32 * limits,le_int32 count)234 inline RunArray::RunArray(const le_int32 *limits, le_int32 count)
235 : UObject(), fClientArrays(TRUE), fLimits(limits), fCount(count), fCapacity(count)
236 {
237 // nothing else to do...
238 }
239
getCount()240 inline le_int32 RunArray::getCount() const
241 {
242 return fCount;
243 }
244
reset()245 inline void RunArray::reset()
246 {
247 fCount = 0;
248 }
249
getLimit(le_int32 run)250 inline le_int32 RunArray::getLimit(le_int32 run) const
251 {
252 if (run < 0 || run >= fCount) {
253 return -1;
254 }
255
256 return fLimits[run];
257 }
258
getLimit()259 inline le_int32 RunArray::getLimit() const
260 {
261 return getLimit(fCount - 1);
262 }
263
264 /**
265 * The <code>FontRuns</code> class associates pointers to <code>LEFontInstance</code>
266 * objects with runs of text.
267 *
268 * @stable ICU 3.2
269 */
270 class U_LAYOUTEX_API FontRuns : public RunArray
271 {
272 public:
273 /**
274 * Construct a <code>FontRuns</code> object from pre-existing arrays of fonts
275 * and limit indices.
276 *
277 * @param fonts is the address of an array of pointers to <code>LEFontInstance</code> objects. This
278 * array, and the <code>LEFontInstance</code> objects to which it points must remain
279 * valid until the <code>FontRuns</code> object is destroyed.
280 *
281 * @param limits is the address of an array of limit indices. This array must remain valid until
282 * the <code>FontRuns</code> object is destroyed.
283 *
284 * @param count is the number of entries in the two arrays.
285 *
286 * @stable ICU 3.2
287 */
288 inline FontRuns(const LEFontInstance **fonts, const le_int32 *limits, le_int32 count);
289
290 /**
291 * Construct an empty <code>FontRuns</code> object. Clients can add font and limit
292 * indices arrays using the <code>add</code> method.
293 *
294 * @param initialCapacity is the initial size of the font and limit indices arrays. If
295 * this value is zero, no arrays will be allocated.
296 *
297 * @see add
298 *
299 * @stable ICU 3.2
300 */
301 FontRuns(le_int32 initialCapacity);
302
303 /**
304 * The destructor; virtual so that subclass destructors are invoked as well.
305 *
306 * @stable ICU 3.2
307 */
308 virtual ~FontRuns();
309
310 /**
311 * Get the <code>LEFontInstance</code> object assoicated with the given run
312 * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
313 * limit index.
314 *
315 * @param run is the index into the font and limit indices arrays.
316 *
317 * @return the <code>LEFontInstance</code> associated with the given text run.
318 *
319 * @see RunArray::getLimit
320 *
321 * @stable ICU 3.2
322 */
323 const LEFontInstance *getFont(le_int32 run) const;
324
325
326 /**
327 * Add an <code>LEFontInstance</code> and limit index pair to the data arrays and return
328 * the run index where the data was stored. This method calls
329 * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
330 *
331 * If the <code>FontRuns</code> object was created with a client-supplied
332 * font and limit indices arrays, this method will return a run index of -1.
333 *
334 * Subclasses should not override this method. Rather they should provide a new <code>add</code>
335 * method which takes a font and a limit index along with whatever other data they implement.
336 * The new <code>add</code> method should first call this method to grow the font and limit indices
337 * arrays, and use the returned run index to store data their own arrays.
338 *
339 * @param font is the address of the <code>LEFontInstance</code> to add. This object must
340 * remain valid until the <code>FontRuns</code> object is destroyed.
341 *
342 * @param limit is the limit index to add
343 *
344 * @return the run index where the font and limit index were stored, or -1 if the data cannot be stored.
345 *
346 * @stable ICU 3.2
347 */
348 le_int32 add(const LEFontInstance *font, le_int32 limit);
349
350 /**
351 * ICU "poor man's RTTI", returns a UClassID for this class.
352 *
353 * @stable ICU 3.2
354 */
getStaticClassID()355 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
356
357 /**
358 * ICU "poor man's RTTI", returns a UClassID for the actual class.
359 *
360 * @stable ICU 3.2
361 */
getDynamicClassID()362 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
363
364 protected:
365 virtual void init(le_int32 capacity);
366 virtual void grow(le_int32 capacity);
367
368 private:
369
370 inline FontRuns();
371 inline FontRuns(const FontRuns &other);
372 inline FontRuns &operator=(const FontRuns & /*other*/) { return *this; };
373
374 /**
375 * The address of this static class variable serves as this class's ID
376 * for ICU "poor man's RTTI".
377 */
378 static const char fgClassID;
379
380 const LEFontInstance **fFonts;
381 };
382
FontRuns()383 inline FontRuns::FontRuns()
384 : RunArray(0), fFonts(NULL)
385 {
386 // nothing else to do...
387 }
388
FontRuns(const FontRuns &)389 inline FontRuns::FontRuns(const FontRuns & /*other*/)
390 : RunArray(0), fFonts(NULL)
391 {
392 // nothing else to do...
393 }
394
FontRuns(const LEFontInstance ** fonts,const le_int32 * limits,le_int32 count)395 inline FontRuns::FontRuns(const LEFontInstance **fonts, const le_int32 *limits, le_int32 count)
396 : RunArray(limits, count), fFonts(fonts)
397 {
398 // nothing else to do...
399 }
400
401 /**
402 * The <code>LocaleRuns</code> class associates pointers to <code>Locale</code>
403 * objects with runs of text.
404 *
405 * @stable ICU 3.2
406 */
407 class U_LAYOUTEX_API LocaleRuns : public RunArray
408 {
409 public:
410 /**
411 * Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales
412 * and limit indices.
413 *
414 * @param locales is the address of an array of pointers to <code>Locale</code> objects. This array,
415 * and the <code>Locale</code> objects to which it points, must remain valid until
416 * the <code>LocaleRuns</code> object is destroyed.
417 *
418 * @param limits is the address of an array of limit indices. This array must remain valid until the
419 * <code>LocaleRuns</code> object is destroyed.
420 *
421 * @param count is the number of entries in the two arrays.
422 *
423 * @stable ICU 3.2
424 */
425 inline LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count);
426
427 /**
428 * Construct an empty <code>LocaleRuns</code> object. Clients can add locale and limit
429 * indices arrays using the <code>add</code> method.
430 *
431 * @param initialCapacity is the initial size of the locale and limit indices arrays. If
432 * this value is zero, no arrays will be allocated.
433 *
434 * @see add
435 *
436 * @stable ICU 3.2
437 */
438 LocaleRuns(le_int32 initialCapacity);
439
440 /**
441 * The destructor; virtual so that subclass destructors are invoked as well.
442 *
443 * @stable ICU 3.2
444 */
445 virtual ~LocaleRuns();
446
447 /**
448 * Get the <code>Locale</code> object assoicated with the given run
449 * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
450 * limit index.
451 *
452 * @param run is the index into the font and limit indices arrays.
453 *
454 * @return the <code>Locale</code> associated with the given text run.
455 *
456 * @see RunArray::getLimit
457 *
458 * @stable ICU 3.2
459 */
460 const Locale *getLocale(le_int32 run) const;
461
462
463 /**
464 * Add a <code>Locale</code> and limit index pair to the data arrays and return
465 * the run index where the data was stored. This method calls
466 * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
467 *
468 * If the <code>LocaleRuns</code> object was created with a client-supplied
469 * locale and limit indices arrays, this method will return a run index of -1.
470 *
471 * Subclasses should not override this method. Rather they should provide a new <code>add</code>
472 * method which takes a locale and a limit index along with whatever other data they implement.
473 * The new <code>add</code> method should first call this method to grow the font and limit indices
474 * arrays, and use the returned run index to store data their own arrays.
475 *
476 * @param locale is the address of the <code>Locale</code> to add. This object must remain valid
477 * until the <code>LocaleRuns</code> object is destroyed.
478 *
479 * @param limit is the limit index to add
480 *
481 * @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored.
482 *
483 * @stable ICU 3.2
484 */
485 le_int32 add(const Locale *locale, le_int32 limit);
486
487 /**
488 * ICU "poor man's RTTI", returns a UClassID for this class.
489 *
490 * @stable ICU 3.2
491 */
getStaticClassID()492 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
493
494 /**
495 * ICU "poor man's RTTI", returns a UClassID for the actual class.
496 *
497 * @stable ICU 3.2
498 */
getDynamicClassID()499 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
500
501 protected:
502 virtual void init(le_int32 capacity);
503 virtual void grow(le_int32 capacity);
504
505 /**
506 * @internal
507 */
508 const Locale **fLocales;
509
510 private:
511
512 inline LocaleRuns();
513 inline LocaleRuns(const LocaleRuns &other);
514 inline LocaleRuns &operator=(const LocaleRuns & /*other*/) { return *this; };
515
516 /**
517 * The address of this static class variable serves as this class's ID
518 * for ICU "poor man's RTTI".
519 */
520 static const char fgClassID;
521 };
522
LocaleRuns()523 inline LocaleRuns::LocaleRuns()
524 : RunArray(0), fLocales(NULL)
525 {
526 // nothing else to do...
527 }
528
LocaleRuns(const LocaleRuns &)529 inline LocaleRuns::LocaleRuns(const LocaleRuns & /*other*/)
530 : RunArray(0), fLocales(NULL)
531 {
532 // nothing else to do...
533 }
534
LocaleRuns(const Locale ** locales,const le_int32 * limits,le_int32 count)535 inline LocaleRuns::LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count)
536 : RunArray(limits, count), fLocales(locales)
537 {
538 // nothing else to do...
539 }
540
541 /**
542 * The <code>ValueRuns</code> class associates integer values with runs of text.
543 *
544 * @stable ICU 3.2
545 */
546 class U_LAYOUTEX_API ValueRuns : public RunArray
547 {
548 public:
549 /**
550 * Construct a <code>ValueRuns</code> object from pre-existing arrays of values
551 * and limit indices.
552 *
553 * @param values is the address of an array of integer. This array must remain valid until
554 * the <code>ValueRuns</code> object is destroyed.
555 *
556 * @param limits is the address of an array of limit indices. This array must remain valid until
557 * the <code>ValueRuns</code> object is destroyed.
558 *
559 * @param count is the number of entries in the two arrays.
560 *
561 * @stable ICU 3.2
562 */
563 inline ValueRuns(const le_int32 *values, const le_int32 *limits, le_int32 count);
564
565 /**
566 * Construct an empty <code>ValueRuns</code> object. Clients can add value and limit
567 * indices arrays using the <code>add</code> method.
568 *
569 * @param initialCapacity is the initial size of the value and limit indices arrays. If
570 * this value is zero, no arrays will be allocated.
571 *
572 * @see add
573 *
574 * @stable ICU 3.2
575 */
576 ValueRuns(le_int32 initialCapacity);
577
578 /**
579 * The destructor; virtual so that subclass destructors are invoked as well.
580 *
581 * @stable ICU 3.2
582 */
583 virtual ~ValueRuns();
584
585 /**
586 * Get the integer value assoicated with the given run
587 * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
588 * limit index.
589 *
590 * @param run is the index into the font and limit indices arrays.
591 *
592 * @return the integer value associated with the given text run.
593 *
594 * @see RunArray::getLimit
595 *
596 * @stable ICU 3.2
597 */
598 le_int32 getValue(le_int32 run) const;
599
600
601 /**
602 * Add an integer value and limit index pair to the data arrays and return
603 * the run index where the data was stored. This method calls
604 * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
605 *
606 * If the <code>ValueRuns</code> object was created with a client-supplied
607 * font and limit indices arrays, this method will return a run index of -1.
608 *
609 * Subclasses should not override this method. Rather they should provide a new <code>add</code>
610 * method which takes an integer value and a limit index along with whatever other data they implement.
611 * The new <code>add</code> method should first call this method to grow the font and limit indices
612 * arrays, and use the returned run index to store data their own arrays.
613 *
614 * @param value is the integer value to add
615 *
616 * @param limit is the limit index to add
617 *
618 * @return the run index where the value and limit index were stored, or -1 if the data cannot be stored.
619 *
620 * @stable ICU 3.2
621 */
622 le_int32 add(le_int32 value, le_int32 limit);
623
624 /**
625 * ICU "poor man's RTTI", returns a UClassID for this class.
626 *
627 * @stable ICU 3.2
628 */
getStaticClassID()629 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
630
631 /**
632 * ICU "poor man's RTTI", returns a UClassID for the actual class.
633 *
634 * @stable ICU 3.2
635 */
getDynamicClassID()636 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
637
638 protected:
639 virtual void init(le_int32 capacity);
640 virtual void grow(le_int32 capacity);
641
642 private:
643
644 inline ValueRuns();
645 inline ValueRuns(const ValueRuns &other);
646 inline ValueRuns &operator=(const ValueRuns & /*other*/) { return *this; };
647
648 /**
649 * The address of this static class variable serves as this class's ID
650 * for ICU "poor man's RTTI".
651 */
652 static const char fgClassID;
653
654 const le_int32 *fValues;
655 };
656
ValueRuns()657 inline ValueRuns::ValueRuns()
658 : RunArray(0), fValues(NULL)
659 {
660 // nothing else to do...
661 }
662
ValueRuns(const ValueRuns &)663 inline ValueRuns::ValueRuns(const ValueRuns & /*other*/)
664 : RunArray(0), fValues(NULL)
665 {
666 // nothing else to do...
667 }
668
ValueRuns(const le_int32 * values,const le_int32 * limits,le_int32 count)669 inline ValueRuns::ValueRuns(const le_int32 *values, const le_int32 *limits, le_int32 count)
670 : RunArray(limits, count), fValues(values)
671 {
672 // nothing else to do...
673 }
674
675 U_NAMESPACE_END
676 #endif
677