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 16U_NAMESPACE_USE 17 18U_CAPI pl_fontRuns * U_EXPORT2 19pl_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 26U_CAPI pl_fontRuns * U_EXPORT2 27pl_openEmptyFontRuns(le_int32 initialCapacity) 28{ 29 return (pl_fontRuns *) new FontRuns(initialCapacity); 30} 31 32U_CAPI void U_EXPORT2 33pl_closeFontRuns(pl_fontRuns *fontRuns) 34{ 35 FontRuns *fr = (FontRuns *) fontRuns; 36 37 delete fr; 38} 39 40U_CAPI le_int32 U_EXPORT2 41pl_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 52U_CAPI void U_EXPORT2 53pl_resetFontRuns(pl_fontRuns *fontRuns) 54{ 55 FontRuns *fr = (FontRuns *) fontRuns; 56 57 if (fr != NULL) { 58 fr->reset(); 59 } 60} 61 62U_CAPI le_int32 U_EXPORT2 63pl_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 74U_CAPI le_int32 U_EXPORT2 75pl_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 87U_CAPI const le_font * U_EXPORT2 88pl_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 100U_CAPI le_int32 U_EXPORT2 101pl_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 114U_CAPI pl_valueRuns * U_EXPORT2 115pl_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 122U_CAPI pl_valueRuns * U_EXPORT2 123pl_openEmptyValueRuns(le_int32 initialCapacity) 124{ 125 return (pl_valueRuns *) new ValueRuns(initialCapacity); 126} 127 128U_CAPI void U_EXPORT2 129pl_closeValueRuns(pl_valueRuns *valueRuns) 130{ 131 ValueRuns *vr = (ValueRuns *) valueRuns; 132 133 delete vr; 134} 135 136U_CAPI le_int32 U_EXPORT2 137pl_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 148U_CAPI void U_EXPORT2 149pl_resetValueRuns(pl_valueRuns *valueRuns) 150{ 151 ValueRuns *vr = (ValueRuns *) valueRuns; 152 153 if (vr != NULL) { 154 vr->reset(); 155 } 156} 157 158U_CAPI le_int32 U_EXPORT2 159pl_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 170U_CAPI le_int32 U_EXPORT2 171pl_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 183U_CAPI le_int32 U_EXPORT2 184pl_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 196U_CAPI le_int32 U_EXPORT2 197pl_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 210U_NAMESPACE_BEGIN 211class ULocRuns : public LocaleRuns 212{ 213public: 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 304protected: 305 virtual void init(le_int32 capacity); 306 virtual void grow(le_int32 capacity); 307 308private: 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 316inline ULocRuns::ULocRuns() 317 : LocaleRuns(0), fLocaleNames(NULL) 318{ 319 // nothing else to do... 320} 321 322inline ULocRuns::ULocRuns(const ULocRuns & /*other*/) 323 : LocaleRuns(0), fLocaleNames(NULL) 324{ 325 // nothing else to do... 326} 327 328static 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 339ULocRuns::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 345ULocRuns::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 353ULocRuns::~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 370void ULocRuns::init(le_int32 capacity) 371{ 372 LocaleRuns::init(capacity); 373 fLocaleNames = LE_NEW_ARRAY(const char *, capacity); 374} 375 376void ULocRuns::grow(le_int32 capacity) 377{ 378 LocaleRuns::grow(capacity); 379 fLocaleNames = (const char **) LE_GROW_ARRAY(fLocaleNames, capacity); 380} 381 382le_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 396const char *ULocRuns::getLocaleName(le_int32 run) const 397{ 398 if (run < 0 || run >= getCount()) { 399 return NULL; 400 } 401 402 return fLocaleNames[run]; 403} 404UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ULocRuns) 405U_NAMESPACE_END 406 407U_CAPI pl_localeRuns * U_EXPORT2 408pl_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 415U_CAPI pl_localeRuns * U_EXPORT2 416pl_openEmptyLocaleRuns(le_int32 initialCapacity) 417{ 418 return (pl_localeRuns *) new ULocRuns(initialCapacity); 419} 420 421U_CAPI void U_EXPORT2 422pl_closeLocaleRuns(pl_localeRuns *localeRuns) 423{ 424 ULocRuns *lr = (ULocRuns *) localeRuns; 425 426 delete lr; 427} 428 429U_CAPI le_int32 U_EXPORT2 430pl_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 441U_CAPI void U_EXPORT2 442pl_resetLocaleRuns(pl_localeRuns *localeRuns) 443{ 444 ULocRuns *lr = (ULocRuns *) localeRuns; 445 446 if (lr != NULL) { 447 lr->reset(); 448 } 449} 450 451U_CAPI le_int32 U_EXPORT2 452pl_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 463U_CAPI le_int32 U_EXPORT2 464pl_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 476U_CAPI const char * U_EXPORT2 477pl_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 489U_CAPI le_int32 U_EXPORT2 490pl_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