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