1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * (C) Copyright IBM Corp. 1998-2009 - 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 "LELanguages.h" 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LayoutEngine.h" 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ArabicLayoutEngine.h" 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "CanonShaping.h" 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "HanLayoutEngine.h" 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "HangulLayoutEngine.h" 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "IndicLayoutEngine.h" 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "KhmerLayoutEngine.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ThaiLayoutEngine.h" 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "TibetanLayoutEngine.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GXLayoutEngine.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ScriptAndLanguageTags.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "CharSubstitutionFilter.h" 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LEGlyphStorage.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "OpenTypeUtilities.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GlyphSubstitutionTables.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "GlyphDefinitionTables.h" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "MorphTables.h" 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "DefaultCharMapper.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "KernTable.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Leave this copyright notice here! It needs to go somewhere in this library. */ 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char copyright[] = U_COPYRIGHT_STRING; 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst LEUnicode32 DefaultCharMapper::controlChars[] = { 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x0009, 0x000A, 0x000D, 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*0x200C, 0x200D,*/ 0x200E, 0x200F, 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x2028, 0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E, 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x206A, 0x206B, 0x206C, 0x206D, 0x206E, 0x206F 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst le_int32 DefaultCharMapper::controlCharsCount = LE_ARRAY_SIZE(controlChars); 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEUnicode32 DefaultCharMapper::mapChar(LEUnicode32 ch) const 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fFilterControls) { 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 index = OpenTypeUtilities::search((le_uint32)ch, (le_uint32 *)controlChars, controlCharsCount); 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (controlChars[index] == ch) { 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0xFFFF; 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fMirror) { 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 index = OpenTypeUtilities::search((le_uint32) ch, (le_uint32 *)DefaultCharMapper::mirroredChars, DefaultCharMapper::mirroredCharsCount); 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mirroredChars[index] == ch) { 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return DefaultCharMapper::srahCderorrim[index]; 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ch; 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This is here to get it out of LEGlyphFilter.h. 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// No particular reason to put it here, other than 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// this is a good central location... 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEGlyphFilter::~LEGlyphFilter() 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing to do 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCharSubstitutionFilter::CharSubstitutionFilter(const LEFontInstance *fontInstance) 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : fFontInstance(fontInstance) 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing to do 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCharSubstitutionFilter::~CharSubstitutionFilter() 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing to do 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CanonMarkFilter : public UMemory, public LEGlyphFilter 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const GlyphClassDefinitionTable *classDefTable; 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable); 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual ~CanonMarkFilter(); 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual le_bool accept(LEGlyphID glyph) const; 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable) 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru classDefTable = gdefTable->getMarkAttachClassDefinitionTable(); 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCanonMarkFilter::~CanonMarkFilter() 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // nothing to do? 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_bool CanonMarkFilter::accept(LEGlyphID glyph) const 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 glyphClass = classDefTable->getGlyphClass(glyph); 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return glyphClass != 0; 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine) 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ccmpFeatureTag LE_CCMP_FEATURE_TAG 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ccmpFeatureMask 0x80000000UL 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define canonFeatures (ccmpFeatureMask) 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const FeatureMap canonFeatureMap[] = 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru {ccmpFeatureTag, ccmpFeatureMask} 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap); 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 13785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoLayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, 13885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho le_int32 scriptCode, 13985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho le_int32 languageCode, 14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho le_int32 typoFlags, 14185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho LEErrorCode &success) 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode), 14385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fTypoFlags(typoFlags), fFilterZeroWidth(TRUE) 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 14585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (LE_FAILURE(success)) { 14685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 14785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 14885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage = new LEGlyphStorage(); 15085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (fGlyphStorage == NULL) { 15185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho success = LE_MEMORY_ALLOCATION_ERROR; 15285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 LayoutEngine::getGlyphCount() const 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fGlyphStorage->getGlyphCount(); 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->getCharIndices(charIndices, indexBase, success); 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->getCharIndices(charIndices, success); 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->getGlyphs(glyphs, extraBits, success); 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->getGlyphs(glyphs, success); 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->getGlyphPositions(positions, success); 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->getGlyphPosition(glyphIndex, x, y, success); 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 19385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode); 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode); 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 i, dir = 1, out = 0, outCharCount = count; 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (canonGSUBTable->coversScript(scriptTag)) { 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance); 21185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (substitutionFilter == NULL) { 21285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho success = LE_MEMORY_ALLOCATION_ERROR; 21385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return 0; 21485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 21585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const LEUnicode *inChars = &chars[offset]; 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *reordered = NULL; 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEGlyphStorage fakeGlyphStorage; 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success); 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 22385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho delete substitutionFilter; 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // This is the cheapest way to get mark reordering only for Hebrew. 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // We could just do the mark reordering for all scripts, but most 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // of them probably don't need it... 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fScriptCode == hebrScriptCode) { 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru reordered = LE_NEW_ARRAY(LEUnicode, count); 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (reordered == NULL) { 23485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho delete substitutionFilter; 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_MEMORY_ALLOCATION_ERROR; 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage); 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inChars = reordered; 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fakeGlyphStorage.allocateAuxData(success); 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 24685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho delete substitutionFilter; 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rightToLeft) { 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru out = count - 1; 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dir = -1; 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (i = 0; i < count; i += 1, out += dir) { 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fakeGlyphStorage[out] = (LEGlyphID) inChars[i]; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fakeGlyphStorage.setAuxData(out, canonFeatures, success); 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (reordered != NULL) { 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(reordered); 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 26485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success); 26585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 26685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (LE_FAILURE(success)) { 26785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho delete substitutionFilter; 26885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return 0; 26985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru out = (rightToLeft? outCharCount - 1 : 0); 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 27485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * The char indices array in fakeGlyphStorage has the correct mapping 27585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * back to the original input characters. Save it in glyphStorage. The 27685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * subsequent call to glyphStoratge.allocateGlyphArray will keep this 27785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * array rather than allocating and initializing a new one. 27885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 27985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho glyphStorage.adoptCharIndicesArray(fakeGlyphStorage); 28085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outChars = LE_NEW_ARRAY(LEUnicode, outCharCount); 28285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 28385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (outChars == NULL) { 28485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho delete substitutionFilter; 28585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho success = LE_MEMORY_ALLOCATION_ERROR; 28685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return 0; 28785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 28885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (i = 0; i < outCharCount; i += 1, out += dir) { 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outChars[out] = (LEUnicode) LE_GET_GLYPH(fakeGlyphStorage[i]); 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete substitutionFilter; 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return outCharCount; 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEGlyphStorage &glyphStorage, LEErrorCode &success) 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode *outChars = NULL; 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success); 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (outChars != NULL) { 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft, glyphStorage, success); 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work... 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success); 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return glyphStorage.getGlyphCount(); 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Input: glyphs 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Output: positions 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y, LEErrorCode &success) 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.allocatePositions(success); 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 i, glyphCount = glyphStorage.getGlyphCount(); 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (i = 0; i < glyphCount; i += 1) { 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEPoint advance; 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.setPosition(i, x, y, success); 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFontInstance->getGlyphAdvance(glyphStorage[i], advance); 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru x += advance.fX; 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru y += advance.fY; 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.setPosition(glyphCount, x, y, success); 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEGlyphStorage &glyphStorage, LEErrorCode &success) 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0) { 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CanonMarkFilter filter(gdefTable); 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fTypoFlags & 0x1) { /* kerning enabled */ 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru KernTable kt(fFontInstance, getFontTable(kernTableTag)); 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru kt.process(glyphStorage); 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // default is no adjustments 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success) 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float xAdjust = 0; 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 p, glyphCount = glyphStorage.getGlyphCount(); 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFilter == NULL) { 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float ignore, prev; 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.getGlyphPosition(0, prev, ignore, success); 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (p = 0; p < glyphCount; p += 1) { 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float next, xAdvance; 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.getGlyphPosition(p + 1, next, ignore, success); 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru xAdvance = next - prev; 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.adjustPosition(p, xAdjust, 0, success); 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFilter->accept(glyphStorage[p])) { 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru xAdjust -= xAdvance; 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prev = next; 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success); 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success) 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float xAdjust = 0; 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 c = 0, direction = 1, p; 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 glyphCount = glyphStorage.getGlyphCount(); 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFilter == NULL) { 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (reverse) { 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c = glyphCount - 1; 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru direction = -1; 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float ignore, prev; 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.getGlyphPosition(0, prev, ignore, success); 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (p = 0; p < charCount; p += 1, c += direction) { 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float next, xAdvance; 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.getGlyphPosition(p + 1, next, ignore, success); 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru xAdvance = next - prev; 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.adjustPosition(p, xAdjust, 0, success); 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (markFilter->accept(chars[c])) { 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru xAdjust -= xAdvance; 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prev = next; 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success); 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst void *LayoutEngine::getFontTable(LETag tableTag) const 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fFontInstance->getFontTable(tableTag); 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEGlyphStorage &glyphStorage, LEErrorCode &success) 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphStorage.allocateGlyphArray(count, reverse, success); 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DefaultCharMapper charMapper(TRUE, mirror); 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, fFilterZeroWidth, glyphStorage); 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Input: characters, font? 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Output: glyphs, positions, char indices 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Returns: number of glyphs 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru float x, float y, LEErrorCode &success) 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 glyphCount; 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fGlyphStorage->getGlyphCount() > 0) { 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->reset(); 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success); 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru positionGlyphs(*fGlyphStorage, x, y, success); 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success); 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return glyphCount; 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid LayoutEngine::reset() 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fGlyphStorage->reset(); 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success) 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 3 -> kerning and ligatures 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, 3, success); 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG; 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG; 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (LE_FAILURE(success)) { 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag); 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LayoutEngine *result = NULL; 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LETag scriptTag = 0x00000000; 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LETag languageTag = 0x00000000; 53085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode); 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // Right now, only invoke V2 processing for Devanagari. TODO: Allow more V2 scripts as they are 53385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // properly tested. 53485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 53585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) { 53685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success); 53785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 53885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) { 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (scriptCode) { 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case bengScriptCode: 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case devaScriptCode: 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case gujrScriptCode: 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case kndaScriptCode: 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case mlymScriptCode: 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case oryaScriptCode: 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case guruScriptCode: 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case tamlScriptCode: 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case teluScriptCode: 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case sinhScriptCode: 55085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, FALSE, gsubTable, success); 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case arabScriptCode: 55485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case hangScriptCode: 55885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case haniScriptCode: 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru languageTag = OpenTypeLayoutEngine::getLangSysTag(languageCode); 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (languageCode) { 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case korLanguageCode: 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case janLanguageCode: 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case zhtLanguageCode: 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case zhsLanguageCode: 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) { 57085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // note: falling through to default case. 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 57685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case tibtScriptCode: 58385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case khmrScriptCode: 58785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 59185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag); 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (morphTable != NULL) { 59885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable, success); 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (scriptCode) { 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case bengScriptCode: 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case devaScriptCode: 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case gujrScriptCode: 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case kndaScriptCode: 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case mlymScriptCode: 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case oryaScriptCode: 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case guruScriptCode: 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case tamlScriptCode: 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case teluScriptCode: 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case sinhScriptCode: 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 61285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case arabScriptCode: 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //case hebrScriptCode: 61885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //case hebrScriptCode: 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case thaiScriptCode: 62585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case hangScriptCode: 62985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 63385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 63985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (result && LE_FAILURE(success)) { 64085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho delete result; 64185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result = NULL; 64285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 64385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result == NULL) { 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = LE_MEMORY_ALLOCATION_ERROR; 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLayoutEngine::~LayoutEngine() { 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete fGlyphStorage; 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 656