IndicLayoutEngine.cpp revision c73f511526464f8e56c242df80552e9b0d94ae3d
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 23U_NAMESPACE_BEGIN 24 25UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) 26 27IndicOpenTypeLayoutEngine::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 41IndicOpenTypeLayoutEngine::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 49IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine() 50{ 51 // nothing to do 52} 53 54// Input: characters, tags 55// Output: glyphs, char indices 56le_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 87le_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 135U_NAMESPACE_END 136