1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ********************************************************************** 5 * Copyright (C) 2002-2014, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ********************************************************************** 8 */ 9 10 #ifndef __PARAGRAPHLAYOUT_H 11 12 #define __PARAGRAPHLAYOUT_H 13 14 /** 15 * \file 16 * \brief C++ API: Paragraph Layout 17 */ 18 19 /* 20 * ParagraphLayout doesn't make much sense without 21 * BreakIterator... 22 */ 23 #include "unicode/uscript.h" 24 #if ! UCONFIG_NO_BREAK_ITERATION 25 26 #include "layout/LETypes.h" 27 #include "layout/LEFontInstance.h" 28 #include "layout/LayoutEngine.h" 29 #include "unicode/ubidi.h" 30 #include "unicode/brkiter.h" 31 32 #include "layout/RunArrays.h" 33 34 U_NAMESPACE_BEGIN 35 36 /** 37 * ParagraphLayout. 38 * 39 * The <code>ParagraphLayout</code> object will analyze the text into runs of text in the 40 * same font, script and direction, and will create a <code>LayoutEngine</code> object for each run. 41 * The <code>LayoutEngine</code> will transform the characters into glyph codes in visual order. 42 * 43 * Clients can use this to break a paragraph into lines, and to display the glyphs in each line. 44 * 45 * Note that the ICU layout engine has been deprecated and removed. 46 * You may use this class with the HarfBuzz icu-le-hb wrapper, 47 * see http://www.freedesktop.org/wiki/Software/HarfBuzz/ 48 * 49 * See http://userguide.icu-project.org/layoutengine for special build instructions. 50 */ 51 class U_LAYOUTEX_API ParagraphLayout : public UObject 52 { 53 public: 54 class VisualRun; 55 56 /** 57 * This class represents a single line of text in a <code>ParagraphLayout</code>. They 58 * can only be created by calling <code>ParagraphLayout::nextLine()</code>. Each line 59 * consists of multiple visual runs, represented by <code>ParagraphLayout::VisualRun</code> 60 * objects. 61 * 62 * @see ParagraphLayout 63 * @see ParagraphLayout::VisualRun 64 * 65 * @stable ICU 3.2 66 */ 67 class U_LAYOUTEX_API Line : public UObject 68 { 69 public: 70 /** 71 * The constructor is private since these objects can only be 72 * created by <code>ParagraphLayout</code>. However, it is the 73 * clients responsibility to destroy the objects, so the destructor 74 * is public. 75 * 76 * @stable ICU 3.2 77 */ 78 ~Line(); 79 80 /** 81 * Count the number of visual runs in the line. 82 * 83 * @return the number of visual runs. 84 * 85 * @stable ICU 3.2 86 */ 87 inline le_int32 countRuns() const; 88 89 /** 90 * Get the ascent of the line. This is the maximum ascent 91 * of all the fonts on the line. 92 * 93 * @return the ascent of the line. 94 * 95 * @stable ICU 3.2 96 */ 97 le_int32 getAscent() const; 98 99 /** 100 * Get the descent of the line. This is the maximum descent 101 * of all the fonts on the line. 102 * 103 * @return the descent of the line. 104 * 105 * @stable ICU 3.2 106 */ 107 le_int32 getDescent() const; 108 109 /** 110 * Get the leading of the line. This is the maximum leading 111 * of all the fonts on the line. 112 * 113 * @return the leading of the line. 114 * 115 * @stable ICU 3.2 116 */ 117 le_int32 getLeading() const; 118 119 /** 120 * Get the width of the line. This is a convenience method 121 * which returns the last X position of the last visual run 122 * in the line. 123 * 124 * @return the width of the line. 125 * 126 * @stable ICU 2.8 127 */ 128 le_int32 getWidth() const; 129 130 /** 131 * Get a <code>ParagraphLayout::VisualRun</code> object for a given 132 * visual run in the line. 133 * 134 * @param runIndex is the index of the run, in visual order. 135 * 136 * @return the <code>ParagraphLayout::VisualRun</code> object representing the 137 * visual run. This object is owned by the <code>Line</code> object which 138 * created it, and will remain valid for as long as the <code>Line</code> 139 * object is valid. 140 * 141 * @see ParagraphLayout::VisualRun 142 * 143 * @stable ICU 3.2 144 */ 145 const VisualRun *getVisualRun(le_int32 runIndex) const; 146 147 /** 148 * ICU "poor man's RTTI", returns a UClassID for this class. 149 * 150 * @stable ICU 3.2 151 */ 152 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 153 154 /** 155 * ICU "poor man's RTTI", returns a UClassID for the actual class. 156 * 157 * @stable ICU 3.2 158 */ 159 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 160 161 private: 162 163 /** 164 * The address of this static class variable serves as this class's ID 165 * for ICU "poor man's RTTI". 166 */ 167 static const char fgClassID; 168 169 friend class ParagraphLayout; 170 171 le_int32 fAscent; 172 le_int32 fDescent; 173 le_int32 fLeading; 174 175 le_int32 fRunCount; 176 le_int32 fRunCapacity; 177 178 VisualRun **fRuns; 179 180 inline Line(); 181 inline Line(const Line &other); 182 inline Line &operator=(const Line & /*other*/) { return *this; }; 183 184 void computeMetrics(); 185 186 void append(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount, 187 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]); 188 }; 189 190 /** 191 * This object represents a single visual run in a line of text in 192 * a paragraph. A visual run is text which is in the same font, 193 * script, and direction. The text is represented by an array of 194 * <code>LEGlyphIDs</code>, an array of (x, y) glyph positions and 195 * a table which maps indices into the glyph array to indices into 196 * the original character array which was used to create the paragraph. 197 * 198 * These objects are only created by <code>ParagraphLayout::Line</code> objects, 199 * so their constructors and destructors are private. 200 * 201 * @see ParagraphLayout::Line 202 * 203 * @stable ICU 3.2 204 */ 205 class U_LAYOUTEX_API VisualRun : public UObject 206 { 207 public: 208 /** 209 * Get the <code>LEFontInstance</code> object which 210 * represents the font of the visual run. This will always 211 * be a non-composite font. 212 * 213 * @return the <code>LEFontInstance</code> object which represents the 214 * font of the visual run. 215 * 216 * @see LEFontInstance 217 * 218 * @stable ICU 3.2 219 */ 220 inline const LEFontInstance *getFont() const; 221 222 /** 223 * Get the direction of the visual run. 224 * 225 * @return the direction of the run. This will be UBIDI_LTR if the 226 * run is left-to-right and UBIDI_RTL if the line is right-to-left. 227 * 228 * @stable ICU 3.2 229 */ 230 inline UBiDiDirection getDirection() const; 231 232 /** 233 * Get the number of glyphs in the visual run. 234 * 235 * @return the number of glyphs. 236 * 237 * @stable ICU 3.2 238 */ 239 inline le_int32 getGlyphCount() const; 240 241 /** 242 * Get the glyphs in the visual run. Glyphs with the values <code>0xFFFE</code> and 243 * <code>0xFFFF</code> should be ignored. 244 * 245 * @return the address of the array of glyphs for this visual run. The storage 246 * is owned by the <code>VisualRun</code> object and must not be deleted. 247 * It will remain valid as long as the <code>VisualRun</code> object is valid. 248 * 249 * @stable ICU 3.2 250 */ 251 inline const LEGlyphID *getGlyphs() const; 252 253 /** 254 * Get the (x, y) positions of the glyphs in the visual run. To simplify storage 255 * management, the x and y positions are stored in a single array with the x positions 256 * at even offsets in the array and the corresponding y position in the following odd offset. 257 * There is an extra (x, y) pair at the end of the array which represents the advance of 258 * the final glyph in the run. 259 * 260 * @return the address of the array of glyph positions for this visual run. The storage 261 * is owned by the <code>VisualRun</code> object and must not be deleted. 262 * It will remain valid as long as the <code>VisualRun</code> object is valid. 263 * 264 * @stable ICU 3.2 265 */ 266 inline const float *getPositions() const; 267 268 /** 269 * Get the glyph-to-character map for this visual run. This maps the indices into 270 * the glyph array to indices into the character array used to create the paragraph. 271 * 272 * @return the address of the character-to-glyph map for this visual run. The storage 273 * is owned by the <code>VisualRun</code> object and must not be deleted. 274 * It will remain valid as long as the <code>VisualRun</code> object is valid. 275 * 276 * @stable ICU 3.2 277 */ 278 inline const le_int32 *getGlyphToCharMap() const; 279 280 /** 281 * A convenience method which returns the ascent value for the font 282 * associated with this run. 283 * 284 * @return the ascent value of this run's font. 285 * 286 * @stable ICU 3.2 287 */ 288 inline le_int32 getAscent() const; 289 290 /** 291 * A convenience method which returns the descent value for the font 292 * associated with this run. 293 * 294 * @return the descent value of this run's font. 295 * 296 * @stable ICU 3.2 297 */ 298 inline le_int32 getDescent() const; 299 300 /** 301 * A convenience method which returns the leading value for the font 302 * associated with this run. 303 * 304 * @return the leading value of this run's font. 305 * 306 * @stable ICU 3.2 307 */ 308 inline le_int32 getLeading() const; 309 310 /** 311 * ICU "poor man's RTTI", returns a UClassID for this class. 312 * 313 * @stable ICU 3.2 314 */ 315 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 316 317 /** 318 * ICU "poor man's RTTI", returns a UClassID for the actual class. 319 * 320 * @stable ICU 3.2 321 */ 322 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 323 324 private: 325 326 /** 327 * The address of this static class variable serves as this class's ID 328 * for ICU "poor man's RTTI". 329 */ 330 static const char fgClassID; 331 332 const LEFontInstance *fFont; 333 const UBiDiDirection fDirection; 334 335 const le_int32 fGlyphCount; 336 337 const LEGlyphID *fGlyphs; 338 const float *fPositions; 339 const le_int32 *fGlyphToCharMap; 340 341 friend class Line; 342 343 inline VisualRun(); 344 inline VisualRun(const VisualRun &other); 345 inline VisualRun &operator=(const VisualRun &/*other*/) { return *this; }; 346 347 inline VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount, 348 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]); 349 350 ~VisualRun(); 351 }; 352 353 /** 354 * Construct a <code>ParagraphLayout</code> object for a styled paragraph. The paragraph is specified 355 * as runs of text all in the same font. An <code>LEFontInstance</code> object and a limit offset 356 * are specified for each font run. The limit offset is the offset of the character immediately 357 * after the font run. 358 * 359 * Clients can optionally specify directional runs and / or script runs. If these aren't specified 360 * they will be computed. 361 * 362 * If any errors are encountered during construction, <code>status</code> will be set, and the object 363 * will be set to be empty. 364 * 365 * @param chars is an array of the characters in the paragraph 366 * 367 * @param count is the number of characters in the paragraph. 368 * 369 * @param fontRuns a pointer to a <code>FontRuns</code> object representing the font runs. 370 * 371 * @param levelRuns is a pointer to a <code>ValueRuns</code> object representing the directional levels. 372 * If this pointer in <code>NULL</code> the levels will be determined by running the Unicde 373 * Bidi algorithm. 374 * 375 * @param scriptRuns is a pointer to a <code>ValueRuns</code> object representing script runs. 376 * If this pointer in <code>NULL</code> the script runs will be determined using the 377 * Unicode code points. 378 * 379 * @param localeRuns is a pointer to a <code>LocaleRuns</code> object representing locale runs. 380 * The <code>Locale</code> objects are used to determind the language of the text. If this 381 * pointer is <code>NULL</code> the default locale will be used for all of the text. 382 * 383 * @param paragraphLevel is the directionality of the paragraph, as in the UBiDi object. 384 * 385 * @param vertical is <code>TRUE</code> if the paragraph should be set vertically. 386 * 387 * @param status will be set to any error code encountered during construction. 388 * 389 * @see ubidi.h 390 * @see LEFontInstance.h 391 * @see LayoutEngine.h 392 * @see RunArrays.h 393 * 394 * @stable ICU 2.8 395 */ 396 ParagraphLayout(const LEUnicode chars[], le_int32 count, 397 const FontRuns *fontRuns, 398 const ValueRuns *levelRuns, 399 const ValueRuns *scriptRuns, 400 const LocaleRuns *localeRuns, 401 UBiDiLevel paragraphLevel, le_bool vertical, 402 LEErrorCode &status); 403 404 /** 405 * The destructor. Virtual so that it works correctly with 406 * sublcasses. 407 * 408 * @stable ICU 3.2 409 */ 410 ~ParagraphLayout(); 411 412 // Note: the following is #if 0'd out because there's no good 413 // way to implement it without either calling layoutEngineFactory() 414 // or duplicating the logic there... 415 #if 0 416 /** 417 * Examine the given styled paragraph and determine if it contains any text which 418 * requires complex processing. (i.e. that cannot be correctly rendered by 419 * just mapping the characters to glyphs and rendering them in order) 420 * 421 * @param chars is an array of the characters in the paragraph 422 * 423 * @param count is the number of characters in the paragraph. 424 * 425 * @param fontRuns is a pointer to a <code>FontRuns</code> object representing the font runs. 426 * 427 * @return <code>TRUE</code> if the paragraph contains complex text. 428 * 429 * @stable ICU 3.2 430 */ 431 static le_bool isComplex(const LEUnicode chars[], le_int32 count, const FontRuns *fontRuns); 432 #else 433 /** 434 * Examine the given text and determine if it contains characters in any 435 * script which requires complex processing to be rendered correctly. 436 * 437 * @param chars is an array of the characters in the paragraph 438 * 439 * @param count is the number of characters in the paragraph. 440 * 441 * @return <code>TRUE</code> if any of the text requires complex processing. 442 * 443 * @stable ICU 3.2 444 */ 445 static le_bool isComplex(const LEUnicode chars[], le_int32 count); 446 447 #endif 448 449 /** 450 * Return the resolved paragraph level. This is useful for those cases 451 * where the bidi analysis has determined the level based on the first 452 * strong character in the paragraph. 453 * 454 * @return the resolved paragraph level. 455 * 456 * @stable ICU 3.2 457 */ 458 inline UBiDiLevel getParagraphLevel(); 459 460 /** 461 * Return the directionality of the text in the paragraph. 462 * 463 * @return <code>UBIDI_LTR</code> if the text is all left to right, 464 * <code>UBIDI_RTL</code> if the text is all right to left, 465 * or <code>UBIDI_MIXED</code> if the text has mixed direction. 466 * 467 * @stable ICU 3.2 468 */ 469 inline UBiDiDirection getTextDirection(); 470 471 /** 472 * Return the max ascent value for all the fonts 473 * in the paragraph. 474 * 475 * @return the ascent value. 476 * 477 * @stable ICU 3.2 478 */ 479 virtual le_int32 getAscent() const; 480 481 /** 482 * Return the max descent value for all the fonts 483 * in the paragraph. 484 * 485 * @return the decent value. 486 * 487 * @stable ICU 3.2 488 */ 489 virtual le_int32 getDescent() const; 490 491 /** 492 * Return the max leading value for all the fonts 493 * in the paragraph. 494 * 495 * @return the leading value. 496 * 497 * @stable ICU 3.2 498 */ 499 virtual le_int32 getLeading() const; 500 501 /** 502 * Reset line breaking to start from the beginning of the paragraph. 503 * 504 * 505 * @stable ICU 3.2 506 */ 507 inline void reflow(); 508 509 #ifndef U_HIDE_INTERNAL_API 510 /** 511 * 512 * Convenience method for determining if paragraph layout processing is complete ( i.e. there 513 * are no more lines left to process. ) 514 * 515 * @return true if there are no more lines to be processed 516 * 517 * @internal 518 */ 519 inline le_bool isDone() const; 520 #endif /* U_HIDE_INTERNAL_API */ 521 522 /** 523 * Return a <code>ParagraphLayout::Line</code> object which represents next line 524 * in the paragraph. The width of the line is specified each time so that it can 525 * be varied to support arbitrary paragraph shapes. 526 * 527 * @param width is the width of the line. If <code>width</code> is less than or equal 528 * to zero, a <code>ParagraphLayout::Line</code> object representing the 529 * rest of the paragraph will be returned. 530 * 531 * @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller 532 * is responsible for deleting the object. Returns <code>NULL</code> if there are no 533 * more lines in the paragraph. 534 * 535 * @see ParagraphLayout::Line 536 * 537 * @stable ICU 3.2 538 */ 539 Line *nextLine(float width); 540 541 /** 542 * ICU "poor man's RTTI", returns a UClassID for this class. 543 * 544 * @stable ICU 3.2 545 */ 546 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 547 548 /** 549 * ICU "poor man's RTTI", returns a UClassID for the actual class. 550 * 551 * @stable ICU 3.2 552 */ 553 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 554 555 private: 556 557 558 /** 559 * The address of this static class variable serves as this class's ID 560 * for ICU "poor man's RTTI". 561 */ 562 static const char fgClassID; 563 564 struct StyleRunInfo 565 { 566 LayoutEngine *engine; 567 const LEFontInstance *font; 568 const Locale *locale; 569 LEGlyphID *glyphs; 570 float *positions; 571 UScriptCode script; 572 UBiDiLevel level; 573 le_int32 runBase; 574 le_int32 runLimit; 575 le_int32 glyphBase; 576 le_int32 glyphCount; 577 }; 578 579 ParagraphLayout() {}; 580 ParagraphLayout(const ParagraphLayout & /*other*/) : UObject( ){}; 581 inline ParagraphLayout &operator=(const ParagraphLayout & /*other*/) { return *this; }; 582 583 void computeLevels(UBiDiLevel paragraphLevel); 584 585 Line *computeVisualRuns(); 586 void appendRun(Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar); 587 588 void computeScripts(); 589 590 void computeLocales(); 591 592 void computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status); 593 594 void computeMetrics(); 595 596 le_int32 getLanguageCode(const Locale *locale); 597 598 le_int32 getCharRun(le_int32 charIndex); 599 600 static le_bool isComplex(UScriptCode script); 601 602 le_int32 previousBreak(le_int32 charIndex); 603 604 605 const LEUnicode *fChars; 606 le_int32 fCharCount; 607 608 const FontRuns *fFontRuns; 609 const ValueRuns *fLevelRuns; 610 const ValueRuns *fScriptRuns; 611 const LocaleRuns *fLocaleRuns; 612 613 le_bool fVertical; 614 le_bool fClientLevels; 615 le_bool fClientScripts; 616 le_bool fClientLocales; 617 618 UBiDiLevel *fEmbeddingLevels; 619 620 le_int32 fAscent; 621 le_int32 fDescent; 622 le_int32 fLeading; 623 624 le_int32 *fGlyphToCharMap; 625 le_int32 *fCharToMinGlyphMap; 626 le_int32 *fCharToMaxGlyphMap; 627 float *fGlyphWidths; 628 le_int32 fGlyphCount; 629 630 UBiDi *fParaBidi; 631 UBiDi *fLineBidi; 632 633 le_int32 *fStyleRunLimits; 634 le_int32 *fStyleIndices; 635 StyleRunInfo *fStyleRunInfo; 636 le_int32 fStyleRunCount; 637 638 BreakIterator *fBreakIterator; 639 le_int32 fLineStart; 640 le_int32 fLineEnd; 641 642 le_int32 fFirstVisualRun; 643 le_int32 fLastVisualRun; 644 float fVisualRunLastX; 645 float fVisualRunLastY; 646 }; 647 648 inline UBiDiLevel ParagraphLayout::getParagraphLevel() 649 { 650 return ubidi_getParaLevel(fParaBidi); 651 } 652 653 inline UBiDiDirection ParagraphLayout::getTextDirection() 654 { 655 return ubidi_getDirection(fParaBidi); 656 } 657 658 inline void ParagraphLayout::reflow() 659 { 660 fLineEnd = 0; 661 } 662 663 inline ParagraphLayout::Line::Line() 664 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL) 665 { 666 // nothing else to do 667 } 668 669 inline ParagraphLayout::Line::Line(const Line & /*other*/) 670 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL) 671 { 672 // nothing else to do 673 } 674 675 inline le_int32 ParagraphLayout::Line::countRuns() const 676 { 677 return fRunCount; 678 } 679 680 inline const LEFontInstance *ParagraphLayout::VisualRun::getFont() const 681 { 682 return fFont; 683 } 684 685 inline UBiDiDirection ParagraphLayout::VisualRun::getDirection() const 686 { 687 return fDirection; 688 } 689 690 inline le_int32 ParagraphLayout::VisualRun::getGlyphCount() const 691 { 692 return fGlyphCount; 693 } 694 695 inline const LEGlyphID *ParagraphLayout::VisualRun::getGlyphs() const 696 { 697 return fGlyphs; 698 } 699 700 inline const float *ParagraphLayout::VisualRun::getPositions() const 701 { 702 return fPositions; 703 } 704 705 inline const le_int32 *ParagraphLayout::VisualRun::getGlyphToCharMap() const 706 { 707 return fGlyphToCharMap; 708 } 709 710 inline le_int32 ParagraphLayout::VisualRun::getAscent() const 711 { 712 return fFont->getAscent(); 713 } 714 715 inline le_int32 ParagraphLayout::VisualRun::getDescent() const 716 { 717 return fFont->getDescent(); 718 } 719 720 inline le_int32 ParagraphLayout::VisualRun::getLeading() const 721 { 722 return fFont->getLeading(); 723 } 724 725 inline ParagraphLayout::VisualRun::VisualRun() 726 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL) 727 { 728 // nothing 729 } 730 731 inline ParagraphLayout::VisualRun::VisualRun(const VisualRun &/*other*/) 732 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL) 733 { 734 // nothing 735 } 736 737 inline ParagraphLayout::VisualRun::VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount, 738 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]) 739 : fFont(font), fDirection(direction), fGlyphCount(glyphCount), 740 fGlyphs(glyphs), fPositions(positions), fGlyphToCharMap(glyphToCharMap) 741 { 742 // nothing else needs to be done! 743 } 744 745 U_NAMESPACE_END 746 #endif 747 #endif 748