1 2 /* 3 * 4 * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved 5 * 6 */ 7 8 #include "LETypes.h" 9 #include "LayoutEngine.h" 10 #include "OpenTypeLayoutEngine.h" 11 #include "IndicLayoutEngine.h" 12 #include "ScriptAndLanguageTags.h" 13 14 #include "GlyphSubstitutionTables.h" 15 #include "GlyphDefinitionTables.h" 16 #include "GlyphPositioningTables.h" 17 18 #include "GDEFMarkFilter.h" 19 #include "LEGlyphStorage.h" 20 21 #include "IndicReordering.h" 22 23 U_NAMESPACE_BEGIN 24 25 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) 26 27 IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 28 le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) 29 : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL) 30 { 31 if ( version2 ) { 32 fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount); 33 } else { 34 fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); 35 } 36 fFeatureOrder = TRUE; 37 fVersion2 = version2; 38 fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode); 39 } 40 41 IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) 42 : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMPreFixups(NULL) 43 { 44 fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); 45 fFeatureOrder = TRUE; 46 fVersion2 = FALSE; 47 } 48 49 IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine() 50 { 51 // nothing to do 52 } 53 54 // Input: characters, tags 55 // Output: glyphs, char indices 56 le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 57 LEGlyphStorage &glyphStorage, LEErrorCode &success) 58 { 59 if (LE_FAILURE(success)) { 60 return 0; 61 } 62 63 if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 64 success = LE_ILLEGAL_ARGUMENT_ERROR; 65 return 0; 66 } 67 68 le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success); 69 70 if (LE_FAILURE(success)) { 71 return 0; 72 } 73 74 if (fVersion2) { 75 IndicReordering::finalReordering(glyphStorage,retCount); 76 IndicReordering::applyPresentationForms(glyphStorage,retCount); 77 OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success); 78 } else { 79 IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success); 80 } 81 return retCount; 82 } 83 84 // Input: characters 85 // Output: characters, char indices, tags 86 // Returns: output character count 87 le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 88 LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) 89 { 90 if (LE_FAILURE(success)) { 91 return 0; 92 } 93 94 if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 95 success = LE_ILLEGAL_ARGUMENT_ERROR; 96 return 0; 97 } 98 99 le_int32 worstCase = count * IndicReordering::getWorstCaseExpansion(fScriptCode); 100 101 outChars = LE_NEW_ARRAY(LEUnicode, worstCase); 102 103 if (outChars == NULL) { 104 success = LE_MEMORY_ALLOCATION_ERROR; 105 return 0; 106 } 107 108 glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success); 109 glyphStorage.allocateAuxData(success); 110 111 if (LE_FAILURE(success)) { 112 LE_DELETE_ARRAY(outChars); 113 return 0; 114 } 115 116 // NOTE: assumes this allocates featureTags... 117 // (probably better than doing the worst case stuff here...) 118 119 le_int32 outCharCount; 120 if (fVersion2) { 121 outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage); 122 } else { 123 outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success); 124 } 125 126 if (LE_FAILURE(success)) { 127 LE_DELETE_ARRAY(outChars); 128 return 0; 129 } 130 131 glyphStorage.adoptGlyphCount(outCharCount); 132 return outCharCount; 133 } 134 135 U_NAMESPACE_END 136