• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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          */
getStaticClassID()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          */
getDynamicClassID()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          */
getStaticClassID()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          */
getDynamicClassID()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      */
getStaticClassID()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      */
getDynamicClassID()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 
ParagraphLayout()559     ParagraphLayout() {};
ParagraphLayout(const 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 
getParagraphLevel()628 inline UBiDiLevel ParagraphLayout::getParagraphLevel()
629 {
630     return ubidi_getParaLevel(fParaBidi);
631 }
632 
getTextDirection()633 inline UBiDiDirection ParagraphLayout::getTextDirection()
634 {
635     return ubidi_getDirection(fParaBidi);
636 }
637 
reflow()638 inline void ParagraphLayout::reflow()
639 {
640     fLineEnd = 0;
641 }
642 
Line()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 
Line(const Line &)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 
countRuns()655 inline le_int32 ParagraphLayout::Line::countRuns() const
656 {
657     return fRunCount;
658 }
659 
getFont()660 inline const LEFontInstance *ParagraphLayout::VisualRun::getFont() const
661 {
662     return fFont;
663 }
664 
getDirection()665 inline UBiDiDirection ParagraphLayout::VisualRun::getDirection() const
666 {
667     return fDirection;
668 }
669 
getGlyphCount()670 inline le_int32 ParagraphLayout::VisualRun::getGlyphCount() const
671 {
672     return fGlyphCount;
673 }
674 
getGlyphs()675 inline const LEGlyphID *ParagraphLayout::VisualRun::getGlyphs() const
676 {
677     return fGlyphs;
678 }
679 
getPositions()680 inline const float *ParagraphLayout::VisualRun::getPositions() const
681 {
682     return fPositions;
683 }
684 
getGlyphToCharMap()685 inline const le_int32 *ParagraphLayout::VisualRun::getGlyphToCharMap() const
686 {
687     return fGlyphToCharMap;
688 }
689 
getAscent()690 inline le_int32 ParagraphLayout::VisualRun::getAscent() const
691 {
692     return fFont->getAscent();
693 }
694 
getDescent()695 inline le_int32 ParagraphLayout::VisualRun::getDescent() const
696 {
697     return fFont->getDescent();
698 }
699 
getLeading()700 inline le_int32 ParagraphLayout::VisualRun::getLeading() const
701 {
702     return fFont->getLeading();
703 }
704 
VisualRun()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 
VisualRun(const VisualRun &)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 
VisualRun(const LEFontInstance * font,UBiDiDirection direction,le_int32 glyphCount,const LEGlyphID glyphs[],const float positions[],const le_int32 glyphToCharMap[])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