Home | History | Annotate | Download | only in layoutex
      1 /*
      2  *
      3  * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
      4  *
      5  */
      6 
      7 #include "layout/LETypes.h"
      8 #include "layout/loengine.h"
      9 #include "layout/plruns.h"
     10 
     11 #include "unicode/locid.h"
     12 
     13 #include "layout/LayoutEngine.h"
     14 #include "layout/RunArrays.h"
     15 
     16 U_NAMESPACE_USE
     17 
     18 U_CAPI pl_fontRuns * U_EXPORT2
     19 pl_openFontRuns(const le_font **fonts,
     20                 const le_int32 *limits,
     21                 le_int32 count)
     22 {
     23     return (pl_fontRuns *) new FontRuns((const LEFontInstance **) fonts, limits, count);
     24 }
     25 
     26 U_CAPI pl_fontRuns * U_EXPORT2
     27 pl_openEmptyFontRuns(le_int32 initialCapacity)
     28 {
     29     return (pl_fontRuns *) new FontRuns(initialCapacity);
     30 }
     31 
     32 U_CAPI void U_EXPORT2
     33 pl_closeFontRuns(pl_fontRuns *fontRuns)
     34 {
     35     FontRuns *fr = (FontRuns *) fontRuns;
     36 
     37     delete fr;
     38 }
     39 
     40 U_CAPI le_int32 U_EXPORT2
     41 pl_getFontRunCount(const pl_fontRuns *fontRuns)
     42 {
     43     const FontRuns *fr = (const FontRuns *) fontRuns;
     44 
     45     if (fr == NULL) {
     46         return -1;
     47     }
     48 
     49     return fr->getCount();
     50 }
     51 
     52 U_CAPI void U_EXPORT2
     53 pl_resetFontRuns(pl_fontRuns *fontRuns)
     54 {
     55     FontRuns *fr = (FontRuns *) fontRuns;
     56 
     57     if (fr != NULL) {
     58         fr->reset();
     59     }
     60 }
     61 
     62 U_CAPI le_int32 U_EXPORT2
     63 pl_getFontRunLastLimit(const pl_fontRuns *fontRuns)
     64 {
     65     const FontRuns *fr = (const FontRuns *) fontRuns;
     66 
     67     if (fr == NULL) {
     68         return -1;
     69     }
     70 
     71     return fr->getLimit();
     72 }
     73 
     74 U_CAPI le_int32 U_EXPORT2
     75 pl_getFontRunLimit(const pl_fontRuns *fontRuns,
     76                    le_int32 run)
     77 {
     78     const FontRuns *fr = (const FontRuns *) fontRuns;
     79 
     80     if (fr == NULL) {
     81         return -1;
     82     }
     83 
     84     return fr->getLimit(run);
     85 }
     86 
     87 U_CAPI const le_font * U_EXPORT2
     88 pl_getFontRunFont(const pl_fontRuns *fontRuns,
     89                     le_int32 run)
     90 {
     91     const FontRuns *fr = (const FontRuns *) fontRuns;
     92 
     93     if (fr == NULL) {
     94         return NULL;
     95     }
     96 
     97     return (const le_font *) fr->getFont(run);
     98 }
     99 
    100 U_CAPI le_int32 U_EXPORT2
    101 pl_addFontRun(pl_fontRuns *fontRuns,
    102               const le_font *font,
    103               le_int32 limit)
    104 {
    105     FontRuns *fr = (FontRuns *) fontRuns;
    106 
    107     if (fr == NULL) {
    108         return -1;
    109     }
    110 
    111     return fr->add((const LEFontInstance *) font, limit);
    112 }
    113 
    114 U_CAPI pl_valueRuns * U_EXPORT2
    115 pl_openValueRuns(const le_int32 *values,
    116                  const le_int32 *limits,
    117                  le_int32 count)
    118 {
    119     return (pl_valueRuns *) new ValueRuns(values, limits, count);
    120 }
    121 
    122 U_CAPI pl_valueRuns * U_EXPORT2
    123 pl_openEmptyValueRuns(le_int32 initialCapacity)
    124 {
    125     return (pl_valueRuns *) new ValueRuns(initialCapacity);
    126 }
    127 
    128 U_CAPI void U_EXPORT2
    129 pl_closeValueRuns(pl_valueRuns *valueRuns)
    130 {
    131     ValueRuns *vr = (ValueRuns *) valueRuns;
    132 
    133     delete vr;
    134 }
    135 
    136 U_CAPI le_int32 U_EXPORT2
    137 pl_getValueRunCount(const pl_valueRuns *valueRuns)
    138 {
    139     const ValueRuns *vr = (const ValueRuns *) valueRuns;
    140 
    141     if (vr == NULL) {
    142         return -1;
    143     }
    144 
    145     return vr->getCount();
    146 }
    147 
    148 U_CAPI void U_EXPORT2
    149 pl_resetValueRuns(pl_valueRuns *valueRuns)
    150 {
    151     ValueRuns *vr = (ValueRuns *) valueRuns;
    152 
    153     if (vr != NULL) {
    154         vr->reset();
    155     }
    156 }
    157 
    158 U_CAPI le_int32 U_EXPORT2
    159 pl_getValueRunLastLimit(const pl_valueRuns *valueRuns)
    160 {
    161     const ValueRuns *vr = (const ValueRuns *) valueRuns;
    162 
    163     if (vr == NULL) {
    164         return -1;
    165     }
    166 
    167     return vr->getLimit();
    168 }
    169 
    170 U_CAPI le_int32 U_EXPORT2
    171 pl_getValueRunLimit(const pl_valueRuns *valueRuns,
    172                     le_int32 run)
    173 {
    174     const ValueRuns *vr = (const ValueRuns *) valueRuns;
    175 
    176     if (vr == NULL) {
    177         return -1;
    178     }
    179 
    180     return vr->getLimit(run);
    181 }
    182 
    183 U_CAPI le_int32 U_EXPORT2
    184 pl_getValueRunValue(const pl_valueRuns *valueRuns,
    185                      le_int32 run)
    186 {
    187     const ValueRuns *vr = (const ValueRuns *) valueRuns;
    188 
    189     if (vr == NULL) {
    190         return -1;
    191     }
    192 
    193     return vr->getValue(run);
    194 }
    195 
    196 U_CAPI le_int32 U_EXPORT2
    197 pl_addValueRun(pl_valueRuns *valueRuns,
    198                le_int32 value,
    199                le_int32 limit)
    200 {
    201     ValueRuns *vr = (ValueRuns *) valueRuns;
    202 
    203     if (vr == NULL) {
    204         return -1;
    205     }
    206 
    207     return vr->add(value, limit);
    208 }
    209 
    210 U_NAMESPACE_BEGIN
    211 class ULocRuns : public LocaleRuns
    212 {
    213 public:
    214     /**
    215      * Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales
    216      * and limit indices.
    217      *
    218      * @param locales is the address of an array of locale name strings. This array,
    219      *                and the <code>Locale</code> objects to which it points, must remain valid until
    220      *                the <code>LocaleRuns</code> object is destroyed.
    221      *
    222      * @param limits is the address of an array of limit indices. This array must remain valid until the
    223      *               <code>LocaleRuns</code> object is destroyed.
    224      *
    225      * @param count is the number of entries in the two arrays.
    226      *
    227      * @draft ICU 3.8
    228      */
    229     ULocRuns(const char **locales, const le_int32 *limits, le_int32 count);
    230 
    231     /**
    232      * Construct an empty <code>LoIDRuns</code> object. Clients can add locale and limit
    233      * indices arrays using the <code>add</code> method.
    234      *
    235      * @param initialCapacity is the initial size of the locale and limit indices arrays. If
    236      *        this value is zero, no arrays will be allocated.
    237      *
    238      * @see add
    239      *
    240      * @draft ICU 3.8
    241      */
    242     ULocRuns(le_int32 initialCapacity);
    243 
    244     /**
    245      * The destructor; virtual so that subclass destructors are invoked as well.
    246      *
    247      * @draft ICU 3.8
    248      */
    249     virtual ~ULocRuns();
    250 
    251     /**
    252      * Get the name of the locale assoicated with the given run
    253      * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
    254      * limit index.
    255      *
    256      * @param run is the index into the font and limit indices arrays.
    257      *
    258      * @return the locale name associated with the given text run.
    259      *
    260      * @see RunArray::getLimit
    261      *
    262      * @draft ICU 3.8
    263      */
    264     const char *getLocaleName(le_int32 run) const;
    265 
    266     /**
    267      * Add a <code>Locale</code> and limit index pair to the data arrays and return
    268      * the run index where the data was stored. This  method calls
    269      * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
    270      *
    271      * If the <code>ULocRuns</code> object was created with a client-supplied
    272      * locale and limit indices arrays, this method will return a run index of -1.
    273      *
    274      * Subclasses should not override this method. Rather they should provide a new <code>add</code>
    275      * method which takes a locale name and a limit index along with whatever other data they implement.
    276      * The new <code>add</code> method should first call this method to grow the font and limit indices
    277      * arrays, and use the returned run index to store data their own arrays.
    278      *
    279      * @param locale is the name of the locale to add. This object must remain valid
    280      *               until the <code>ULocRuns</code> object is destroyed.
    281      *
    282      * @param limit is the limit index to add
    283      *
    284      * @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored.
    285      *
    286      * @draft ICU 3.8
    287      */
    288     le_int32 add(const char *locale, le_int32 limit);
    289 
    290     /**
    291      * ICU "poor man's RTTI", returns a UClassID for this class.
    292      *
    293      * @draft ICU 3.8
    294      */
    295     static inline UClassID getStaticClassID();
    296 
    297     /**
    298      * ICU "poor man's RTTI", returns a UClassID for the actual class.
    299      *
    300      * @draft ICU 3.8
    301      */
    302     virtual inline UClassID getDynamicClassID() const;
    303 
    304 protected:
    305     virtual void init(le_int32 capacity);
    306     virtual void grow(le_int32 capacity);
    307 
    308 private:
    309 
    310     inline ULocRuns();
    311     inline ULocRuns(const ULocRuns &other);
    312     inline ULocRuns &operator=(const ULocRuns & /*other*/) { return *this; };
    313     const char **fLocaleNames;
    314     Locale **fLocalesCopy;
    315 };
    316 
    317 inline ULocRuns::ULocRuns()
    318     : LocaleRuns(0), fLocaleNames(NULL)
    319 {
    320     // nothing else to do...
    321 }
    322 
    323 inline ULocRuns::ULocRuns(const ULocRuns & /*other*/)
    324     : LocaleRuns(0), fLocaleNames(NULL)
    325 {
    326     // nothing else to do...
    327 }
    328 
    329 static const Locale **getLocales(const char **localeNames, le_int32 count)
    330 {
    331     Locale **locales = LE_NEW_ARRAY(Locale *, count);
    332 
    333     for (int i = 0; i < count; i += 1) {
    334         locales[i] = new Locale(Locale::createFromName(localeNames[i]));
    335     }
    336 
    337     return (const Locale **) locales;
    338 }
    339 
    340 ULocRuns::ULocRuns(const char **locales, const le_int32 *limits, le_int32 count)
    341     : LocaleRuns(getLocales(locales, count), limits, count), fLocaleNames(locales)
    342 {
    343     // nothing else to do...
    344 }
    345 
    346 ULocRuns::ULocRuns(le_int32 initialCapacity)
    347     : LocaleRuns(initialCapacity), fLocaleNames(NULL)
    348 {
    349     if(initialCapacity > 0) {
    350         fLocaleNames = LE_NEW_ARRAY(const char *, initialCapacity);
    351     }
    352 }
    353 
    354 ULocRuns::~ULocRuns()
    355 {
    356     le_int32 count = getCount();
    357 
    358     for(int i = 0; i < count; i += 1) {
    359         delete fLocales[i];
    360     }
    361 
    362     if (fClientArrays) {
    363         LE_DELETE_ARRAY(fLocales);
    364         fLocales = NULL;
    365     } else {
    366         LE_DELETE_ARRAY(fLocaleNames);
    367         fLocaleNames = NULL;
    368     }
    369 }
    370 
    371 void ULocRuns::init(le_int32 capacity)
    372 {
    373     LocaleRuns::init(capacity);
    374     fLocaleNames = LE_NEW_ARRAY(const char *, capacity);
    375 }
    376 
    377 void ULocRuns::grow(le_int32 capacity)
    378 {
    379     LocaleRuns::grow(capacity);
    380     fLocaleNames = (const char **) LE_GROW_ARRAY(fLocaleNames, capacity);
    381 }
    382 
    383 le_int32 ULocRuns::add(const char *locale, le_int32 limit)
    384 {
    385     Locale *loc = new Locale(Locale::createFromName(locale));
    386     le_int32 index = LocaleRuns::add(loc, limit);
    387 
    388     if (index >= 0) {
    389         char **localeNames = (char **) fLocaleNames;
    390 
    391         localeNames[index] = (char *) locale;
    392     }
    393 
    394     return index;
    395 }
    396 
    397 const char *ULocRuns::getLocaleName(le_int32 run) const
    398 {
    399     if (run < 0 || run >= getCount()) {
    400         return NULL;
    401     }
    402 
    403     return fLocaleNames[run];
    404 }
    405 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ULocRuns)
    406 U_NAMESPACE_END
    407 
    408 U_CAPI pl_localeRuns * U_EXPORT2
    409 pl_openLocaleRuns(const char **locales,
    410                   const le_int32 *limits,
    411                   le_int32 count)
    412 {
    413     return (pl_localeRuns *) new ULocRuns(locales, limits, count);
    414 }
    415 
    416 U_CAPI pl_localeRuns * U_EXPORT2
    417 pl_openEmptyLocaleRuns(le_int32 initialCapacity)
    418 {
    419     return (pl_localeRuns *) new ULocRuns(initialCapacity);
    420 }
    421 
    422 U_CAPI void U_EXPORT2
    423 pl_closeLocaleRuns(pl_localeRuns *localeRuns)
    424 {
    425     ULocRuns *lr = (ULocRuns *) localeRuns;
    426 
    427     delete lr;
    428 }
    429 
    430 U_CAPI le_int32 U_EXPORT2
    431 pl_getLocaleRunCount(const pl_localeRuns *localeRuns)
    432 {
    433     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    434 
    435     if (lr == NULL) {
    436         return -1;
    437     }
    438 
    439     return lr->getCount();
    440 }
    441 
    442 U_CAPI void U_EXPORT2
    443 pl_resetLocaleRuns(pl_localeRuns *localeRuns)
    444 {
    445     ULocRuns *lr = (ULocRuns *) localeRuns;
    446 
    447     if (lr != NULL) {
    448         lr->reset();
    449     }
    450 }
    451 
    452 U_CAPI le_int32 U_EXPORT2
    453 pl_getLocaleRunLastLimit(const pl_localeRuns *localeRuns)
    454 {
    455     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    456 
    457     if (lr == NULL) {
    458         return -1;
    459     }
    460 
    461     return lr->getLimit();
    462 }
    463 
    464 U_CAPI le_int32 U_EXPORT2
    465 pl_getLocaleRunLimit(const pl_localeRuns *localeRuns,
    466                      le_int32 run)
    467 {
    468     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    469 
    470     if (lr == NULL) {
    471         return -1;
    472     }
    473 
    474     return lr->getLimit(run);
    475 }
    476 
    477 U_CAPI const char * U_EXPORT2
    478 pl_getLocaleRunLocale(const pl_localeRuns *localeRuns,
    479                       le_int32 run)
    480 {
    481     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    482 
    483     if (lr == NULL) {
    484         return NULL;
    485     }
    486 
    487     return lr->getLocaleName(run);
    488 }
    489 
    490 U_CAPI le_int32 U_EXPORT2
    491 pl_addLocaleRun(pl_localeRuns *localeRuns,
    492                 const char *locale,
    493                 le_int32 limit)
    494 {
    495     ULocRuns *lr = (ULocRuns *) localeRuns;
    496 
    497     if (lr == NULL) {
    498         return -1;
    499     }
    500 
    501     return lr->add(locale, limit);
    502 }
    503