1 // © 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 cannot 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 associated 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 associated 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 associated 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