2 **********************************************************************
3 * Copyright (C) 2002-2003, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
8 #ifndef __PARAGRAPHLAYOUT_H
10 #define __PARAGRAPHLAYOUT_H
13 * ParagraphLayout doesn't make much sense without
16 #include "unicode/uscript.h"
17 #if ! UCONFIG_NO_BREAK_ITERATION
19 #include "layout/LETypes.h"
20 #include "layout/LEFontInstance.h"
21 #include "layout/LayoutEngine.h"
22 #include "unicode/ubidi.h"
23 #include "unicode/brkiter.h"
25 #include "layout/RunArrays.h"
32 * The <code>ParagraphLayout</code> object will analyze the text into runs of text in the
33 * same font, script and direction, and will create a <code>LayoutEngine</code> object for each run.
34 * The <code>LayoutEngine</code> will transform the characters into glyph codes in visual order.
36 * Clients can use this to break a paragraph into lines, and to display the glyphs in each line.
39 class U_LAYOUTEX_API ParagraphLayout
: public UObject
45 * This class represents a single line of text in a <code>ParagraphLayout</code>. They
46 * can only be created by calling <code>ParagraphLayout::nextLine()</code>. Each line
47 * consists of multiple visual runs, represented by <code>ParagraphLayout::VisualRun</code>
50 * @see ParagraphLayout
51 * @see ParagraphLayout::VisualRun
55 class U_LAYOUTEX_API Line
: public UObject
59 * The constructor is private since these objects can only be
60 * created by <code>ParagraphLayout</code>. However, it is the
61 * clients responsibility to destroy the objects, so the destructor
69 * Count the number of visual runs in the line.
71 * @return the number of visual runs.
75 le_int32
countRuns() const;
78 * Get the ascent of the line. This is the maximum ascent
79 * of all the fonts on the line.
81 * @return the ascent of the line.
85 le_int32
getAscent() const;
88 * Get the descent of the line. This is the maximum descent
89 * of all the fonts on the line.
91 * @return the descent of the line.
95 le_int32
getDescent() const;
98 * Get the leading of the line. This is the maximum leading
99 * of all the fonts on the line.
101 * @return the leading of the line.
105 le_int32
getLeading() const;
108 * Get a <code>ParagraphLayout::VisualRun</code> object for a given
109 * visual run in the line.
111 * @param runIndex is the index of the run, in visual order.
113 * @return the <code>ParagraphLayout::VisualRun</code> object representing the
114 * visual run. This object is owned by the <code>Line</code> object which
115 * created it, and will remain valid for as long as the <code>Line</code>
118 * @see ParagraphLayout::VisualRun
122 const VisualRun
*getVisualRun(le_int32 runIndex
) const;
125 * ICU "poor man's RTTI", returns a UClassID for the actual class.
129 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
132 * ICU "poor man's RTTI", returns a UClassID for this class.
136 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
141 * The address of this static class variable serves as this class's ID
142 * for ICU "poor man's RTTI".
144 static const char fgClassID
;
146 friend class ParagraphLayout
;
153 le_int32 fRunCapacity
;
158 Line(const Line
&other
);
159 Line
&operator=(const Line
& /*other*/) { return *this; };
161 void computeMetrics();
163 void append(const LEFontInstance
*font
, UBiDiDirection direction
, le_int32 glyphCount
,
164 const LEGlyphID glyphs
[], const float positions
[], const le_int32 glyphToCharMap
[]);
168 * This object represents a single visual run in a line of text in
169 * a paragraph. A visual run is text which is in the same font,
170 * script, and direction. The text is represented by an array of
171 * <code>LEGlyphIDs</code>, an array of (x, y) glyph positions and
172 * a table which maps indices into the glyph array to indices into
173 * the original character array which was used to create the paragraph.
175 * These objects are only created by <code>ParagraphLayout::Line<code> objects,
176 * so their constructors and destructors are private.
178 * @see ParagraphLayout::Line
182 class U_LAYOUTEX_API VisualRun
: public UObject
186 * Get the <code>LEFontInstance</code> object which
187 * represents the font of the visual run. This will always
188 * be a non-composite font.
190 * @return the <code>LEFontInstance</code> object which represents the
191 * font of the visual run.
193 * @see LEFontInstance
197 const LEFontInstance
*getFont() const;
200 * Get the direction of the visual run.
202 * @return the direction of the run. This will be UBIDI_LTR if the
203 * run is left-to-right and UBIDI_RTL if the line is right-to-left.
207 UBiDiDirection
getDirection() const;
210 * Get the number of glyphs in the visual run.
212 * @return the number of glyphs.
216 le_int32
getGlyphCount() const;
219 * Get the glyphs in the visual run. Glyphs with the values <code>0xFFFE</code> and
220 * <code>0xFFFF</code> should be ignored.
222 * @return the address of the array of glyphs for this visual run. The storage
223 * is owned by the <code>VisualRun</code> object and must not be deleted.
224 * It will remain valid as long as the <code>VisualRun</code> object is valid.
228 const LEGlyphID
*getGlyphs() const;
231 * Get the (x, y) positions of the glyphs in the visual run. To simplify storage
232 * management, the x and y positions are stored in a single array with the x positions
233 * at even offsets in the array and the corresponding y position in the following odd offset.
234 * There is an extra (x, y) pair at the end of the array which represents the advance of
235 * the final glyph in the run.
237 * @return the address of the array of glyph positions for this visual run. The storage
238 * is owned by the <code>VisualRun</code> object and must not be deleted.
239 * It will remain valid as long as the <code>VisualRun</code> object is valid.
243 const float *getPositions() const;
246 * Get the glyph-to-character map for this visual run. This maps the indices into
247 * the glyph array to indices into the character array used to create the paragraph.
249 * @return the address of the character-to-glyph map for this visual run. The storage
250 * is owned by the <code>VisualRun</code> object and must not be deleted.
251 * It will remain valid as long as the <code>VisualRun</code> object is valid.
255 const le_int32
*getGlyphToCharMap() const;
258 * A convenience method which returns the ascent value for the font
259 * associated with this run.
261 * @return the ascent value of this run's font.
265 le_int32
getAscent() const;
268 * A convenience method which returns the descent value for the font
269 * associated with this run.
271 * @return the descent value of this run's font.
275 le_int32
getDescent() const;
278 * A convenience method which returns the leading value for the font
279 * associated with this run.
281 * @return the leading value of this run's font.
285 le_int32
getLeading() const;
288 * ICU "poor man's RTTI", returns a UClassID for the actual class.
292 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
295 * ICU "poor man's RTTI", returns a UClassID for this class.
299 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
304 * The address of this static class variable serves as this class's ID
305 * for ICU "poor man's RTTI".
307 static const char fgClassID
;
309 const LEFontInstance
*fFont
;
310 const UBiDiDirection fDirection
;
312 const le_int32 fGlyphCount
;
314 const LEGlyphID
*fGlyphs
;
315 const float *fPositions
;
316 const le_int32
*fGlyphToCharMap
;
321 VisualRun(const VisualRun
&other
);
322 VisualRun
&operator=(const VisualRun
&other
) { return *this; };
324 VisualRun(const LEFontInstance
*font
, UBiDiDirection direction
, le_int32 glyphCount
,
325 const LEGlyphID glyphs
[], const float positions
[], const le_int32 glyphToCharMap
[]);
331 * Construct a <code>ParagraphLayout</code> object for a styled paragraph. The paragraph is specified
332 * as runs of text all in the same font. An <code>LEFontInstance</code> object and a limit offset
333 * are specified for each font run. The limit offset is the offset of the character immediately
334 * after the font run.
336 * Clients can optionally specify directional runs and / or script runs. If these aren't specified
337 * they will be computed.
339 * @param chars is an array of the characters in the paragraph
341 * @param count is the number of characters in the paragraph.
343 * @param fontRuns a pointer to a <code>FontRuns</code> object representing the font runs.
345 * @param levelRuns is a pointer to a <code>ValueRuns</code> object representing the directional levels.
346 * If this pointer in <code>NULL</code> the levels will be determined by running the Unicde
349 * @param scriptRuns is a pointer to a <code>ValueRuns</code> object representing script runs.
350 * If this pointer in <code>NULL</code> the script runs will be determined using the
351 * Unicode code points.
353 * @param localeRuns is a pointer to a <code>LocaleRuns</code> object representing locale runs.
354 * The <code>Locale</code> objects are used to determind the language of the text. If this
355 * pointer is <code>NULL</code> the default locale will be used for all of the text.
357 * @param paragraphLevel is the directionality of the paragraph, as in the UBiDi object.
359 * @param vertical is <code>true</code> if the paragraph should be set vertically.
362 * @see LEFontInstance.h
363 * @see LayoutEngine.h
368 ParagraphLayout(const LEUnicode chars
[], le_int32 count
,
369 const FontRuns
*fontRuns
,
370 const ValueRuns
*levelRuns
,
371 const ValueRuns
*scriptRuns
,
372 const LocaleRuns
*localeRuns
,
373 UBiDiLevel paragraphLevel
, le_bool vertical
);
376 * The destructor. Virtual so that it works correctly with
383 // Note: the following is #if 0'd out because there's no good
384 // way to implement it without either calling layoutEngineFactory()
385 // or duplicating the logic there...
388 * Examine the given styled paragraph and determine if it contains any text which
389 * requires complex processing. (i.e. that cannot be correctly rendered by
390 * just mapping the characters to glyphs and rendering them in order)
392 * @param chars is an array of the characters in the paragraph
394 * @param count is the number of characters in the paragraph.
396 * @param fontRuns is a pointer to a <code>FontRuns</code> object representing the font runs.
398 * @return <code>true</code> if the paragraph contains complex text.
402 static le_bool
isComplex(const LEUnicode chars
[], le_int32 count
, const FontRuns
*fontRuns
);
405 * Examine the given text and determine if it contains characters in any
406 * script which requires complex processing to be rendered correctly.
408 * @param chars is an array of the characters in the paragraph
410 * @param count is the number of characters in the paragraph.
412 * @return <code>true</code> if any of the text requires complex processing.
416 static le_bool
isComplex(const LEUnicode chars
[], le_int32 count
);
421 * Return the resolved paragraph level. This is useful for those cases
422 * where the bidi analysis has determined the level based on the first
423 * strong character in the paragraph.
425 * @return the resolved paragraph level.
429 UBiDiLevel
getParagraphLevel();
432 * Return the directionality of the text in the paragraph.
434 * @return <code>UBIDI_LTR</code> if the text is all left to right,
435 * <code>UBIDI_RTL</code> if the text is all right to left,
436 * or <code>UBIDI_MIXED</code> if the text has mixed direction.
440 UBiDiDirection
getTextDirection();
443 * Return the max ascent value for all the fonts
446 * @return the ascent value.
450 virtual le_int32
getAscent() const;
453 * Return the max descent value for all the fonts
456 * @return the decent value.
460 virtual le_int32
getDescent() const;
463 * Return the max leading value for all the fonts
466 * @return the leading value.
470 virtual le_int32
getLeading() const;
473 * Reset line breaking to start from the beginning of the paragraph.
481 * Return a <code>ParagraphLayout::Line</code> object which represents next line
482 * in the paragraph. The width of the line is specified each time so that it can
483 * be varied to support arbitrary paragraph shapes.
485 * @param width is the width of the line. If <code>width</code> is less than or equal
486 * to zero, a <code>ParagraphLayout::Line</code> object representing the
487 * rest of the paragraph will be returned.
489 * @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller
490 * is responsible for deleting the object. Returns <code>NULL</code> if there are no
491 * more lines in the paragraph.
493 * @see ParagraphLayout::Line
497 Line
*nextLine(float width
);
500 * ICU "poor man's RTTI", returns a UClassID for the actual class.
504 virtual inline UClassID
getDynamicClassID() const { return getStaticClassID(); }
507 * ICU "poor man's RTTI", returns a UClassID for this class.
511 static inline UClassID
getStaticClassID() { return (UClassID
)&fgClassID
; }
517 * The address of this static class variable serves as this class's ID
518 * for ICU "poor man's RTTI".
520 static const char fgClassID
;
524 LayoutEngine
*engine
;
525 const LEFontInstance
*font
;
526 const Locale
*locale
;
537 ParagraphLayout() {};
538 ParagraphLayout(const ParagraphLayout
& /*other*/) : UObject( ){};
539 ParagraphLayout
&operator=(const ParagraphLayout
& /*other*/) { return *this; };
541 void computeLevels(UBiDiLevel paragraphLevel
);
543 Line
*computeVisualRuns();
544 void appendRun(Line
*line
, le_int32 run
, le_int32 firstChar
, le_int32 lastChar
);
546 void computeScripts();
548 void computeLocales();
550 void computeSubFonts(const FontRuns
*fontRuns
);
552 void computeMetrics();
554 le_int32
getLanguageCode(const Locale
*locale
);
556 le_int32
getCharRun(le_int32 charIndex
);
558 static le_bool
isComplex(UScriptCode script
);
560 le_int32
previousBreak(le_int32 charIndex
);
563 const LEUnicode
*fChars
;
566 const FontRuns
*fFontRuns
;
567 const ValueRuns
*fLevelRuns
;
568 const ValueRuns
*fScriptRuns
;
569 const LocaleRuns
*fLocaleRuns
;
572 le_bool fClientLevels
;
573 le_bool fClientScripts
;
574 le_bool fClientLocales
;
576 UBiDiLevel
*fEmbeddingLevels
;
582 le_int32
*fGlyphToCharMap
;
583 le_int32
*fCharToGlyphMap
;
585 le_int32 fGlyphCount
;
590 le_int32
*fStyleRunLimits
;
591 le_int32
*fStyleIndices
;
592 StyleRunInfo
*fStyleRunInfo
;
593 le_int32 fStyleRunCount
;
595 BreakIterator
*fBreakIterator
;
599 le_int32 fFirstVisualRun
;
600 le_int32 fLastVisualRun
;
601 float fVisualRunLastX
;
602 float fVisualRunLastY
;
605 inline UBiDiLevel
ParagraphLayout::getParagraphLevel()
607 return ubidi_getParaLevel(fParaBidi
);
610 inline UBiDiDirection
ParagraphLayout::getTextDirection()
612 return ubidi_getDirection(fParaBidi
);
615 inline void ParagraphLayout::reflow()
620 inline ParagraphLayout::Line::Line()
621 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL
)
623 // nothing else to do
626 inline ParagraphLayout::Line::Line(const Line
& /*other*/)
627 : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL
)
629 // nothing else to do
632 inline le_int32
ParagraphLayout::Line::countRuns() const
637 inline const LEFontInstance
*ParagraphLayout::VisualRun::getFont() const
642 inline UBiDiDirection
ParagraphLayout::VisualRun::getDirection() const
647 inline le_int32
ParagraphLayout::VisualRun::getGlyphCount() const
652 inline const LEGlyphID
*ParagraphLayout::VisualRun::getGlyphs() const
657 inline const float *ParagraphLayout::VisualRun::getPositions() const
662 inline const le_int32
*ParagraphLayout::VisualRun::getGlyphToCharMap() const
664 return fGlyphToCharMap
;
667 inline le_int32
ParagraphLayout::VisualRun::getAscent() const
669 return fFont
->getAscent();
672 inline le_int32
ParagraphLayout::VisualRun::getDescent() const
674 return fFont
->getDescent();
677 inline le_int32
ParagraphLayout::VisualRun::getLeading() const
679 return fFont
->getLeading();
682 inline ParagraphLayout::VisualRun::VisualRun()
683 : UObject(), fFont(NULL
), fDirection(UBIDI_LTR
), fGlyphCount(0), fGlyphs(NULL
), fPositions(NULL
), fGlyphToCharMap(NULL
)
688 inline ParagraphLayout::VisualRun::VisualRun(const VisualRun
&other
)
689 : UObject(), fFont(NULL
), fDirection(UBIDI_LTR
), fGlyphCount(0), fGlyphs(NULL
), fPositions(NULL
), fGlyphToCharMap(NULL
)
694 inline ParagraphLayout::VisualRun::VisualRun(const LEFontInstance
*font
, UBiDiDirection direction
, le_int32 glyphCount
,
695 const LEGlyphID glyphs
[], const float positions
[], const le_int32 glyphToCharMap
[])
696 : fFont(font
), fDirection(direction
), fGlyphCount(glyphCount
),
697 fGlyphs(glyphs
), fPositions(positions
), fGlyphToCharMap(glyphToCharMap
)
699 // nothing else needs to be done!
702 inline ParagraphLayout::VisualRun::~VisualRun()
704 LE_DELETE_ARRAY(fGlyphToCharMap
);
705 LE_DELETE_ARRAY(fPositions
);
706 LE_DELETE_ARRAY(fGlyphs
);