1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LETypes.h" 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LEScripts.h" 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LEGlyphFilter.h" 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LEGlyphStorage.h" 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LayoutEngine.h" 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "OpenTypeLayoutEngine.h" 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ArabicLayoutEngine.h" 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ScriptAndLanguageTags.h" 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "CharSubstitutionFilter.h" 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GlyphSubstitutionTables.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GlyphDefinitionTables.h" 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GlyphPositioningTables.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GDEFMarkFilter.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ArabicShaping.h" 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "CanonShaping.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fFontInstance->canDisplay((LEUnicode) glyph); 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine) 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 3785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) 3885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success) 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFeatureOrder = TRUE; 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 4585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho le_int32 typoFlags, LEErrorCode &success) 4685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // NOTE: We don't need to set fFeatureOrder to TRUE here 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // because this constructor is only called by the constructor 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // for UnicodeArabicOpenTypeLayoutEngine, which uses a pre-built 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // GSUB table that has the features in the correct order. 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //fFeatureOrder = TRUE; 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine() 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing to do 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Input: characters 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Output: characters, char indices, tags 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Returns: output character count 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outChars = LE_NEW_ARRAY(LEUnicode, count); 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (outChars == NULL) { 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_MEMORY_ALLOCATION_ERROR; 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.allocateGlyphArray(count, rightToLeft, success); 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.allocateAuxData(success); 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(outChars); 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage); 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Note: This processes the *original* character array so we can get context 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // for the first and last characters. This is OK because only the marks 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // will have been reordered, and they don't contribute to shaping. 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage); 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return count; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEGlyphStorage &glyphStorage, LEErrorCode &success) 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0) { 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fGPOSTable != NULL) { 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success); 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (fGDEFTable != NULL) { 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru GDEFMarkFilter filter(fGDEFTable); 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru adjustMarkGlyphs(glyphStorage, &filter, success); 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru GDEFMarkFilter filter(gdefTable); 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) 13085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fSubstitutionFilter = new CharSubstitutionFilter(fontInstance); 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine() 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete fSubstitutionFilter; 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// "glyphs", "indices" -> glyphs, indices 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success) 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // FIXME: we could avoid the memory allocation and copy if we 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // made a clone of mapCharsToGlyphs which took the fake glyphs 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // directly. 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 tempGlyphCount = tempGlyphStorage.getGlyphCount(); 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *tempChars = LE_NEW_ARRAY(LEUnicode, tempGlyphCount); 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (tempChars == NULL) { 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_MEMORY_ALLOCATION_ERROR; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (le_int32 i = 0; i < tempGlyphCount; i += 1) { 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphStorage[i]); 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.adoptCharIndicesArray(tempGlyphStorage); 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success); 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(tempChars); 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tempGlyphCount; 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success) 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0) { 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 i, dir = 1, out = 0; 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (reverse) { 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru out = count - 1; 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dir = -1; 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.allocateGlyphArray(count, reverse, success); 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (i = 0; i < count; i += 1, out += dir) { 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage[out] = (LEGlyphID) chars[offset + i]; 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEGlyphStorage &glyphStorage, LEErrorCode &success) 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0) { 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru GDEFMarkFilter filter(fGDEFTable); 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 218