Home | History | Annotate | Download | only in layout
      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 
     34 U_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 the ICU layout engine has been deprecated and removed.
     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 class U_LAYOUTEX_API ParagraphLayout : public UObject
     52 {
     53 public:
     54     class VisualRun;
     55 
     56     /**
     57      * This class represents a single line of text in a <code>ParagraphLayout</code>. They
     58      * can only be created by calling <code>ParagraphLayout::nextLine()</code>. Each line
     59      * consists of multiple visual runs, represented by <code>ParagraphLayout::VisualRun</code>
     60      * objects.
     61      *
     62      * @see ParagraphLayout
     63      * @see ParagraphLayout::VisualRun
     64      *
     65      * @stable ICU 3.2
     66      */
     67     class U_LAYOUTEX_API Line : public UObject
     68     {
     69     public:
     70         /**
     71          * The constructor is private since these objects can only be
     72          * created by <code>ParagraphLayout</code>. However, it is the
     73          * clients responsibility to destroy the objects, so the destructor
     74          * is public.
     75         *
     76         * @stable ICU 3.2
     77          */
     78         ~Line();
     79 
     80         /**
     81          * Count the number of visual runs in the line.
     82          *
     83          * @return the number of visual runs.
     84          *
     85          * @stable ICU 3.2
     86          */
     87         inline le_int32 countRuns() const;
     88 
     89         /**
     90          * Get the ascent of the line. This is the maximum ascent
     91          * of all the fonts on the line.
     92          *
     93          * @return the ascent of the line.
     94          *
     95          * @stable ICU 3.2
     96          */
     97         le_int32 getAscent() const;
     98 
     99         /**
    100          * Get the descent of the line. This is the maximum descent
    101          * of all the fonts on the line.
    102          *
    103          * @return the descent of the line.
    104          *
    105          * @stable ICU 3.2
    106          */
    107         le_int32 getDescent() const;
    108 
    109         /**
    110          * Get the leading of the line. This is the maximum leading
    111          * of all the fonts on the line.
    112          *
    113          * @return the leading of the line.
    114          *
    115          * @stable ICU 3.2
    116          */
    117         le_int32 getLeading() const;
    118 
    119         /**
    120          * Get the width of the line. This is a convenience method
    121          * which returns the last X position of the last visual run
    122          * in the line.
    123          *
    124          * @return the width of the line.
    125          *
    126          * @stable ICU 2.8
    127          */
    128         le_int32 getWidth() const;
    129 
    130         /**
    131          * Get a <code>ParagraphLayout::VisualRun</code> object for a given
    132          * visual run in the line.
    133          *
    134          * @param runIndex is the index of the run, in visual order.
    135          *
    136          * @return the <code>ParagraphLayout::VisualRun</code> object representing the
    137          *         visual run. This object is owned by the <code>Line</code> object which
    138          *         created it, and will remain valid for as long as the <code>Line</code>
    139          *         object is valid.
    140          *
    141          * @see ParagraphLayout::VisualRun
    142          *
    143          * @stable ICU 3.2
    144          */
    145         const VisualRun *getVisualRun(le_int32 runIndex) const;
    146 
    147         /**
    148          * ICU "poor man's RTTI", returns a UClassID for this class.
    149          *
    150          * @stable ICU 3.2
    151          */
    152         static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
    153 
    154         /**
    155          * ICU "poor man's RTTI", returns a UClassID for the actual class.
    156          *
    157          * @stable ICU 3.2
    158          */
    159         virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
    160 
    161     private:
    162 
    163         /**
    164          * The address of this static class variable serves as this class's ID
    165          * for ICU "poor man's RTTI".
    166          */
    167         static const char fgClassID;
    168 
    169         friend class ParagraphLayout;
    170 
    171         le_int32 fAscent;
    172         le_int32 fDescent;
    173         le_int32 fLeading;
    174 
    175         le_int32 fRunCount;
    176         le_int32 fRunCapacity;
    177 
    178         VisualRun **fRuns;
    179 
    180         inline Line();
    181         inline Line(const Line &other);
    182         inline Line &operator=(const Line & /*other*/) { return *this; };
    183 
    184         void computeMetrics();
    185 
    186         void append(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
    187                     const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]);
    188     };
    189 
    190     /**
    191      * This object represents a single visual run in a line of text in
    192      * a paragraph. A visual run is text which is in the same font,
    193      * script, and direction. The text is represented by an array of
    194      * <code>LEGlyphIDs</code>, an array of (x, y) glyph positions and
    195      * a table which maps indices into the glyph array to indices into
    196      * the original character array which was used to create the paragraph.
    197      *
    198      * These objects are only created by <code>ParagraphLayout::Line</code> objects,
    199      * so their constructors and destructors are private.
    200      *
    201      * @see ParagraphLayout::Line
    202      *
    203      * @stable ICU 3.2
    204      */
    205     class U_LAYOUTEX_API VisualRun : public UObject
    206     {
    207     public:
    208         /**
    209          * Get the <code>LEFontInstance</code> object which
    210          * represents the font of the visual run. This will always
    211          * be a non-composite font.
    212          *
    213          * @return the <code>LEFontInstance</code> object which represents the
    214          *         font of the visual run.
    215          *
    216          * @see LEFontInstance
    217          *
    218          * @stable ICU 3.2
    219          */
    220         inline const LEFontInstance *getFont() const;
    221 
    222         /**
    223          * Get the direction of the visual run.
    224          *
    225          * @return the direction of the run. This will be UBIDI_LTR if the
    226          *         run is left-to-right and UBIDI_RTL if the line is right-to-left.
    227          *
    228          * @stable ICU 3.2
    229          */
    230         inline UBiDiDirection getDirection() const;
    231 
    232         /**
    233          * Get the number of glyphs in the visual run.
    234          *
    235          * @return the number of glyphs.
    236          *
    237          * @stable ICU 3.2
    238          */
    239         inline le_int32 getGlyphCount() const;
    240 
    241         /**
    242          * Get the glyphs in the visual run. Glyphs with the values <code>0xFFFE</code> and
    243          * <code>0xFFFF</code> should be ignored.
    244          *
    245          * @return the address of the array of glyphs for this visual run. The storage
    246          *         is owned by the <code>VisualRun</code> object and must not be deleted.
    247          *         It will remain valid as long as the <code>VisualRun</code> object is valid.
    248          *
    249          * @stable ICU 3.2
    250          */
    251         inline const LEGlyphID *getGlyphs() const;
    252 
    253         /**
    254          * Get the (x, y) positions of the glyphs in the visual run. To simplify storage
    255          * management, the x and y positions are stored in a single array with the x positions
    256          * at even offsets in the array and the corresponding y position in the following odd offset.
    257          * There is an extra (x, y) pair at the end of the array which represents the advance of
    258          * the final glyph in the run.
    259          *
    260          * @return the address of the array of glyph positions for this visual run. The storage
    261          *         is owned by the <code>VisualRun</code> object and must not be deleted.
    262          *         It will remain valid as long as the <code>VisualRun</code> object is valid.
    263          *
    264          * @stable ICU 3.2
    265          */
    266         inline const float *getPositions() const;
    267 
    268         /**
    269          * Get the glyph-to-character map for this visual run. This maps the indices into
    270          * the glyph array to indices into the character array used to create the paragraph.
    271          *
    272          * @return the address of the character-to-glyph map for this visual run. The storage
    273          *         is owned by the <code>VisualRun</code> object and must not be deleted.
    274          *         It will remain valid as long as the <code>VisualRun</code> object is valid.
    275          *
    276          * @stable ICU 3.2
    277          */
    278         inline const le_int32 *getGlyphToCharMap() const;
    279 
    280         /**
    281          * A convenience method which returns the ascent value for the font
    282          * associated with this run.
    283          *
    284          * @return the ascent value of this run's font.
    285          *
    286          * @stable ICU 3.2
    287          */
    288         inline le_int32 getAscent() const;
    289 
    290         /**
    291          * A convenience method which returns the descent value for the font
    292          * associated with this run.
    293          *
    294          * @return the descent value of this run's font.
    295          *
    296          * @stable ICU 3.2
    297          */
    298         inline le_int32 getDescent() const;
    299 
    300         /**
    301          * A convenience method which returns the leading value for the font
    302          * associated with this run.
    303          *
    304          * @return the leading value of this run's font.
    305          *
    306          * @stable ICU 3.2
    307          */
    308         inline le_int32 getLeading() const;
    309 
    310         /**
    311          * ICU "poor man's RTTI", returns a UClassID for this class.
    312          *
    313          * @stable ICU 3.2
    314          */
    315         static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
    316 
    317         /**
    318          * ICU "poor man's RTTI", returns a UClassID for the actual class.
    319          *
    320          * @stable ICU 3.2
    321          */
    322         virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
    323 
    324     private:
    325 
    326         /**
    327          * The address of this static class variable serves as this class's ID
    328          * for ICU "poor man's RTTI".
    329          */
    330         static const char fgClassID;
    331 
    332         const LEFontInstance *fFont;
    333         const UBiDiDirection  fDirection;
    334 
    335         const le_int32 fGlyphCount;
    336 
    337         const LEGlyphID *fGlyphs;
    338         const float     *fPositions;
    339         const le_int32  *fGlyphToCharMap;
    340 
    341         friend class Line;
    342 
    343         inline VisualRun();
    344         inline VisualRun(const VisualRun &other);
    345         inline VisualRun &operator=(const VisualRun &/*other*/) { return *this; };
    346 
    347         inline VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
    348                   const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[]);
    349 
    350         ~VisualRun();
    351     };
    352 
    353     /**
    354      * Construct a <code>ParagraphLayout</code> object for a styled paragraph. The paragraph is specified
    355      * as runs of text all in the same font. An <code>LEFontInstance</code> object and a limit offset
    356      * are specified for each font run. The limit offset is the offset of the character immediately
    357      * after the font run.
    358      *
    359      * Clients can optionally specify directional runs and / or script runs. If these aren't specified
    360      * they will be computed.
    361      *
    362      * If any errors are encountered during construction, <code>status</code> will be set, and the object
    363      * will be set to be empty.
    364      *
    365      * @param chars is an array of the characters in the paragraph
    366      *
    367      * @param count is the number of characters in the paragraph.
    368      *
    369      * @param fontRuns a pointer to a <code>FontRuns</code> object representing the font runs.
    370      *
    371      * @param levelRuns is a pointer to a <code>ValueRuns</code> object representing the directional levels.
    372      *        If this pointer in <code>NULL</code> the levels will be determined by running the Unicde
    373      *        Bidi algorithm.
    374      *
    375      * @param scriptRuns is a pointer to a <code>ValueRuns</code> object representing script runs.
    376      *        If this pointer in <code>NULL</code> the script runs will be determined using the
    377      *        Unicode code points.
    378      *
    379      * @param localeRuns is a pointer to a <code>LocaleRuns</code> object representing locale runs.
    380      *        The <code>Locale</code> objects are used to determind the language of the text. If this
    381      *        pointer is <code>NULL</code> the default locale will be used for all of the text.
    382      *
    383      * @param paragraphLevel is the directionality of the paragraph, as in the UBiDi object.
    384      *
    385      * @param vertical is <code>TRUE</code> if the paragraph should be set vertically.
    386      *
    387      * @param status will be set to any error code encountered during construction.
    388      *
    389      * @see ubidi.h
    390      * @see LEFontInstance.h
    391      * @see LayoutEngine.h
    392      * @see RunArrays.h
    393      *
    394      * @stable ICU 2.8
    395      */
    396     ParagraphLayout(const LEUnicode chars[], le_int32 count,
    397                     const FontRuns *fontRuns,
    398                     const ValueRuns *levelRuns,
    399                     const ValueRuns *scriptRuns,
    400                     const LocaleRuns *localeRuns,
    401                     UBiDiLevel paragraphLevel, le_bool vertical,
    402                     LEErrorCode &status);
    403 
    404     /**
    405      * The destructor. Virtual so that it works correctly with
    406      * sublcasses.
    407      *
    408      * @stable ICU 3.2
    409      */
    410     ~ParagraphLayout();
    411 
    412     // Note: the following is #if 0'd out because there's no good
    413     // way to implement it without either calling layoutEngineFactory()
    414     // or duplicating the logic there...
    415 #if 0
    416     /**
    417      * Examine the given styled paragraph and determine if it contains any text which
    418      * requires complex processing. (i.e. that cannot be correctly rendered by
    419      * just mapping the characters to glyphs and rendering them in order)
    420      *
    421      * @param chars is an array of the characters in the paragraph
    422      *
    423      * @param count is the number of characters in the paragraph.
    424      *
    425      * @param fontRuns is a pointer to a <code>FontRuns</code> object representing the font runs.
    426      *
    427      * @return <code>TRUE</code> if the paragraph contains complex text.
    428      *
    429      * @stable ICU 3.2
    430      */
    431     static le_bool isComplex(const LEUnicode chars[], le_int32 count, const FontRuns *fontRuns);
    432 #else
    433     /**
    434      * Examine the given text and determine if it contains characters in any
    435      * script which requires complex processing to be rendered correctly.
    436      *
    437      * @param chars is an array of the characters in the paragraph
    438      *
    439      * @param count is the number of characters in the paragraph.
    440      *
    441      * @return <code>TRUE</code> if any of the text requires complex processing.
    442      *
    443      * @stable ICU 3.2
    444      */
    445     static le_bool isComplex(const LEUnicode chars[], le_int32 count);
    446 
    447 #endif
    448 
    449     /**
    450      * Return the resolved paragraph level. This is useful for those cases
    451      * where the bidi analysis has determined the level based on the first
    452      * strong character in the paragraph.
    453      *
    454      * @return the resolved paragraph level.
    455      *
    456      * @stable ICU 3.2
    457      */
    458     inline UBiDiLevel getParagraphLevel();
    459 
    460     /**
    461      * Return the directionality of the text in the paragraph.
    462      *
    463      * @return <code>UBIDI_LTR</code> if the text is all left to right,
    464      *         <code>UBIDI_RTL</code> if the text is all right to left,
    465      *         or <code>UBIDI_MIXED</code> if the text has mixed direction.
    466      *
    467      * @stable ICU 3.2
    468      */
    469     inline UBiDiDirection getTextDirection();
    470 
    471     /**
    472      * Return the max ascent value for all the fonts
    473      * in the paragraph.
    474      *
    475      * @return the ascent value.
    476      *
    477      * @stable ICU 3.2
    478      */
    479     virtual le_int32 getAscent() const;
    480 
    481     /**
    482      * Return the max descent value for all the fonts
    483      * in the paragraph.
    484      *
    485      * @return the decent value.
    486      *
    487      * @stable ICU 3.2
    488      */
    489     virtual le_int32 getDescent() const;
    490 
    491     /**
    492      * Return the max leading value for all the fonts
    493      * in the paragraph.
    494      *
    495      * @return the leading value.
    496      *
    497      * @stable ICU 3.2
    498      */
    499     virtual le_int32 getLeading() const;
    500 
    501     /**
    502      * Reset line breaking to start from the beginning of the paragraph.
    503      *
    504      *
    505      * @stable ICU 3.2
    506      */
    507     inline void reflow();
    508 
    509 #ifndef U_HIDE_INTERNAL_API
    510     /**
    511      *
    512      * Convenience method for determining if paragraph layout processing is complete ( i.e. there
    513      * are no more lines left to process. )
    514      *
    515      * @return true if there are no more lines to be processed
    516      *
    517      * @internal
    518      */
    519     inline le_bool isDone() const;
    520 #endif  /* U_HIDE_INTERNAL_API */
    521 
    522     /**
    523      * Return a <code>ParagraphLayout::Line</code> object which represents next line
    524      * in the paragraph. The width of the line is specified each time so that it can
    525      * be varied to support arbitrary paragraph shapes.
    526      *
    527      * @param width is the width of the line. If <code>width</code> is less than or equal
    528      *              to zero, a <code>ParagraphLayout::Line</code> object representing the
    529      *              rest of the paragraph will be returned.
    530      *
    531      * @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller
    532      *         is responsible for deleting the object. Returns <code>NULL</code> if there are no
    533      *         more lines in the paragraph.
    534      *
    535      * @see ParagraphLayout::Line
    536      *
    537      * @stable ICU 3.2
    538      */
    539     Line *nextLine(float width);
    540 
    541     /**
    542      * ICU "poor man's RTTI", returns a UClassID for this class.
    543      *
    544      * @stable ICU 3.2
    545      */
    546     static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
    547 
    548     /**
    549      * ICU "poor man's RTTI", returns a UClassID for the actual class.
    550      *
    551      * @stable ICU 3.2
    552      */
    553     virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
    554 
    555 private:
    556 
    557 
    558     /**
    559      * The address of this static class variable serves as this class's ID
    560      * for ICU "poor man's RTTI".
    561      */
    562     static const char fgClassID;
    563 
    564     struct StyleRunInfo
    565     {
    566           LayoutEngine   *engine;
    567     const LEFontInstance *font;
    568     const Locale         *locale;
    569           LEGlyphID      *glyphs;
    570           float          *positions;
    571           UScriptCode     script;
    572           UBiDiLevel      level;
    573           le_int32        runBase;
    574           le_int32        runLimit;
    575           le_int32        glyphBase;
    576           le_int32        glyphCount;
    577     };
    578 
    579     ParagraphLayout() {};
    580     ParagraphLayout(const ParagraphLayout & /*other*/) : UObject( ){};
    581     inline ParagraphLayout &operator=(const ParagraphLayout & /*other*/) { return *this; };
    582 
    583     void computeLevels(UBiDiLevel paragraphLevel);
    584 
    585     Line *computeVisualRuns();
    586     void appendRun(Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar);
    587 
    588     void computeScripts();
    589 
    590     void computeLocales();
    591 
    592     void computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status);
    593 
    594     void computeMetrics();
    595 
    596     le_int32 getLanguageCode(const Locale *locale);
    597 
    598     le_int32 getCharRun(le_int32 charIndex);
    599 
    600     static le_bool isComplex(UScriptCode script);
    601 
    602     le_int32 previousBreak(le_int32 charIndex);
    603 
    604 
    605     const LEUnicode *fChars;
    606           le_int32   fCharCount;
    607 
    608     const FontRuns   *fFontRuns;
    609     const ValueRuns  *fLevelRuns;
    610     const ValueRuns  *fScriptRuns;
    611     const LocaleRuns *fLocaleRuns;
    612 
    613           le_bool fVertical;
    614           le_bool fClientLevels;
    615           le_bool fClientScripts;
    616           le_bool fClientLocales;
    617 
    618           UBiDiLevel *fEmbeddingLevels;
    619 
    620           le_int32 fAscent;
    621           le_int32 fDescent;
    622           le_int32 fLeading;
    623 
    624           le_int32 *fGlyphToCharMap;
    625           le_int32 *fCharToMinGlyphMap;
    626           le_int32 *fCharToMaxGlyphMap;
    627           float    *fGlyphWidths;
    628           le_int32  fGlyphCount;
    629 
    630           UBiDi *fParaBidi;
    631           UBiDi *fLineBidi;
    632 
    633           le_int32     *fStyleRunLimits;
    634           le_int32     *fStyleIndices;
    635           StyleRunInfo *fStyleRunInfo;
    636           le_int32      fStyleRunCount;
    637 
    638           BreakIterator *fBreakIterator;
    639           le_int32       fLineStart;
    640           le_int32       fLineEnd;
    641 
    642           le_int32       fFirstVisualRun;
    643           le_int32       fLastVisualRun;
    644           float          fVisualRunLastX;
    645           float          fVisualRunLastY;
    646 };
    647 
    648 inline UBiDiLevel ParagraphLayout::getParagraphLevel()
    649 {
    650     return ubidi_getParaLevel(fParaBidi);
    651 }
    652 
    653 inline UBiDiDirection ParagraphLayout::getTextDirection()
    654 {
    655     return ubidi_getDirection(fParaBidi);
    656 }
    657 
    658 inline void ParagraphLayout::reflow()
    659 {
    660     fLineEnd = 0;
    661 }
    662 
    663 inline ParagraphLayout::Line::Line()
    664     : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL)
    665 {
    666     // nothing else to do
    667 }
    668 
    669 inline ParagraphLayout::Line::Line(const Line & /*other*/)
    670     : UObject(), fAscent(0), fDescent(0), fLeading(0), fRunCount(0), fRunCapacity(0), fRuns(NULL)
    671 {
    672     // nothing else to do
    673 }
    674 
    675 inline le_int32 ParagraphLayout::Line::countRuns() const
    676 {
    677     return fRunCount;
    678 }
    679 
    680 inline const LEFontInstance *ParagraphLayout::VisualRun::getFont() const
    681 {
    682     return fFont;
    683 }
    684 
    685 inline UBiDiDirection ParagraphLayout::VisualRun::getDirection() const
    686 {
    687     return fDirection;
    688 }
    689 
    690 inline le_int32 ParagraphLayout::VisualRun::getGlyphCount() const
    691 {
    692     return fGlyphCount;
    693 }
    694 
    695 inline const LEGlyphID *ParagraphLayout::VisualRun::getGlyphs() const
    696 {
    697     return fGlyphs;
    698 }
    699 
    700 inline const float *ParagraphLayout::VisualRun::getPositions() const
    701 {
    702     return fPositions;
    703 }
    704 
    705 inline const le_int32 *ParagraphLayout::VisualRun::getGlyphToCharMap() const
    706 {
    707     return fGlyphToCharMap;
    708 }
    709 
    710 inline le_int32 ParagraphLayout::VisualRun::getAscent() const
    711 {
    712     return fFont->getAscent();
    713 }
    714 
    715 inline le_int32 ParagraphLayout::VisualRun::getDescent() const
    716 {
    717     return fFont->getDescent();
    718 }
    719 
    720 inline le_int32 ParagraphLayout::VisualRun::getLeading() const
    721 {
    722     return fFont->getLeading();
    723 }
    724 
    725 inline ParagraphLayout::VisualRun::VisualRun()
    726     : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL)
    727 {
    728     // nothing
    729 }
    730 
    731 inline ParagraphLayout::VisualRun::VisualRun(const VisualRun &/*other*/)
    732     : UObject(), fFont(NULL), fDirection(UBIDI_LTR), fGlyphCount(0), fGlyphs(NULL), fPositions(NULL), fGlyphToCharMap(NULL)
    733 {
    734     // nothing
    735 }
    736 
    737 inline ParagraphLayout::VisualRun::VisualRun(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
    738                                              const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[])
    739     : fFont(font), fDirection(direction), fGlyphCount(glyphCount),
    740       fGlyphs(glyphs), fPositions(positions), fGlyphToCharMap(glyphToCharMap)
    741 {
    742     // nothing else needs to be done!
    743 }
    744 
    745 U_NAMESPACE_END
    746 #endif
    747 #endif
    748