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