+
+ const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
+ LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
+ LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
+ le_int32 i, dir = 1, out = 0, outCharCount = count;
+
+ if (canonGSUBTable->coversScript(scriptTag)) {
+ CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
+
+ glyphStorage.allocateGlyphArray(count, rightToLeft, success);
+ glyphStorage.allocateAuxData(success);
+
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
+ if (rightToLeft) {
+ out = count - 1;
+ dir = -1;
+ }
+
+ for (i = 0; i < count; i += 1, out += dir) {
+ glyphStorage[out] = (LEGlyphID) chars[offset + i];
+ glyphStorage.setAuxData(out, (void *) canonFeatures, success);
+ }
+
+ outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, NULL);
+
+ out = (rightToLeft? count - 1 : 0);
+
+ outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);
+ for (i = 0; i < outCharCount; i += 1, out += dir) {
+ outChars[out] = (LEUnicode) LE_GET_GLYPH(glyphStorage[i]);
+ }
+
+ delete substitutionFilter;