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