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