Home | History | Annotate | Download | only in layout
      1 /*
      2  *
      3  * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
      4  *
      5  */
      6 
      7 #ifndef __INDICREORDERING_H
      8 #define __INDICREORDERING_H
      9 
     10 /**
     11  * \file
     12  * \internal
     13  */
     14 
     15 #include "LETypes.h"
     16 #include "OpenTypeTables.h"
     17 
     18 U_NAMESPACE_BEGIN
     19 
     20 // Characters that get refered to by name...
     21 #define C_SIGN_ZWNJ           0x200C
     22 #define C_SIGN_ZWJ            0x200D
     23 
     24 // Character class values
     25 #define CC_RESERVED               0U
     26 #define CC_VOWEL_MODIFIER         1U
     27 #define CC_STRESS_MARK            2U
     28 #define CC_INDEPENDENT_VOWEL      3U
     29 #define CC_INDEPENDENT_VOWEL_2    4U
     30 #define CC_INDEPENDENT_VOWEL_3    5U
     31 #define CC_CONSONANT              6U
     32 #define CC_CONSONANT_WITH_NUKTA   7U
     33 #define CC_NUKTA                  8U
     34 #define CC_DEPENDENT_VOWEL        9U
     35 #define CC_SPLIT_VOWEL_PIECE_1   10U
     36 #define CC_SPLIT_VOWEL_PIECE_2   11U
     37 #define CC_SPLIT_VOWEL_PIECE_3   12U
     38 #define CC_VIRAMA                13U
     39 #define CC_ZERO_WIDTH_MARK       14U
     40 #define CC_AL_LAKUNA             15U
     41 #define CC_COUNT                 16U
     42 
     43 // Character class flags
     44 #define CF_CLASS_MASK    0x0000FFFFU
     45 
     46 #define CF_CONSONANT     0x80000000U
     47 
     48 #define CF_REPH          0x40000000U
     49 #define CF_VATTU         0x20000000U
     50 #define CF_BELOW_BASE    0x10000000U
     51 #define CF_POST_BASE     0x08000000U
     52 #define CF_LENGTH_MARK   0x04000000U
     53 
     54 #define CF_POS_BEFORE    0x00300000U
     55 #define CF_POS_BELOW     0x00200000U
     56 #define CF_POS_ABOVE     0x00100000U
     57 #define CF_POS_AFTER     0x00000000U
     58 #define CF_POS_MASK      0x00300000U
     59 
     60 #define CF_INDEX_MASK    0x000F0000U
     61 #define CF_INDEX_SHIFT   16
     62 
     63 // Script flag bits
     64 #define SF_MATRAS_AFTER_BASE     0x80000000U
     65 #define SF_REPH_AFTER_BELOW      0x40000000U
     66 #define SF_EYELASH_RA            0x20000000U
     67 #define SF_MPRE_FIXUP            0x10000000U
     68 #define SF_FILTER_ZERO_WIDTH     0x08000000U
     69 
     70 #define SF_POST_BASE_LIMIT_MASK  0x0000FFFFU
     71 #define SF_NO_POST_BASE_LIMIT    0x00007FFFU
     72 
     73 typedef LEUnicode SplitMatra[3];
     74 
     75 class MPreFixups;
     76 class LEGlyphStorage;
     77 
     78 // Dynamic Properties ( v2 fonts only )
     79 typedef le_uint32 DynamicProperties;
     80 
     81 #define DP_REPH               0x80000000U
     82 #define DP_HALF               0x40000000U
     83 #define DP_PREF               0x20000000U
     84 #define DP_BLWF               0x10000000U
     85 #define DP_PSTF               0x08000000U
     86 
     87 struct IndicClassTable
     88 {
     89     typedef le_uint32 CharClass;
     90     typedef le_uint32 ScriptFlags;
     91 
     92     LEUnicode firstChar;
     93     LEUnicode lastChar;
     94     le_int32 worstCaseExpansion;
     95     ScriptFlags scriptFlags;
     96     const CharClass *classTable;
     97     const SplitMatra *splitMatraTable;
     98 
     99     inline le_int32 getWorstCaseExpansion() const;
    100     inline le_bool getFilterZeroWidth() const;
    101 
    102     CharClass getCharClass(LEUnicode ch) const;
    103 
    104     inline const SplitMatra *getSplitMatra(CharClass charClass) const;
    105 
    106     inline le_bool isVowelModifier(LEUnicode ch) const;
    107     inline le_bool isStressMark(LEUnicode ch) const;
    108     inline le_bool isConsonant(LEUnicode ch) const;
    109     inline le_bool isReph(LEUnicode ch) const;
    110     inline le_bool isVirama(LEUnicode ch) const;
    111     inline le_bool isAlLakuna(LEUnicode ch) const;
    112     inline le_bool isNukta(LEUnicode ch) const;
    113     inline le_bool isVattu(LEUnicode ch) const;
    114     inline le_bool isMatra(LEUnicode ch) const;
    115     inline le_bool isSplitMatra(LEUnicode ch) const;
    116     inline le_bool isLengthMark(LEUnicode ch) const;
    117     inline le_bool hasPostOrBelowBaseForm(LEUnicode ch) const;
    118     inline le_bool hasPostBaseForm(LEUnicode ch) const;
    119     inline le_bool hasBelowBaseForm(LEUnicode ch) const;
    120     inline le_bool hasAboveBaseForm(LEUnicode ch) const;
    121 
    122     inline static le_bool isVowelModifier(CharClass charClass);
    123     inline static le_bool isStressMark(CharClass charClass);
    124     inline static le_bool isConsonant(CharClass charClass);
    125     inline static le_bool isReph(CharClass charClass);
    126     inline static le_bool isVirama(CharClass charClass);
    127     inline static le_bool isAlLakuna(CharClass charClass);
    128     inline static le_bool isNukta(CharClass charClass);
    129     inline static le_bool isVattu(CharClass charClass);
    130     inline static le_bool isMatra(CharClass charClass);
    131     inline static le_bool isSplitMatra(CharClass charClass);
    132     inline static le_bool isLengthMark(CharClass charClass);
    133     inline static le_bool hasPostOrBelowBaseForm(CharClass charClass);
    134     inline static le_bool hasPostBaseForm(CharClass charClass);
    135     inline static le_bool hasBelowBaseForm(CharClass charClass);
    136     inline static le_bool hasAboveBaseForm(CharClass charClass);
    137 
    138     static const IndicClassTable *getScriptClassTable(le_int32 scriptCode);
    139 };
    140 
    141 class IndicReordering /* not : public UObject because all methods are static */ {
    142 public:
    143     static le_int32 getWorstCaseExpansion(le_int32 scriptCode);
    144 
    145     static le_bool getFilterZeroWidth(le_int32 scriptCode);
    146 
    147     static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
    148         LEUnicode *outChars, LEGlyphStorage &glyphStorage,
    149         MPreFixups **outMPreFixups, LEErrorCode& success);
    150 
    151     static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success);
    152 
    153     static le_int32 v2process(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
    154         LEUnicode *outChars, LEGlyphStorage &glyphStorage);
    155 
    156     static const FeatureMap *getFeatureMap(le_int32 &count);
    157 
    158 	static const FeatureMap *getv2FeatureMap(le_int32 &count);
    159 
    160     static void applyPresentationForms(LEGlyphStorage &glyphStorage, le_int32 count);
    161 
    162     static void finalReordering(LEGlyphStorage &glyphStorage, le_int32 count);
    163 
    164     static void getDynamicProperties(DynamicProperties *dProps, const IndicClassTable *classTable);
    165 
    166 private:
    167     // do not instantiate
    168     IndicReordering();
    169 
    170     static le_int32 findSyllable(const IndicClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount);
    171 
    172 };
    173 
    174 inline le_int32 IndicClassTable::getWorstCaseExpansion() const
    175 {
    176     return worstCaseExpansion;
    177 }
    178 
    179 inline le_bool IndicClassTable::getFilterZeroWidth() const
    180 {
    181     return (scriptFlags & SF_FILTER_ZERO_WIDTH) != 0;
    182 }
    183 
    184 inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const
    185 {
    186     le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT;
    187 
    188     return &splitMatraTable[index - 1];
    189 }
    190 
    191 inline le_bool IndicClassTable::isVowelModifier(CharClass charClass)
    192 {
    193     return (charClass & CF_CLASS_MASK) == CC_VOWEL_MODIFIER;
    194 }
    195 
    196 inline le_bool IndicClassTable::isStressMark(CharClass charClass)
    197 {
    198     return (charClass & CF_CLASS_MASK) == CC_STRESS_MARK;
    199 }
    200 
    201 inline le_bool IndicClassTable::isConsonant(CharClass charClass)
    202 {
    203     return (charClass & CF_CONSONANT) != 0;
    204 }
    205 
    206 inline le_bool IndicClassTable::isReph(CharClass charClass)
    207 {
    208     return (charClass & CF_REPH) != 0;
    209 }
    210 
    211 inline le_bool IndicClassTable::isNukta(CharClass charClass)
    212 {
    213     return (charClass & CF_CLASS_MASK) == CC_NUKTA;
    214 }
    215 
    216 inline le_bool IndicClassTable::isVirama(CharClass charClass)
    217 {
    218     return (charClass & CF_CLASS_MASK) == CC_VIRAMA;
    219 }
    220 
    221 inline le_bool IndicClassTable::isAlLakuna(CharClass charClass)
    222 {
    223     return (charClass & CF_CLASS_MASK) == CC_AL_LAKUNA;
    224 }
    225 
    226 inline le_bool IndicClassTable::isVattu(CharClass charClass)
    227 {
    228     return (charClass & CF_VATTU) != 0;
    229 }
    230 
    231 inline le_bool IndicClassTable::isMatra(CharClass charClass)
    232 {
    233     charClass &= CF_CLASS_MASK;
    234 
    235     return charClass >= CC_DEPENDENT_VOWEL && charClass <= CC_SPLIT_VOWEL_PIECE_3;
    236 }
    237 
    238 inline le_bool IndicClassTable::isSplitMatra(CharClass charClass)
    239 {
    240     return (charClass & CF_INDEX_MASK) != 0;
    241 }
    242 
    243 inline le_bool IndicClassTable::isLengthMark(CharClass charClass)
    244 {
    245     return (charClass & CF_LENGTH_MARK) != 0;
    246 }
    247 
    248 inline le_bool IndicClassTable::hasPostOrBelowBaseForm(CharClass charClass)
    249 {
    250     return (charClass & (CF_POST_BASE | CF_BELOW_BASE)) != 0;
    251 }
    252 
    253 inline le_bool IndicClassTable::hasPostBaseForm(CharClass charClass)
    254 {
    255     return (charClass & CF_POST_BASE) != 0;
    256 }
    257 
    258 inline le_bool IndicClassTable::hasBelowBaseForm(CharClass charClass)
    259 {
    260     return (charClass & CF_BELOW_BASE) != 0;
    261 }
    262 
    263 inline le_bool IndicClassTable::hasAboveBaseForm(CharClass charClass)
    264 {
    265     return ((charClass & CF_POS_MASK) == CF_POS_ABOVE);
    266 }
    267 
    268 inline le_bool IndicClassTable::isVowelModifier(LEUnicode ch) const
    269 {
    270     return isVowelModifier(getCharClass(ch));
    271 }
    272 
    273 inline le_bool IndicClassTable::isStressMark(LEUnicode ch) const
    274 {
    275     return isStressMark(getCharClass(ch));
    276 }
    277 
    278 inline le_bool IndicClassTable::isConsonant(LEUnicode ch) const
    279 {
    280     return isConsonant(getCharClass(ch));
    281 }
    282 
    283 inline le_bool IndicClassTable::isReph(LEUnicode ch) const
    284 {
    285     return isReph(getCharClass(ch));
    286 }
    287 
    288 inline le_bool IndicClassTable::isVirama(LEUnicode ch) const
    289 {
    290     return isVirama(getCharClass(ch));
    291 }
    292 
    293 inline le_bool IndicClassTable::isAlLakuna(LEUnicode ch) const
    294 {
    295     return isAlLakuna(getCharClass(ch));
    296 }
    297 
    298 inline le_bool IndicClassTable::isNukta(LEUnicode ch) const
    299 {
    300     return isNukta(getCharClass(ch));
    301 }
    302 
    303 inline le_bool IndicClassTable::isVattu(LEUnicode ch) const
    304 {
    305     return isVattu(getCharClass(ch));
    306 }
    307 
    308 inline le_bool IndicClassTable::isMatra(LEUnicode ch) const
    309 {
    310     return isMatra(getCharClass(ch));
    311 }
    312 
    313 inline le_bool IndicClassTable::isSplitMatra(LEUnicode ch) const
    314 {
    315     return isSplitMatra(getCharClass(ch));
    316 }
    317 
    318 inline le_bool IndicClassTable::isLengthMark(LEUnicode ch) const
    319 {
    320     return isLengthMark(getCharClass(ch));
    321 }
    322 
    323 inline le_bool IndicClassTable::hasPostOrBelowBaseForm(LEUnicode ch) const
    324 {
    325     return hasPostOrBelowBaseForm(getCharClass(ch));
    326 }
    327 
    328 inline le_bool IndicClassTable::hasPostBaseForm(LEUnicode ch) const
    329 {
    330     return hasPostBaseForm(getCharClass(ch));
    331 }
    332 
    333 inline le_bool IndicClassTable::hasBelowBaseForm(LEUnicode ch) const
    334 {
    335     return hasBelowBaseForm(getCharClass(ch));
    336 }
    337 
    338 inline le_bool IndicClassTable::hasAboveBaseForm(LEUnicode ch) const
    339 {
    340     return hasAboveBaseForm(getCharClass(ch));
    341 }
    342 U_NAMESPACE_END
    343 #endif
    344