Home | History | Annotate | Download | only in layout
      1 /*
      2  *
      3  * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved
      4  *
      5  */
      6 
      7 #include "LETypes.h"
      8 #include "LEGlyphStorage.h"
      9 #include "MPreFixups.h"
     10 
     11 U_NAMESPACE_BEGIN
     12 
     13 struct FixupData
     14 {
     15     le_int32 fBaseIndex;
     16     le_int32 fMPreIndex;
     17 };
     18 
     19 MPreFixups::MPreFixups(le_int32 charCount)
     20     : fFixupData(NULL), fFixupCount(0)
     21 {
     22     fFixupData = LE_NEW_ARRAY(FixupData, charCount);
     23 }
     24 
     25 MPreFixups::~MPreFixups()
     26 {
     27     LE_DELETE_ARRAY(fFixupData);
     28     fFixupData = NULL;
     29 }
     30 
     31 void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex)
     32 {
     33     // NOTE: don't add the fixup data if the mpre is right
     34     // before the base consonant glyph.
     35     if (baseIndex - mpreIndex > 1) {
     36         fFixupData[fFixupCount].fBaseIndex = baseIndex;
     37         fFixupData[fFixupCount].fMPreIndex = mpreIndex;
     38 
     39         fFixupCount += 1;
     40     }
     41 }
     42 
     43 void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success)
     44 {
     45     if (LE_FAILURE(success)) {
     46         return;
     47     }
     48 
     49     for (le_int32 fixup = 0; fixup < fFixupCount; fixup += 1) {
     50         le_int32 baseIndex = fFixupData[fixup].fBaseIndex;
     51         le_int32 mpreIndex = fFixupData[fixup].fMPreIndex;
     52         le_int32 mpreLimit = mpreIndex + 1;
     53 
     54         while (glyphStorage[baseIndex] == 0xFFFF || glyphStorage[baseIndex] == 0xFFFE) {
     55             baseIndex -= 1;
     56         }
     57 
     58         while (glyphStorage[mpreLimit] == 0xFFFF || glyphStorage[mpreLimit] == 0xFFFE) {
     59             mpreLimit += 1;
     60         }
     61 
     62         if (mpreLimit == baseIndex) {
     63             continue;
     64         }
     65 
     66         LEErrorCode success = LE_NO_ERROR;
     67         le_int32   mpreCount = mpreLimit - mpreIndex;
     68         le_int32   moveCount = baseIndex - mpreLimit;
     69         le_int32   mpreDest  = baseIndex - mpreCount;
     70         LEGlyphID *mpreSave  = LE_NEW_ARRAY(LEGlyphID, mpreCount);
     71         le_int32  *indexSave = LE_NEW_ARRAY(le_int32, mpreCount);
     72 
     73         if (mpreSave == NULL || indexSave == NULL) {
     74             LE_DELETE_ARRAY(mpreSave);
     75             LE_DELETE_ARRAY(indexSave);
     76             success = LE_MEMORY_ALLOCATION_ERROR;
     77             return;
     78         }
     79 
     80         le_int32   i;
     81 
     82         for (i = 0; i < mpreCount; i += 1) {
     83             mpreSave[i]  = glyphStorage[mpreIndex + i];
     84             indexSave[i] = glyphStorage.getCharIndex(mpreIndex + i, success); //charIndices[mpreIndex + i];
     85         }
     86 
     87         for (i = 0; i < moveCount; i += 1) {
     88             LEGlyphID glyph = glyphStorage[mpreLimit + i];
     89             le_int32 charIndex = glyphStorage.getCharIndex(mpreLimit + i, success);
     90 
     91             glyphStorage[mpreIndex + i] = glyph;
     92             glyphStorage.setCharIndex(mpreIndex + i, charIndex, success);
     93         }
     94 
     95         for (i = 0; i < mpreCount; i += 1) {
     96             glyphStorage[mpreDest + i] = mpreSave[i];
     97             glyphStorage.setCharIndex(mpreDest, indexSave[i], success);
     98         }
     99 
    100         LE_DELETE_ARRAY(indexSave);
    101         LE_DELETE_ARRAY(mpreSave);
    102     }
    103 }
    104 
    105 U_NAMESPACE_END
    106