Home | History | Annotate | Download | only in layout
      1 /*
      2  *
      3  * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
      4  *
      5  */
      6 
      7 #include "LETypes.h"
      8 #include "LEGlyphStorage.h"
      9 #include "CanonShaping.h"
     10 #include "GlyphDefinitionTables.h"
     11 #include "ClassDefinitionTables.h"
     12 
     13 U_NAMESPACE_BEGIN
     14 
     15 void CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses, le_int32 index, le_int32 limit)
     16 {
     17     for (le_int32 j = index + 1; j < limit; j += 1) {
     18         le_int32 i;
     19         le_int32 v = indices[j];
     20         le_int32 c = combiningClasses[v];
     21 
     22         for (i = j - 1; i >= index; i -= 1) {
     23             if (c >= combiningClasses[indices[i]]) {
     24                 break;
     25             }
     26 
     27             indices[i + 1] = indices[i];
     28         }
     29 
     30         indices[i + 1] = v;
     31     }
     32 }
     33 
     34 void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
     35                                 LEUnicode *outChars, LEGlyphStorage &glyphStorage)
     36 {
     37     LEErrorCode success = LE_NO_ERROR;
     38     LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
     39     LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
     40     le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
     41     le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
     42     le_int32 i;
     43 
     44     for (i = 0; i < charCount; i += 1) {
     45       combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success);
     46         indices[i] = i;
     47     }
     48 
     49     for (i = 0; i < charCount; i += 1) {
     50         if (combiningClasses[i] != 0) {
     51             le_int32 mark;
     52 
     53             for (mark = i; mark < charCount; mark += 1) {
     54                 if (combiningClasses[mark] == 0) {
     55                     break;
     56                 }
     57             }
     58 
     59             sortMarks(indices, combiningClasses, i, mark);
     60         }
     61     }
     62 
     63     le_int32 out = 0, dir = 1;
     64 
     65     if (rightToLeft) {
     66         out = charCount - 1;
     67         dir = -1;
     68     }
     69 
     70     for (i = 0; i < charCount; i += 1, out += dir) {
     71         le_int32 index = indices[i];
     72 
     73         outChars[i] = inChars[index];
     74         glyphStorage.setCharIndex(out, index, success);
     75     }
     76 
     77     LE_DELETE_ARRAY(indices);
     78     LE_DELETE_ARRAY(combiningClasses);
     79 }
     80 
     81 U_NAMESPACE_END
     82