1/* 2 ********************************************************************** 3 * Copyright (C) 2003-2008, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ********************************************************************** 6 */ 7 8#ifndef __RUNARRAYS_H 9 10#define __RUNARRAYS_H 11 12#include "layout/LETypes.h" 13#include "layout/LEFontInstance.h" 14 15#include "unicode/utypes.h" 16#include "unicode/locid.h" 17 18/** 19 * \file 20 * \brief C++ API: base class for building classes which represent data that is associated with runs of text. 21 */ 22 23U_NAMESPACE_BEGIN 24 25/** 26 * The initial size of an array if it is unspecified. 27 * 28 * @stable ICU 3.2 29 */ 30#define INITIAL_CAPACITY 16 31 32/** 33 * When an array needs to grow, it will double in size until 34 * it becomes this large, then it will grow by this amount. 35 * 36 * @stable ICU 3.2 37 */ 38#define CAPACITY_GROW_LIMIT 128 39 40/** 41 * The <code>RunArray</code> class is a base class for building classes 42 * which represent data that is associated with runs of text. This class 43 * maintains an array of limit indices into the text, subclasses 44 * provide one or more arrays of data. 45 * 46 * @stable ICU 3.2 47 */ 48class U_LAYOUTEX_API RunArray : public UObject 49{ 50public: 51 /** 52 * Construct a <code>RunArray</code> object from a pre-existing 53 * array of limit indices. 54 * 55 * @param limits is an array of limit indices. This array must remain 56 * valid until the <code>RunArray</code> object is destroyed. 57 * 58 * @param count is the number of entries in the limit array. 59 * 60 * @stable ICU 3.2 61 */ 62 inline RunArray(const le_int32 *limits, le_int32 count); 63 64 /** 65 * Construct an empty <code>RunArray</code> object. Clients can add limit 66 * indices array using the <code>add</code> method. 67 * 68 * @param initialCapacity is the initial size of the limit indices array. If 69 * this value is zero, no array will be allocated. 70 * 71 * @see add 72 * 73 * @stable ICU 3.2 74 */ 75 RunArray(le_int32 initialCapacity); 76 77 /** 78 * The destructor; virtual so that subclass destructors are invoked as well. 79 * 80 * @stable ICU 3.2 81 */ 82 virtual ~RunArray(); 83 84 /** 85 * Get the number of entries in the limit indices array. 86 * 87 * @return the number of entries in the limit indices array. 88 * 89 * @stable ICU 3.2 90 */ 91 inline le_int32 getCount() const; 92 93 /** 94 * Reset the limit indices array. This method sets the number of entries in the 95 * limit indices array to zero. It does not delete the array. 96 * 97 * Note: Subclass arrays will also be reset and not deleted. 98 * 99 * @stable ICU 3.6 100 */ 101 inline void reset(); 102 103 /** 104 * Get the last limit index. This is the number of characters in 105 * the text. 106 * 107 * @return the last limit index. 108 * 109 * @stable ICU 3.2 110 */ 111 inline le_int32 getLimit() const; 112 113 /** 114 * Get the limit index for a particular run of text. 115 * 116 * @param run is the run. This is an index into the limit index array. 117 * 118 * @return the limit index for the run, or -1 if <code>run</code> is out of bounds. 119 * 120 * @stable ICU 3.2 121 */ 122 inline le_int32 getLimit(le_int32 run) const; 123 124 /** 125 * Add a limit index to the limit indices array and return the run index 126 * where it was stored. If the array does not exist, it will be created by 127 * calling the <code>init</code> method. If it is full, it will be grown by 128 * calling the <code>grow</code> method. 129 * 130 * If the <code>RunArray</code> object was created with a client-supplied 131 * limit indices array, this method will return a run index of -1. 132 * 133 * Subclasses should not override this method. Rather they should provide 134 * a new <code>add</code> method which takes a limit index along with whatever 135 * other data they implement. The new <code>add</code> method should 136 * first call this method to grow the data arrays, and use the return value 137 * to store the data in their own arrays. 138 * 139 * @param limit is the limit index to add to the array. 140 * 141 * @return the run index where the limit index was stored, or -1 if the limit index cannt be stored. 142 * 143 * @see init 144 * @see grow 145 * 146 * @stable ICU 3.2 147 */ 148 le_int32 add(le_int32 limit); 149 150 /** 151 * ICU "poor man's RTTI", returns a UClassID for this class. 152 * 153 * @stable ICU 3.2 154 */ 155 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 156 157 /** 158 * ICU "poor man's RTTI", returns a UClassID for the actual class. 159 * 160 * @stable ICU 3.2 161 */ 162 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 163 164protected: 165 /** 166 * Create a data array with the given initial size. This method will be 167 * called by the <code>add</code> method if there is no limit indices 168 * array. Subclasses which override this method must also call it from 169 * the overriding method to create the limit indices array. 170 * 171 * @param capacity is the initial size of the data array. 172 * 173 * @see add 174 * 175 * @stable ICU 3.2 176 */ 177 virtual void init(le_int32 capacity); 178 179 /** 180 * Grow a data array to the given initial size. This method will be 181 * called by the <code>add</code> method if the limit indices 182 * array is full. Subclasses which override this method must also call it from 183 * the overriding method to grow the limit indices array. 184 * 185 * @param capacity is the initial size of the data array. 186 * 187 * @see add 188 * 189 * @stable ICU 3.2 190 */ 191 virtual void grow(le_int32 capacity); 192 193 /** 194 * Set by the constructors to indicate whether 195 * or not the client supplied the data arrays. 196 * If they were supplied by the client, the 197 * <code>add</code> method won't change the arrays 198 * and the destructor won't delete them. 199 * 200 * @stable ICU 3.2 201 */ 202 le_bool fClientArrays; 203 204private: 205 /** 206 * The address of this static class variable serves as this class's ID 207 * for ICU "poor man's RTTI". 208 */ 209 static const char fgClassID; 210 211 le_int32 ensureCapacity(); 212 213 inline RunArray(); 214 inline RunArray(const RunArray & /*other*/); 215 inline RunArray &operator=(const RunArray & /*other*/) { return *this; }; 216 217 const le_int32 *fLimits; 218 le_int32 fCount; 219 le_int32 fCapacity; 220}; 221 222inline RunArray::RunArray() 223 : UObject(), fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(0) 224{ 225 // nothing else to do... 226} 227 228inline RunArray::RunArray(const RunArray & /*other*/) 229 : UObject(), fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(0) 230{ 231 // nothing else to do... 232} 233 234inline RunArray::RunArray(const le_int32 *limits, le_int32 count) 235 : UObject(), fClientArrays(TRUE), fLimits(limits), fCount(count), fCapacity(count) 236{ 237 // nothing else to do... 238} 239 240inline le_int32 RunArray::getCount() const 241{ 242 return fCount; 243} 244 245inline void RunArray::reset() 246{ 247 fCount = 0; 248} 249 250inline le_int32 RunArray::getLimit(le_int32 run) const 251{ 252 if (run < 0 || run >= fCount) { 253 return -1; 254 } 255 256 return fLimits[run]; 257} 258 259inline le_int32 RunArray::getLimit() const 260{ 261 return getLimit(fCount - 1); 262} 263 264/** 265 * The <code>FontRuns</code> class associates pointers to <code>LEFontInstance</code> 266 * objects with runs of text. 267 * 268 * @stable ICU 3.2 269 */ 270class U_LAYOUTEX_API FontRuns : public RunArray 271{ 272public: 273 /** 274 * Construct a <code>FontRuns</code> object from pre-existing arrays of fonts 275 * and limit indices. 276 * 277 * @param fonts is the address of an array of pointers to <code>LEFontInstance</code> objects. This 278 * array, and the <code>LEFontInstance</code> objects to which it points must remain 279 * valid until the <code>FontRuns</code> object is destroyed. 280 * 281 * @param limits is the address of an array of limit indices. This array must remain valid until 282 * the <code>FontRuns</code> object is destroyed. 283 * 284 * @param count is the number of entries in the two arrays. 285 * 286 * @stable ICU 3.2 287 */ 288 inline FontRuns(const LEFontInstance **fonts, const le_int32 *limits, le_int32 count); 289 290 /** 291 * Construct an empty <code>FontRuns</code> object. Clients can add font and limit 292 * indices arrays using the <code>add</code> method. 293 * 294 * @param initialCapacity is the initial size of the font and limit indices arrays. If 295 * this value is zero, no arrays will be allocated. 296 * 297 * @see add 298 * 299 * @stable ICU 3.2 300 */ 301 FontRuns(le_int32 initialCapacity); 302 303 /** 304 * The destructor; virtual so that subclass destructors are invoked as well. 305 * 306 * @stable ICU 3.2 307 */ 308 virtual ~FontRuns(); 309 310 /** 311 * Get the <code>LEFontInstance</code> object assoicated with the given run 312 * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding 313 * limit index. 314 * 315 * @param run is the index into the font and limit indices arrays. 316 * 317 * @return the <code>LEFontInstance</code> associated with the given text run. 318 * 319 * @see RunArray::getLimit 320 * 321 * @stable ICU 3.2 322 */ 323 const LEFontInstance *getFont(le_int32 run) const; 324 325 326 /** 327 * Add an <code>LEFontInstance</code> and limit index pair to the data arrays and return 328 * the run index where the data was stored. This method calls 329 * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed. 330 * 331 * If the <code>FontRuns</code> object was created with a client-supplied 332 * font and limit indices arrays, this method will return a run index of -1. 333 * 334 * Subclasses should not override this method. Rather they should provide a new <code>add</code> 335 * method which takes a font and a limit index along with whatever other data they implement. 336 * The new <code>add</code> method should first call this method to grow the font and limit indices 337 * arrays, and use the returned run index to store data their own arrays. 338 * 339 * @param font is the address of the <code>LEFontInstance</code> to add. This object must 340 * remain valid until the <code>FontRuns</code> object is destroyed. 341 * 342 * @param limit is the limit index to add 343 * 344 * @return the run index where the font and limit index were stored, or -1 if the data cannot be stored. 345 * 346 * @stable ICU 3.2 347 */ 348 le_int32 add(const LEFontInstance *font, le_int32 limit); 349 350 /** 351 * ICU "poor man's RTTI", returns a UClassID for this class. 352 * 353 * @stable ICU 3.2 354 */ 355 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 356 357 /** 358 * ICU "poor man's RTTI", returns a UClassID for the actual class. 359 * 360 * @stable ICU 3.2 361 */ 362 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 363 364protected: 365 virtual void init(le_int32 capacity); 366 virtual void grow(le_int32 capacity); 367 368private: 369 370 inline FontRuns(); 371 inline FontRuns(const FontRuns &other); 372 inline FontRuns &operator=(const FontRuns & /*other*/) { return *this; }; 373 374 /** 375 * The address of this static class variable serves as this class's ID 376 * for ICU "poor man's RTTI". 377 */ 378 static const char fgClassID; 379 380 const LEFontInstance **fFonts; 381}; 382 383inline FontRuns::FontRuns() 384 : RunArray(0), fFonts(NULL) 385{ 386 // nothing else to do... 387} 388 389inline FontRuns::FontRuns(const FontRuns & /*other*/) 390 : RunArray(0), fFonts(NULL) 391{ 392 // nothing else to do... 393} 394 395inline FontRuns::FontRuns(const LEFontInstance **fonts, const le_int32 *limits, le_int32 count) 396 : RunArray(limits, count), fFonts(fonts) 397{ 398 // nothing else to do... 399} 400 401/** 402 * The <code>LocaleRuns</code> class associates pointers to <code>Locale</code> 403 * objects with runs of text. 404 * 405 * @stable ICU 3.2 406 */ 407class U_LAYOUTEX_API LocaleRuns : public RunArray 408{ 409public: 410 /** 411 * Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales 412 * and limit indices. 413 * 414 * @param locales is the address of an array of pointers to <code>Locale</code> objects. This array, 415 * and the <code>Locale</code> objects to which it points, must remain valid until 416 * the <code>LocaleRuns</code> object is destroyed. 417 * 418 * @param limits is the address of an array of limit indices. This array must remain valid until the 419 * <code>LocaleRuns</code> object is destroyed. 420 * 421 * @param count is the number of entries in the two arrays. 422 * 423 * @stable ICU 3.2 424 */ 425 inline LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count); 426 427 /** 428 * Construct an empty <code>LocaleRuns</code> object. Clients can add locale and limit 429 * indices arrays using the <code>add</code> method. 430 * 431 * @param initialCapacity is the initial size of the locale and limit indices arrays. If 432 * this value is zero, no arrays will be allocated. 433 * 434 * @see add 435 * 436 * @stable ICU 3.2 437 */ 438 LocaleRuns(le_int32 initialCapacity); 439 440 /** 441 * The destructor; virtual so that subclass destructors are invoked as well. 442 * 443 * @stable ICU 3.2 444 */ 445 virtual ~LocaleRuns(); 446 447 /** 448 * Get the <code>Locale</code> object assoicated with the given run 449 * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding 450 * limit index. 451 * 452 * @param run is the index into the font and limit indices arrays. 453 * 454 * @return the <code>Locale</code> associated with the given text run. 455 * 456 * @see RunArray::getLimit 457 * 458 * @stable ICU 3.2 459 */ 460 const Locale *getLocale(le_int32 run) const; 461 462 463 /** 464 * Add a <code>Locale</code> and limit index pair to the data arrays and return 465 * the run index where the data was stored. This method calls 466 * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed. 467 * 468 * If the <code>LocaleRuns</code> object was created with a client-supplied 469 * locale and limit indices arrays, this method will return a run index of -1. 470 * 471 * Subclasses should not override this method. Rather they should provide a new <code>add</code> 472 * method which takes a locale and a limit index along with whatever other data they implement. 473 * The new <code>add</code> method should first call this method to grow the font and limit indices 474 * arrays, and use the returned run index to store data their own arrays. 475 * 476 * @param locale is the address of the <code>Locale</code> to add. This object must remain valid 477 * until the <code>LocaleRuns</code> object is destroyed. 478 * 479 * @param limit is the limit index to add 480 * 481 * @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored. 482 * 483 * @stable ICU 3.2 484 */ 485 le_int32 add(const Locale *locale, le_int32 limit); 486 487 /** 488 * ICU "poor man's RTTI", returns a UClassID for this class. 489 * 490 * @stable ICU 3.2 491 */ 492 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 493 494 /** 495 * ICU "poor man's RTTI", returns a UClassID for the actual class. 496 * 497 * @stable ICU 3.2 498 */ 499 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 500 501protected: 502 virtual void init(le_int32 capacity); 503 virtual void grow(le_int32 capacity); 504 505 /** 506 * @internal 507 */ 508 const Locale **fLocales; 509 510private: 511 512 inline LocaleRuns(); 513 inline LocaleRuns(const LocaleRuns &other); 514 inline LocaleRuns &operator=(const LocaleRuns & /*other*/) { return *this; }; 515 516 /** 517 * The address of this static class variable serves as this class's ID 518 * for ICU "poor man's RTTI". 519 */ 520 static const char fgClassID; 521}; 522 523inline LocaleRuns::LocaleRuns() 524 : RunArray(0), fLocales(NULL) 525{ 526 // nothing else to do... 527} 528 529inline LocaleRuns::LocaleRuns(const LocaleRuns & /*other*/) 530 : RunArray(0), fLocales(NULL) 531{ 532 // nothing else to do... 533} 534 535inline LocaleRuns::LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count) 536 : RunArray(limits, count), fLocales(locales) 537{ 538 // nothing else to do... 539} 540 541/** 542 * The <code>ValueRuns</code> class associates integer values with runs of text. 543 * 544 * @stable ICU 3.2 545 */ 546class U_LAYOUTEX_API ValueRuns : public RunArray 547{ 548public: 549 /** 550 * Construct a <code>ValueRuns</code> object from pre-existing arrays of values 551 * and limit indices. 552 * 553 * @param values is the address of an array of integer. This array must remain valid until 554 * the <code>ValueRuns</code> object is destroyed. 555 * 556 * @param limits is the address of an array of limit indices. This array must remain valid until 557 * the <code>ValueRuns</code> object is destroyed. 558 * 559 * @param count is the number of entries in the two arrays. 560 * 561 * @stable ICU 3.2 562 */ 563 inline ValueRuns(const le_int32 *values, const le_int32 *limits, le_int32 count); 564 565 /** 566 * Construct an empty <code>ValueRuns</code> object. Clients can add value and limit 567 * indices arrays using the <code>add</code> method. 568 * 569 * @param initialCapacity is the initial size of the value and limit indices arrays. If 570 * this value is zero, no arrays will be allocated. 571 * 572 * @see add 573 * 574 * @stable ICU 3.2 575 */ 576 ValueRuns(le_int32 initialCapacity); 577 578 /** 579 * The destructor; virtual so that subclass destructors are invoked as well. 580 * 581 * @stable ICU 3.2 582 */ 583 virtual ~ValueRuns(); 584 585 /** 586 * Get the integer value assoicated with the given run 587 * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding 588 * limit index. 589 * 590 * @param run is the index into the font and limit indices arrays. 591 * 592 * @return the integer value associated with the given text run. 593 * 594 * @see RunArray::getLimit 595 * 596 * @stable ICU 3.2 597 */ 598 le_int32 getValue(le_int32 run) const; 599 600 601 /** 602 * Add an integer value and limit index pair to the data arrays and return 603 * the run index where the data was stored. This method calls 604 * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed. 605 * 606 * If the <code>ValueRuns</code> object was created with a client-supplied 607 * font and limit indices arrays, this method will return a run index of -1. 608 * 609 * Subclasses should not override this method. Rather they should provide a new <code>add</code> 610 * method which takes an integer value and a limit index along with whatever other data they implement. 611 * The new <code>add</code> method should first call this method to grow the font and limit indices 612 * arrays, and use the returned run index to store data their own arrays. 613 * 614 * @param value is the integer value to add 615 * 616 * @param limit is the limit index to add 617 * 618 * @return the run index where the value and limit index were stored, or -1 if the data cannot be stored. 619 * 620 * @stable ICU 3.2 621 */ 622 le_int32 add(le_int32 value, le_int32 limit); 623 624 /** 625 * ICU "poor man's RTTI", returns a UClassID for this class. 626 * 627 * @stable ICU 3.2 628 */ 629 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 630 631 /** 632 * ICU "poor man's RTTI", returns a UClassID for the actual class. 633 * 634 * @stable ICU 3.2 635 */ 636 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 637 638protected: 639 virtual void init(le_int32 capacity); 640 virtual void grow(le_int32 capacity); 641 642private: 643 644 inline ValueRuns(); 645 inline ValueRuns(const ValueRuns &other); 646 inline ValueRuns &operator=(const ValueRuns & /*other*/) { return *this; }; 647 648 /** 649 * The address of this static class variable serves as this class's ID 650 * for ICU "poor man's RTTI". 651 */ 652 static const char fgClassID; 653 654 const le_int32 *fValues; 655}; 656 657inline ValueRuns::ValueRuns() 658 : RunArray(0), fValues(NULL) 659{ 660 // nothing else to do... 661} 662 663inline ValueRuns::ValueRuns(const ValueRuns & /*other*/) 664 : RunArray(0), fValues(NULL) 665{ 666 // nothing else to do... 667} 668 669inline ValueRuns::ValueRuns(const le_int32 *values, const le_int32 *limits, le_int32 count) 670 : RunArray(limits, count), fValues(values) 671{ 672 // nothing else to do... 673} 674 675U_NAMESPACE_END 676#endif 677