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 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 Locale **fLocalesCopy; 315}; 316 317inline ULocRuns::ULocRuns() 318 : LocaleRuns(0), fLocaleNames(NULL) 319{ 320 // nothing else to do... 321} 322 323inline ULocRuns::ULocRuns(const ULocRuns & /*other*/) 324 : LocaleRuns(0), fLocaleNames(NULL) 325{ 326 // nothing else to do... 327} 328 329static 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 340ULocRuns::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 346ULocRuns::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 354ULocRuns::~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 371void ULocRuns::init(le_int32 capacity) 372{ 373 LocaleRuns::init(capacity); 374 fLocaleNames = LE_NEW_ARRAY(const char *, capacity); 375} 376 377void ULocRuns::grow(le_int32 capacity) 378{ 379 LocaleRuns::grow(capacity); 380 fLocaleNames = (const char **) LE_GROW_ARRAY(fLocaleNames, capacity); 381} 382 383le_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 397const char *ULocRuns::getLocaleName(le_int32 run) const 398{ 399 if (run < 0 || run >= getCount()) { 400 return NULL; 401 } 402 403 return fLocaleNames[run]; 404} 405UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ULocRuns) 406U_NAMESPACE_END 407 408U_CAPI pl_localeRuns * U_EXPORT2 409pl_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 416U_CAPI pl_localeRuns * U_EXPORT2 417pl_openEmptyLocaleRuns(le_int32 initialCapacity) 418{ 419 return (pl_localeRuns *) new ULocRuns(initialCapacity); 420} 421 422U_CAPI void U_EXPORT2 423pl_closeLocaleRuns(pl_localeRuns *localeRuns) 424{ 425 ULocRuns *lr = (ULocRuns *) localeRuns; 426 427 delete lr; 428} 429 430U_CAPI le_int32 U_EXPORT2 431pl_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 442U_CAPI void U_EXPORT2 443pl_resetLocaleRuns(pl_localeRuns *localeRuns) 444{ 445 ULocRuns *lr = (ULocRuns *) localeRuns; 446 447 if (lr != NULL) { 448 lr->reset(); 449 } 450} 451 452U_CAPI le_int32 U_EXPORT2 453pl_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 464U_CAPI le_int32 U_EXPORT2 465pl_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 477U_CAPI const char * U_EXPORT2 478pl_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 490U_CAPI le_int32 U_EXPORT2 491pl_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