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