1 /* 2 * 3 * (C) Copyright IBM Corp. 1998-2005 - 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 const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable; 38 const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable(); 39 le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount); 40 le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount); 41 LEErrorCode status = LE_NO_ERROR; 42 le_int32 i; 43 44 for (i = 0; i < charCount; i += 1) { 45 combiningClasses[i] = classTable->getGlyphClass((LEGlyphID) inChars[i]); 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, status); 75 } 76 77 LE_DELETE_ARRAY(indices); 78 LE_DELETE_ARRAY(combiningClasses); 79 } 80 81 U_NAMESPACE_END 82