2 **********************************************************************
3 * Copyright (C) 2002-2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
8 #ifndef __PARAGRAPHLAYOUT_H
10 #define __PARAGRAPHLAYOUT_H
14 * \brief C++ API: Paragraph Layout
18 * ParagraphLayout doesn't make much sense without
21 #include "unicode/uscript.h"
22 #if ! UCONFIG_NO_BREAK_ITERATION
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"
30 #include "layout/RunArrays.h"
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.
41 * Clients can use this to break a paragraph into lines, and to display the glyphs in each line.
43 * Note that {@link icu::LayoutEngine} is deprecated, but this class is not.
44 * You may use this class with the HarfBuzz icu-le-hb wrapper,
45 * see http://www.freedesktop.org/wiki/Software/HarfBuzz/
47 * See http://userguide.icu-project.org/layoutengine for special build instructions.
49 * @see icu::LayoutEngine
51 class U_LAYOUTEX_API ParagraphLayout
: public UObject
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>
62 * @see ParagraphLayout
63 * @see ParagraphLayout::VisualRun
67 class U_LAYOUTEX_API Line
: public UObject
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
81 * Count the number of visual runs in the line.
83 * @return the number of visual runs.
87 inline le_int32
countRuns() const;
90 * Get the ascent of the line. This is the maximum ascent
91 * of all the fonts on the line.
93 * @return the ascent of the line.
97 le_int32
getAscent() const;
100 * Get the descent of the line. This is the maximum descent
101 * of all the fonts on the line.
103 * @return the descent of the line.
107 le_int32
getDescent() const;
110 * Get the leading of the line. This is the maximum leading
111 * of all the fonts on the line.
113 * @return the leading of the line.
117 le_int32
getLeading() const;
120 * Get the width of the line. This is a convenience method
121 * which returns the last X position of the last visual run
124 * @return the width of the line.
128 le_int32
getWidth() const;
131 * Get a <code>ParagraphLayout::VisualRun</code> object for a given
132 * visual run in the line.
134 * @param runIndex is the index of the run, in visual order.
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>
141 * @see ParagraphLayout::VisualRun
145 const VisualRun
*getVisualRun(le_int32 runIndex
) const;
148 * ICU "poor man's RTTI", returns a UClassID for this class.
152 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
155 * ICU "poor man's RTTI", returns a UClassID for the actual class.
159 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
164 * The address of this static class variable serves as this class's ID
165 * for ICU "poor man's RTTI".
167 static const char fgClassID
;
169 friend class ParagraphLayout
;
176 le_int32 fRunCapacity
;
181 inline Line(const Line
&other
);
182 inline Line
&operator=(const Line
& /*other*/) { return *this; };
184 void computeMetrics();
186 void append(const LEFontInstance
*font
, UBiDiDirection direction
, le_int32 glyphCount
,
187 const LEGlyphID glyphs
[], const float positions
[], const le_int32 glyphToCharMap
[]);
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.
198 * These objects are only created by <code>ParagraphLayout::Line</code> objects,
199 * so their constructors and destructors are private.
201 * @see ParagraphLayout::Line
205 class U_LAYOUTEX_API VisualRun
: public UObject
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.
213 * @return the <code>LEFontInstance</code> object which represents the
214 * font of the visual run.
216 * @see LEFontInstance
220 inline const LEFontInstance
*getFont() const;
223 * Get the direction of the visual run.
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.
230 inline UBiDiDirection
getDirection() const;
233 * Get the number of glyphs in the visual run.
235 * @return the number of glyphs.
239 inline le_int32
getGlyphCount() const;
242 * Get the glyphs in the visual run. Glyphs with the values <code>0xFFFE</code> and
243 * <code>0xFFFF</code> should be ignored.
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.
251 inline const LEGlyphID
*getGlyphs() const;
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.
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.
266 inline const float *getPositions() const;
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.
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.
278 inline const le_int32
*getGlyphToCharMap() const;
281 * A convenience method which returns the ascent value for the font
282 * associated with this run.
284 * @return the ascent value of this run's font.
288 inline le_int32
getAscent() const;
291 * A convenience method which returns the descent value for the font
292 * associated with this run.
294 * @return the descent value of this run's font.
298 inline le_int32
getDescent() const;
301 * A convenience method which returns the leading value for the font
302 * associated with this run.
304 * @return the leading value of this run's font.
308 inline le_int32
getLeading() const;
311 * ICU "poor man's RTTI", returns a UClassID for this class.
315 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
318 * ICU "poor man's RTTI", returns a UClassID for the actual class.
322 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
327 * The address of this static class variable serves as this class's ID
328 * for ICU "poor man's RTTI".
330 static const char fgClassID
;
332 const LEFontInstance
*fFont
;
333 const UBiDiDirection fDirection
;
335 const le_int32 fGlyphCount
;
337 const LEGlyphID
*fGlyphs
;
338 const float *fPositions
;
339 const le_int32
*fGlyphToCharMap
;
344 inline VisualRun(const VisualRun
&other
);
345 inline VisualRun
&operator=(const VisualRun
&/*other*/) { return *this; };
347 inline VisualRun(const LEFontInstance
*font
, UBiDiDirection direction
, le_int32 glyphCount
,
348 const LEGlyphID glyphs
[], const float positions
[], const le_int32 glyphToCharMap
[]);
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.
359 * Clients can optionally specify directional runs and / or script runs. If these aren't specified
360 * they will be computed.
362 * If any errors are encountered during construction, <code>status</code> will be set, and the object
363 * will be set to be empty.
365 * @param chars is an array of the characters in the paragraph
367 * @param count is the number of characters in the paragraph.
369 * @param fontRuns a pointer to a <code>FontRuns</code> object representing the font runs.
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
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.
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.
383 * @param paragraphLevel is the directionality of the paragraph, as in the UBiDi object.
385 * @param vertical is <code>TRUE</code> if the paragraph should be set vertically.
387 * @param status will be set to any error code encountered during construction.
390 * @see LEFontInstance.h
391 * @see LayoutEngine.h
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
);
405 * The destructor. Virtual so that it works correctly with
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...
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)
421 * @param chars is an array of the characters in the paragraph
423 * @param count is the number of characters in the paragraph.
425 * @param fontRuns is a pointer to a <code>FontRuns</code> object representing the font runs.
427 * @return <code>TRUE</code> if the paragraph contains complex text.
431 static le_bool
isComplex(const LEUnicode chars
[], le_int32 count
, const FontRuns
*fontRuns
);
434 * Examine the given text and determine if it contains characters in any
435 * script which requires complex processing to be rendered correctly.
437 * @param chars is an array of the characters in the paragraph
439 * @param count is the number of characters in the paragraph.
441 * @return <code>TRUE</code> if any of the text requires complex processing.
445 static le_bool
isComplex(const LEUnicode chars
[], le_int32 count
);
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.
454 * @return the resolved paragraph level.
458 inline UBiDiLevel
getParagraphLevel();
461 * Return the directionality of the text in the paragraph.
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.
469 inline UBiDiDirection
getTextDirection();
472 * Return the max ascent value for all the fonts
475 * @return the ascent value.
479 virtual le_int32
getAscent() const;
482 * Return the max descent value for all the fonts
485 * @return the decent value.
489 virtual le_int32
getDescent() const;
492 * Return the max leading value for all the fonts
495 * @return the leading value.
499 virtual le_int32
getLeading() const;
502 * Reset line breaking to start from the beginning of the paragraph.
507 inline void reflow();
509 #ifndef U_HIDE_INTERNAL_API
512 * Convenience method for determining if paragraph layout processing is complete ( i.e. there
513 * are no more lines left to process. )
515 * @return true if there are no more lines to be processed
519 inline le_bool
isDone() const;
520 #endif /* U_HIDE_INTERNAL_API */
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.
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.
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.
535 * @see ParagraphLayout::Line
539 Line
*nextLine(float width
);
542 * ICU "poor man's RTTI", returns a UClassID for this class.
546 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
549 * ICU "poor man's RTTI", returns a UClassID for the actual class.
553 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
559 * The address of this static class variable serves as this class's ID
560 * for ICU "poor man's RTTI".
562 static const char fgClassID
;
566 LayoutEngine
*engine
;
567 const LEFontInstance
*font
;
568 const Locale
*locale
;
579 ParagraphLayout() {};
580 ParagraphLayout(const ParagraphLayout
& /*other*/) : UObject( ){};
581 inline ParagraphLayout
&operator=(const ParagraphLayout
& /*other*/) { return *this; };
583 void computeLevels(UBiDiLevel paragraphLevel
);
585 Line
*computeVisualRuns();
586 void appendRun(Line
*line
, le_int32 run
, le_int32 firstChar
, le_int32 lastChar
);
588 void computeScripts();
590 void computeLocales();
592 void computeSubFonts(const FontRuns
*fontRuns
, LEErrorCode
&status
);
594 void computeMetrics();
596 le_int32
getLanguageCode(const Locale
*locale
);
598 le_int32
getCharRun(le_int32 charIndex
);
600 static le_bool
isComplex(UScriptCode script
);
602 le_int32
previousBreak(le_int32 charIndex
);
605 const LEUnicode
*fChars
;
608 const FontRuns
*fFontRuns
;
609 const ValueRuns
*fLevelRuns
;
610 const ValueRuns
*fScriptRuns
;
611 const LocaleRuns
*fLocaleRuns
;
614 le_bool fClientLevels
;
615 le_bool fClientScripts
;
616 le_bool fClientLocales
;
618 UBiDiLevel
*fEmbeddingLevels
;
624 le_int32
*fGlyphToCharMap
;
625 le_int32
*fCharToMinGlyphMap
;
626 le_int32
*fCharToMaxGlyphMap
;
628 le_int32 fGlyphCount
;
633 le_int32
*fStyleRunLimits
;
634 le_int32
*fStyleIndices
;
635 StyleRunInfo
*fStyleRunInfo
;
636 le_int32 fStyleRunCount
;
638 BreakIterator
*fBreakIterator
;
642 le_int32 fFirstVisualRun
;
643 le_int32 fLastVisualRun
;
644 float fVisualRunLastX
;
645 float fVisualRunLastY
;
648 inline UBiDiLevel
ParagraphLayout::getParagraphLevel()
650 return ubidi_getParaLevel(fParaBidi
);
653 inline UBiDiDirection
ParagraphLayout::getTextDirection()
655 return ubidi_getDirection(fParaBidi
);
658 inline void ParagraphLayout::reflow()
663 inline ParagraphLayout::Line::Line()
664 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL
)
666 // nothing else to do
669 inline ParagraphLayout::Line::Line(const Line
& /*other*/)
670 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL
)
672 // nothing else to do
675 inline le_int32
ParagraphLayout::Line::countRuns() const
680 inline const LEFontInstance
*ParagraphLayout::VisualRun::getFont() const
685 inline UBiDiDirection
ParagraphLayout::VisualRun::getDirection() const
690 inline le_int32
ParagraphLayout::VisualRun::getGlyphCount() const
695 inline const LEGlyphID
*ParagraphLayout::VisualRun::getGlyphs() const
700 inline const float *ParagraphLayout::VisualRun::getPositions() const
705 inline const le_int32
*ParagraphLayout::VisualRun::getGlyphToCharMap() const
707 return fGlyphToCharMap
;
710 inline le_int32
ParagraphLayout::VisualRun::getAscent() const
712 return fFont
->getAscent();
715 inline le_int32
ParagraphLayout::VisualRun::getDescent() const
717 return fFont
->getDescent();
720 inline le_int32
ParagraphLayout::VisualRun::getLeading() const
722 return fFont
->getLeading();
725 inline ParagraphLayout::VisualRun::VisualRun()
726 : UObject(), fFont(NULL
), fDirection(UBIDI_LTR
), fGlyphCount(0), fGlyphs(NULL
), fPositions(NULL
), fGlyphToCharMap(NULL
)
731 inline ParagraphLayout::VisualRun::VisualRun(const VisualRun
&/*other*/)
732 : UObject(), fFont(NULL
), fDirection(UBIDI_LTR
), fGlyphCount(0), fGlyphs(NULL
), fPositions(NULL
), fGlyphToCharMap(NULL
)
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
)
742 // nothing else needs to be done!