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