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