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