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