/*
*
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
-ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
- const GlyphSubstitutionTableHeader *gsubTable)
- : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, gsubTable)
+ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
+ le_int32 languageCode, le_int32 typoFlags,
+ const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
+ LEErrorCode &success)
+ : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
- /**/ fFeatureOrder = ArabicShaping::getFeatureOrder();
+ fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
+ fFeatureOrder = TRUE;
}
-ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode)
- : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode)
+ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
+ le_int32 languageCode,
+ le_int32 typoFlags, LEErrorCode &success)
+ : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
- // fFeatureOrder = ArabicShaping::getFeatureOrder();
+ fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
+
+ // NOTE: We don't need to set fFeatureOrder to TRUE here
+ // because this constructor is only called by the constructor
+ // for UnicodeArabicOpenTypeLayoutEngine, which uses a pre-built
+ // GSUB table that has the features in the correct order.
+
+ //fFeatureOrder = TRUE;
}
ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
// Input: characters
// Output: characters, char indices, tags
// Returns: output character count
-le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
- LEUnicode *&/*outChars*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
+le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
+ le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
+ LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return 0;
return 0;
}
- glyphStorage.adoptGlyphCount(count);
+ outChars = LE_NEW_ARRAY(LEUnicode, count);
+
+ if (outChars == NULL) {
+ success = LE_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+
+ glyphStorage.allocateGlyphArray(count, rightToLeft, success);
glyphStorage.allocateAuxData(success);
if (LE_FAILURE(success)) {
- success = LE_MEMORY_ALLOCATION_ERROR;
+ LE_DELETE_ARRAY(outChars);
return 0;
}
+ CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);
+
+ // Note: This processes the *original* character array so we can get context
+ // for the first and last characters. This is OK because only the marks
+ // will have been reordered, and they don't contribute to shaping.
ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);
return count;
return;
}
- if (fGPOSTable != NULL) {
+ if (!fGPOSTable.isEmpty()) {
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
- } else if (fGDEFTable != NULL) {
- GDEFMarkFilter filter(fGDEFTable);
-
+ } else if (!fGDEFTable.isEmpty()) {
+ GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success);
} else {
- GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
- GDEFMarkFilter filter(gdefTable);
+ LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
+ GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
}
}
-UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode)
- : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode)
+UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
+ : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
{
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
-
- fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
+ /* OpenTypeLayoutEngine will allocate a substitution filter */
}
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
{
- delete fSubstitutionFilter;
+ /* OpenTypeLayoutEngine will cleanup the substitution filter */
}
// "glyphs", "indices" -> glyphs, indices
return;
}
- GDEFMarkFilter filter(fGDEFTable);
+ GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
}