1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 359d709d503bab6e2b61931737e662dd293b40578ccornelius * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This file is a modification of the ICU file IndicLayoutEngine.cpp 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * by Jens Herden and Javier Sola for Khmer language 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "OpenTypeLayoutEngine.h" 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "KhmerLayoutEngine.h" 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LEGlyphStorage.h" 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "KhmerReordering.h" 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine) 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruKhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 2159d709d503bab6e2b61931737e662dd293b40578ccornelius le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) 2285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success) 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount); 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFeatureOrder = TRUE; 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruKhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 2985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho le_int32 typoFlags, LEErrorCode &success) 3085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount); 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFeatureOrder = TRUE; 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruKhmerOpenTypeLayoutEngine::~KhmerOpenTypeLayoutEngine() 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing to do 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Input: characters 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Output: characters, char indices, tags 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Returns: output character count 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 KhmerOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 worstCase = count * 3; // worst case is 3 for Khmer TODO check if 2 is enough 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outChars = LE_NEW_ARRAY(LEUnicode, worstCase); 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (outChars == NULL) { 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_MEMORY_ALLOCATION_ERROR; 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success); 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.allocateAuxData(success); 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(outChars); 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // NOTE: assumes this allocates featureTags... 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (probably better than doing the worst case stuff here...) 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 outCharCount = KhmerReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage); 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.adoptGlyphCount(outCharCount); 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return outCharCount; 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 82