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