1 /* 2 ********************************************************************** 3 * Copyright (C) 2002-2010, 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 * 503 * Convenience method for determining if paragraph layout processing is complete ( i.e. there 504 * are no more lines left to process. ) 505 * 506 * @return true if there are no more lines to be processed 507 * 508 * @internal 509 */ 510 inline le_bool isDone() const; 511 512 /** 513 * Return a <code>ParagraphLayout::Line</code> object which represents next line 514 * in the paragraph. The width of the line is specified each time so that it can 515 * be varied to support arbitrary paragraph shapes. 516 * 517 * @param width is the width of the line. If <code>width</code> is less than or equal 518 * to zero, a <code>ParagraphLayout::Line</code> object representing the 519 * rest of the paragraph will be returned. 520 * 521 * @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller 522 * is responsible for deleting the object. Returns <code>NULL</code> if there are no 523 * more lines in the paragraph. 524 * 525 * @see ParagraphLayout::Line 526 * 527 * @stable ICU 3.2 528 */ 529 Line *nextLine(float width); 530 531 /** 532 * ICU "poor man's RTTI", returns a UClassID for this class. 533 * 534 * @stable ICU 3.2 535 */ 536 static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } 537 538 /** 539 * ICU "poor man's RTTI", returns a UClassID for the actual class. 540 * 541 * @stable ICU 3.2 542 */ 543 virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } 544 545 private: 546 547 548 /** 549 * The address of this static class variable serves as this class's ID 550 * for ICU "poor man's RTTI". 551 */ 552 static const char fgClassID; 553 554 struct StyleRunInfo 555 { 556 LayoutEngine *engine; 557 const LEFontInstance *font; 558 const Locale *locale; 559 LEGlyphID *glyphs; 560 float *positions; 561 UScriptCode script; 562 UBiDiLevel level; 563 le_int32 runBase; 564 le_int32 runLimit; 565 le_int32 glyphBase; 566 le_int32 glyphCount; 567 }; 568 569 ParagraphLayout() {}; 570 ParagraphLayout(const ParagraphLayout & /*other*/) : UObject( ){}; 571 inline ParagraphLayout &operator=(const ParagraphLayout & /*other*/) { return *this; }; 572 573 void computeLevels(UBiDiLevel paragraphLevel); 574 575 Line *computeVisualRuns(); 576 void appendRun(Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar); 577 578 void computeScripts(); 579 580 void computeLocales(); 581 582 void computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status); 583 584 void computeMetrics(); 585 586 le_int32 getLanguageCode(const Locale *locale); 587 588 le_int32 getCharRun(le_int32 charIndex); 589 590 static le_bool isComplex(UScriptCode script); 591 592 le_int32 previousBreak(le_int32 charIndex); 593 594 595 const LEUnicode *fChars; 596 le_int32 fCharCount; 597 598 const FontRuns *fFontRuns; 599 const ValueRuns *fLevelRuns; 600 const ValueRuns *fScriptRuns; 601 const LocaleRuns *fLocaleRuns; 602 603 le_bool fVertical; 604 le_bool fClientLevels; 605 le_bool fClientScripts; 606 le_bool fClientLocales; 607 608 UBiDiLevel *fEmbeddingLevels; 609 610 le_int32 fAscent; 611 le_int32 fDescent; 612 le_int32 fLeading; 613 614 le_int32 *fGlyphToCharMap; 615 le_int32 *fCharToMinGlyphMap; 616 le_int32 *fCharToMaxGlyphMap; 617 float *fGlyphWidths; 618 le_int32 fGlyphCount; 619 620 UBiDi *fParaBidi; 621 UBiDi *fLineBidi; 622 623 le_int32 *fStyleRunLimits; 624 le_int32 *fStyleIndices; 625 StyleRunInfo *fStyleRunInfo; 626 le_int32 fStyleRunCount; 627 628 BreakIterator *fBreakIterator; 629 le_int32 fLineStart; 630 le_int32 fLineEnd; 631 632 le_int32 fFirstVisualRun; 633 le_int32 fLastVisualRun; 634 float fVisualRunLastX; 635 float fVisualRunLastY; 636 }; 637 638 inline UBiDiLevel ParagraphLayout::getParagraphLevel() 639 { 640 return ubidi_getParaLevel(fParaBidi); 641 } 642 643 inline UBiDiDirection ParagraphLayout::getTextDirection() 644 { 645 return ubidi_getDirection(fParaBidi); 646 } 647 648 inline void ParagraphLayout::reflow() 649 { 650 fLineEnd = 0; 651 } 652 653 inline ParagraphLayout::Line::Line() 654 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL) 655 { 656 // nothing else to do 657 } 658 659 inline ParagraphLayout::Line::Line(const Line & /*other*/) 660 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL) 661 { 662 // nothing else to do 663 } 664 665 inline le_int32 ParagraphLayout::Line::countRuns() const 666 { 667 return fRunCount; 668 } 669 670 inline const LEFontInstance *ParagraphLayout::VisualRun::getFont() const 671 { 672 return fFont; 673 } 674 675 inline UBiDiDirection ParagraphLayout::VisualRun::getDirection() const 676 { 677 return fDirection; 678 } 679 680 inline le_int32 ParagraphLayout::VisualRun::getGlyphCount() const 681 { 682 return fGlyphCount; 683 } 684 685 inline const LEGlyphID *ParagraphLayout::VisualRun::getGlyphs() const 686 { 687 return fGlyphs; 688 } 689 690 inline const float *ParagraphLayout::VisualRun::getPositions() const 691 { 692 return fPositions; 693 } 694 695 inline const le_int32 *ParagraphLayout::VisualRun::getGlyphToCharMap() const 696 { 697 return fGlyphToCharMap; 698 } 699 700 inline le_int32 ParagraphLayout::VisualRun::getAscent() const 701 { 702 return fFont->getAscent(); 703 } 704 705 inline le_int32 ParagraphLayout::VisualRun::getDescent() const 706 { 707 return fFont->getDescent(); 708 } 709 710 inline le_int32 ParagraphLayout::VisualRun::getLeading() const 711 { 712 return fFont->getLeading(); 713 } 714 715 inline ParagraphLayout::VisualRun::VisualRun() 716 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL) 717 { 718 // nothing 719 } 720 721 inline ParagraphLayout::VisualRun::VisualRun(const VisualRun &/*other*/) 722 : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL) 723 { 724 // nothing 725 } 726 727 inline ParagraphLayout::VisualRun::VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount, 728 const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]) 729 : fFont(font), fDirection(direction), fGlyphCount(glyphCount), 730 fGlyphs(glyphs), fPositions(positions), fGlyphToCharMap(glyphToCharMap) 731 { 732 // nothing else needs to be done! 733 } 734 735 U_NAMESPACE_END 736 #endif 737 #endif 738