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