Home | History | Annotate | Download | only in layout
      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      */
    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      */
    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 
    224 inline RunArray::RunArray()
    225     : UObject(), fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(0)
    226 {
    227     // nothing else to do...
    228 }
    229 
    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 
    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 
    242 inline le_int32 RunArray::getCount() const
    243 {
    244     return fCount;
    245 }
    246 
    247 inline void RunArray::reset()
    248 {
    249     fCount = 0;
    250 }
    251 
    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 
    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      */
    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      */
    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 
    385 inline FontRuns::FontRuns()
    386     : RunArray(0), fFonts(NULL)
    387 {
    388     // nothing else to do...
    389 }
    390 
    391 inline FontRuns::FontRuns(const FontRuns & /*other*/)
    392     : RunArray(0), fFonts(NULL)
    393 {
    394     // nothing else to do...
    395 }
    396 
    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      */
    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      */
    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 
    525 inline LocaleRuns::LocaleRuns()
    526     : RunArray(0), fLocales(NULL)
    527 {
    528     // nothing else to do...
    529 }
    530 
    531 inline LocaleRuns::LocaleRuns(const LocaleRuns & /*other*/)
    532     : RunArray(0), fLocales(NULL)
    533 {
    534     // nothing else to do...
    535 }
    536 
    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      */
    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      */
    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 
    659 inline ValueRuns::ValueRuns()
    660     : RunArray(0), fValues(NULL)
    661 {
    662     // nothing else to do...
    663 }
    664 
    665 inline ValueRuns::ValueRuns(const ValueRuns & /*other*/)
    666     : RunArray(0), fValues(NULL)
    667 {
    668     // nothing else to do...
    669 }
    670 
    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