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 #define CF_PRE_BASE      0x02000000U
     54 
     55 #define CF_POS_BEFORE    0x00300000U
     56 #define CF_POS_BELOW     0x00200000U
     57 #define CF_POS_ABOVE     0x00100000U
     58 #define CF_POS_AFTER     0x00000000U
     59 #define CF_POS_MASK      0x00300000U
     60 
     61 #define CF_INDEX_MASK    0x000F0000U
     62 #define CF_INDEX_SHIFT   16
     63 
     64 // Script flag bits
     65 #define SF_MATRAS_AFTER_BASE     0x80000000U
     66 #define SF_REPH_AFTER_BELOW      0x40000000U
     67 #define SF_EYELASH_RA            0x20000000U
     68 #define SF_MPRE_FIXUP            0x10000000U
     69 #define SF_FILTER_ZERO_WIDTH     0x08000000U
     70 
     71 #define SF_POST_BASE_LIMIT_MASK  0x0000FFFFU
     72 #define SF_NO_POST_BASE_LIMIT    0x00007FFFU
     73 
     74 typedef LEUnicode SplitMatra[3];
     75 
     76 class MPreFixups;
     77 class LEGlyphStorage;
     78 
     79 // Dynamic Properties ( v2 fonts only )
     80 typedef le_uint32 DynamicProperties;
     81 
     82 #define DP_REPH               0x80000000U
     83 #define DP_HALF               0x40000000U
     84 #define DP_PREF               0x20000000U
     85 #define DP_BLWF               0x10000000U
     86 #define DP_PSTF               0x08000000U
     87 
     88 struct IndicClassTable
     89 {
     90     typedef le_uint32 CharClass;
     91     typedef le_uint32 ScriptFlags;
     92 
     93     LEUnicode firstChar;
     94     LEUnicode lastChar;
     95     le_int32 worstCaseExpansion;
     96     ScriptFlags scriptFlags;
     97     const CharClass *classTable;
     98     const SplitMatra *splitMatraTable;
     99 
    100     inline le_int32 getWorstCaseExpansion() const;
    101     inline le_bool getFilterZeroWidth() const;
    102 
    103     CharClass getCharClass(LEUnicode ch) const;
    104 
    105     inline const SplitMatra *getSplitMatra(CharClass charClass) const;
    106 
    107     inline le_bool isVowelModifier(LEUnicode ch) const;
    108     inline le_bool isStressMark(LEUnicode ch) const;
    109     inline le_bool isConsonant(LEUnicode ch) const;
    110     inline le_bool isReph(LEUnicode ch) const;
    111     inline le_bool isVirama(LEUnicode ch) const;
    112     inline le_bool isAlLakuna(LEUnicode ch) const;
    113     inline le_bool isNukta(LEUnicode ch) const;
    114     inline le_bool isVattu(LEUnicode ch) const;
    115     inline le_bool isMatra(LEUnicode ch) const;
    116     inline le_bool isSplitMatra(LEUnicode ch) const;
    117     inline le_bool isLengthMark(LEUnicode ch) const;
    118     inline le_bool hasPostOrBelowBaseForm(LEUnicode ch) const;
    119     inline le_bool hasPostBaseForm(LEUnicode ch) const;
    120     inline le_bool hasBelowBaseForm(LEUnicode ch) const;
    121     inline le_bool hasAboveBaseForm(LEUnicode ch) const;
    122     inline le_bool hasPreBaseForm(LEUnicode ch) const;
    123 
    124     inline static le_bool isVowelModifier(CharClass charClass);
    125     inline static le_bool isStressMark(CharClass charClass);
    126     inline static le_bool isConsonant(CharClass charClass);
    127     inline static le_bool isReph(CharClass charClass);
    128     inline static le_bool isVirama(CharClass charClass);
    129     inline static le_bool isAlLakuna(CharClass charClass);
    130     inline static le_bool isNukta(CharClass charClass);
    131     inline static le_bool isVattu(CharClass charClass);
    132     inline static le_bool isMatra(CharClass charClass);
    133     inline static le_bool isSplitMatra(CharClass charClass);
    134     inline static le_bool isLengthMark(CharClass charClass);
    135     inline static le_bool hasPostOrBelowBaseForm(CharClass charClass);
    136     inline static le_bool hasPostBaseForm(CharClass charClass);
    137     inline static le_bool hasBelowBaseForm(CharClass charClass);
    138     inline static le_bool hasAboveBaseForm(CharClass charClass);
    139     inline static le_bool hasPreBaseForm(CharClass charClass);
    140 
    141     static const IndicClassTable *getScriptClassTable(le_int32 scriptCode);
    142 };
    143 
    144 class IndicReordering /* not : public UObject because all methods are static */ {
    145 public:
    146     static le_int32 getWorstCaseExpansion(le_int32 scriptCode);
    147 
    148     static le_bool getFilterZeroWidth(le_int32 scriptCode);
    149 
    150     static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
    151         LEUnicode *outChars, LEGlyphStorage &glyphStorage,
    152         MPreFixups **outMPreFixups, LEErrorCode& success);
    153 
    154     static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success);
    155 
    156     static le_int32 v2process(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
    157         LEUnicode *outChars, LEGlyphStorage &glyphStorage);
    158 
    159     static const FeatureMap *getFeatureMap(le_int32 &count);
    160 
    161 	static const FeatureMap *getv2FeatureMap(le_int32 &count);
    162 
    163     static void applyPresentationForms(LEGlyphStorage &glyphStorage, le_int32 count);
    164 
    165     static void finalReordering(LEGlyphStorage &glyphStorage, le_int32 count);
    166 
    167     static void getDynamicProperties(DynamicProperties *dProps, const IndicClassTable *classTable);
    168 
    169 private:
    170     // do not instantiate
    171     IndicReordering();
    172 
    173     static le_int32 findSyllable(const IndicClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount);
    174 
    175 };
    176 
    177 inline le_int32 IndicClassTable::getWorstCaseExpansion() const
    178 {
    179     return worstCaseExpansion;
    180 }
    181 
    182 inline le_bool IndicClassTable::getFilterZeroWidth() const
    183 {
    184     return (scriptFlags & SF_FILTER_ZERO_WIDTH) != 0;
    185 }
    186 
    187 inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const
    188 {
    189     le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT;
    190 
    191     return &splitMatraTable[index - 1];
    192 }
    193 
    194 inline le_bool IndicClassTable::isVowelModifier(CharClass charClass)
    195 {
    196     return (charClass & CF_CLASS_MASK) == CC_VOWEL_MODIFIER;
    197 }
    198 
    199 inline le_bool IndicClassTable::isStressMark(CharClass charClass)
    200 {
    201     return (charClass & CF_CLASS_MASK) == CC_STRESS_MARK;
    202 }
    203 
    204 inline le_bool IndicClassTable::isConsonant(CharClass charClass)
    205 {
    206     return (charClass & CF_CONSONANT) != 0;
    207 }
    208 
    209 inline le_bool IndicClassTable::isReph(CharClass charClass)
    210 {
    211     return (charClass & CF_REPH) != 0;
    212 }
    213 
    214 inline le_bool IndicClassTable::isNukta(CharClass charClass)
    215 {
    216     return (charClass & CF_CLASS_MASK) == CC_NUKTA;
    217 }
    218 
    219 inline le_bool IndicClassTable::isVirama(CharClass charClass)
    220 {
    221     return (charClass & CF_CLASS_MASK) == CC_VIRAMA;
    222 }
    223 
    224 inline le_bool IndicClassTable::isAlLakuna(CharClass charClass)
    225 {
    226     return (charClass & CF_CLASS_MASK) == CC_AL_LAKUNA;
    227 }
    228 
    229 inline le_bool IndicClassTable::isVattu(CharClass charClass)
    230 {
    231     return (charClass & CF_VATTU) != 0;
    232 }
    233 
    234 inline le_bool IndicClassTable::isMatra(CharClass charClass)
    235 {
    236     charClass &= CF_CLASS_MASK;
    237 
    238     return charClass >= CC_DEPENDENT_VOWEL && charClass <= CC_SPLIT_VOWEL_PIECE_3;
    239 }
    240 
    241 inline le_bool IndicClassTable::isSplitMatra(CharClass charClass)
    242 {
    243     return (charClass & CF_INDEX_MASK) != 0;
    244 }
    245 
    246 inline le_bool IndicClassTable::isLengthMark(CharClass charClass)
    247 {
    248     return (charClass & CF_LENGTH_MARK) != 0;
    249 }
    250 
    251 inline le_bool IndicClassTable::hasPostOrBelowBaseForm(CharClass charClass)
    252 {
    253     return (charClass & (CF_POST_BASE | CF_BELOW_BASE)) != 0;
    254 }
    255 
    256 inline le_bool IndicClassTable::hasPostBaseForm(CharClass charClass)
    257 {
    258     return (charClass & CF_POST_BASE) != 0;
    259 }
    260 
    261 inline le_bool IndicClassTable::hasPreBaseForm(CharClass charClass)
    262 {
    263     return (charClass & CF_PRE_BASE) != 0;
    264 }
    265 
    266 inline le_bool IndicClassTable::hasBelowBaseForm(CharClass charClass)
    267 {
    268     return (charClass & CF_BELOW_BASE) != 0;
    269 }
    270 
    271 inline le_bool IndicClassTable::hasAboveBaseForm(CharClass charClass)
    272 {
    273     return ((charClass & CF_POS_MASK) == CF_POS_ABOVE);
    274 }
    275 
    276 inline le_bool IndicClassTable::isVowelModifier(LEUnicode ch) const
    277 {
    278     return isVowelModifier(getCharClass(ch));
    279 }
    280 
    281 inline le_bool IndicClassTable::isStressMark(LEUnicode ch) const
    282 {
    283     return isStressMark(getCharClass(ch));
    284 }
    285 
    286 inline le_bool IndicClassTable::isConsonant(LEUnicode ch) const
    287 {
    288     return isConsonant(getCharClass(ch));
    289 }
    290 
    291 inline le_bool IndicClassTable::isReph(LEUnicode ch) const
    292 {
    293     return isReph(getCharClass(ch));
    294 }
    295 
    296 inline le_bool IndicClassTable::isVirama(LEUnicode ch) const
    297 {
    298     return isVirama(getCharClass(ch));
    299 }
    300 
    301 inline le_bool IndicClassTable::isAlLakuna(LEUnicode ch) const
    302 {
    303     return isAlLakuna(getCharClass(ch));
    304 }
    305 
    306 inline le_bool IndicClassTable::isNukta(LEUnicode ch) const
    307 {
    308     return isNukta(getCharClass(ch));
    309 }
    310 
    311 inline le_bool IndicClassTable::isVattu(LEUnicode ch) const
    312 {
    313     return isVattu(getCharClass(ch));
    314 }
    315 
    316 inline le_bool IndicClassTable::isMatra(LEUnicode ch) const
    317 {
    318     return isMatra(getCharClass(ch));
    319 }
    320 
    321 inline le_bool IndicClassTable::isSplitMatra(LEUnicode ch) const
    322 {
    323     return isSplitMatra(getCharClass(ch));
    324 }
    325 
    326 inline le_bool IndicClassTable::isLengthMark(LEUnicode ch) const
    327 {
    328     return isLengthMark(getCharClass(ch));
    329 }
    330 
    331 inline le_bool IndicClassTable::hasPostOrBelowBaseForm(LEUnicode ch) const
    332 {
    333     return hasPostOrBelowBaseForm(getCharClass(ch));
    334 }
    335 
    336 inline le_bool IndicClassTable::hasPostBaseForm(LEUnicode ch) const
    337 {
    338     return hasPostBaseForm(getCharClass(ch));
    339 }
    340 
    341 inline le_bool IndicClassTable::hasBelowBaseForm(LEUnicode ch) const
    342 {
    343     return hasBelowBaseForm(getCharClass(ch));
    344 }
    345 
    346 inline le_bool IndicClassTable::hasPreBaseForm(LEUnicode ch) const
    347 {
    348     return hasPreBaseForm(getCharClass(ch));
    349 }
    350 
    351 inline le_bool IndicClassTable::hasAboveBaseForm(LEUnicode ch) const
    352 {
    353     return hasAboveBaseForm(getCharClass(ch));
    354 }
    355 U_NAMESPACE_END
    356 #endif
    357