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