Home | History | Annotate | Download | only in layoutex
      1 /*
      2  *
      3  * (C) Copyright IBM Corp. 1998-2013 - 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 };
    315 
    316 inline ULocRuns::ULocRuns()
    317     : LocaleRuns(0), fLocaleNames(NULL)
    318 {
    319     // nothing else to do...
    320 }
    321 
    322 inline ULocRuns::ULocRuns(const ULocRuns & /*other*/)
    323     : LocaleRuns(0), fLocaleNames(NULL)
    324 {
    325     // nothing else to do...
    326 }
    327 
    328 static const Locale **getLocales(const char **localeNames, le_int32 count)
    329 {
    330     Locale **locales = LE_NEW_ARRAY(Locale *, count);
    331 
    332     for (int i = 0; i < count; i += 1) {
    333         locales[i] = new Locale(Locale::createFromName(localeNames[i]));
    334     }
    335 
    336     return (const Locale **) locales;
    337 }
    338 
    339 ULocRuns::ULocRuns(const char **locales, const le_int32 *limits, le_int32 count)
    340     : LocaleRuns(getLocales(locales, count), limits, count), fLocaleNames(locales)
    341 {
    342     // nothing else to do...
    343 }
    344 
    345 ULocRuns::ULocRuns(le_int32 initialCapacity)
    346     : LocaleRuns(initialCapacity), fLocaleNames(NULL)
    347 {
    348     if(initialCapacity > 0) {
    349         fLocaleNames = LE_NEW_ARRAY(const char *, initialCapacity);
    350     }
    351 }
    352 
    353 ULocRuns::~ULocRuns()
    354 {
    355     le_int32 count = getCount();
    356 
    357     for(int i = 0; i < count; i += 1) {
    358         delete fLocales[i];
    359     }
    360 
    361     if (fClientArrays) {
    362         LE_DELETE_ARRAY(fLocales);
    363         fLocales = NULL;
    364     } else {
    365         LE_DELETE_ARRAY(fLocaleNames);
    366         fLocaleNames = NULL;
    367     }
    368 }
    369 
    370 void ULocRuns::init(le_int32 capacity)
    371 {
    372     LocaleRuns::init(capacity);
    373     fLocaleNames = LE_NEW_ARRAY(const char *, capacity);
    374 }
    375 
    376 void ULocRuns::grow(le_int32 capacity)
    377 {
    378     LocaleRuns::grow(capacity);
    379     fLocaleNames = (const char **) LE_GROW_ARRAY(fLocaleNames, capacity);
    380 }
    381 
    382 le_int32 ULocRuns::add(const char *locale, le_int32 limit)
    383 {
    384     Locale *loc = new Locale(Locale::createFromName(locale));
    385     le_int32 index = LocaleRuns::add(loc, limit);
    386 
    387     if (index >= 0) {
    388         char **localeNames = (char **) fLocaleNames;
    389 
    390         localeNames[index] = (char *) locale;
    391     }
    392 
    393     return index;
    394 }
    395 
    396 const char *ULocRuns::getLocaleName(le_int32 run) const
    397 {
    398     if (run < 0 || run >= getCount()) {
    399         return NULL;
    400     }
    401 
    402     return fLocaleNames[run];
    403 }
    404 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ULocRuns)
    405 U_NAMESPACE_END
    406 
    407 U_CAPI pl_localeRuns * U_EXPORT2
    408 pl_openLocaleRuns(const char **locales,
    409                   const le_int32 *limits,
    410                   le_int32 count)
    411 {
    412     return (pl_localeRuns *) new ULocRuns(locales, limits, count);
    413 }
    414 
    415 U_CAPI pl_localeRuns * U_EXPORT2
    416 pl_openEmptyLocaleRuns(le_int32 initialCapacity)
    417 {
    418     return (pl_localeRuns *) new ULocRuns(initialCapacity);
    419 }
    420 
    421 U_CAPI void U_EXPORT2
    422 pl_closeLocaleRuns(pl_localeRuns *localeRuns)
    423 {
    424     ULocRuns *lr = (ULocRuns *) localeRuns;
    425 
    426     delete lr;
    427 }
    428 
    429 U_CAPI le_int32 U_EXPORT2
    430 pl_getLocaleRunCount(const pl_localeRuns *localeRuns)
    431 {
    432     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    433 
    434     if (lr == NULL) {
    435         return -1;
    436     }
    437 
    438     return lr->getCount();
    439 }
    440 
    441 U_CAPI void U_EXPORT2
    442 pl_resetLocaleRuns(pl_localeRuns *localeRuns)
    443 {
    444     ULocRuns *lr = (ULocRuns *) localeRuns;
    445 
    446     if (lr != NULL) {
    447         lr->reset();
    448     }
    449 }
    450 
    451 U_CAPI le_int32 U_EXPORT2
    452 pl_getLocaleRunLastLimit(const pl_localeRuns *localeRuns)
    453 {
    454     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    455 
    456     if (lr == NULL) {
    457         return -1;
    458     }
    459 
    460     return lr->getLimit();
    461 }
    462 
    463 U_CAPI le_int32 U_EXPORT2
    464 pl_getLocaleRunLimit(const pl_localeRuns *localeRuns,
    465                      le_int32 run)
    466 {
    467     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    468 
    469     if (lr == NULL) {
    470         return -1;
    471     }
    472 
    473     return lr->getLimit(run);
    474 }
    475 
    476 U_CAPI const char * U_EXPORT2
    477 pl_getLocaleRunLocale(const pl_localeRuns *localeRuns,
    478                       le_int32 run)
    479 {
    480     const ULocRuns *lr = (const ULocRuns *) localeRuns;
    481 
    482     if (lr == NULL) {
    483         return NULL;
    484     }
    485 
    486     return lr->getLocaleName(run);
    487 }
    488 
    489 U_CAPI le_int32 U_EXPORT2
    490 pl_addLocaleRun(pl_localeRuns *localeRuns,
    491                 const char *locale,
    492                 le_int32 limit)
    493 {
    494     ULocRuns *lr = (ULocRuns *) localeRuns;
    495 
    496     if (lr == NULL) {
    497         return -1;
    498     }
    499 
    500     return lr->add(locale, limit);
    501 }
    502