1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "LETypes.h" 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "LayoutEngine.h" 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ThaiLayoutEngine.h" 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ScriptAndLanguageTags.h" 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "LEGlyphStorage.h" 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "KernTable.h" 1585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ThaiShaping.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ThaiLayoutEngine) 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoThaiLayoutEngine::ThaiLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) 2385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fErrorChar = 0x25CC; 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Figure out which presentation forms the font uses 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (! fontInstance->canDisplay(0x0E01)) { 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // No Thai in font; don't use presentation forms. 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphSet = 3; 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (fontInstance->canDisplay(0x0E64)) { 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // WorldType uses reserved space in Thai block 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphSet = 0; 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (fontInstance->canDisplay(0xF701)) { 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Microsoft corporate zone 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphSet = 1; 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!fontInstance->canDisplay(fErrorChar)) { 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fErrorChar = 0xF71B; 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (fontInstance->canDisplay(0xF885)) { 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Apple corporate zone 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphSet = 2; 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no presentation forms in the font 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fGlyphSet = 3; 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThaiLayoutEngine::~ThaiLayoutEngine() 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // nothing to do 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Input: characters (0..max provided for context) 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Output: glyphs, char indices 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Returns: the glyph count 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// NOTE: this assumes that ThaiShaping::compose will allocate the outChars array... 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querule_int32 ThaiLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/, LEGlyphStorage &glyphStorage, LEErrorCode &success) 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(success)) { 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = LE_ILLEGAL_ARGUMENT_ERROR; 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LEUnicode *outChars; 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru le_int32 glyphCount; 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This is enough room for the worst-case expansion 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (it says here...) 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outChars = LE_NEW_ARRAY(LEUnicode, count * 2); 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (outChars == NULL) { 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = LE_MEMORY_ALLOCATION_ERROR; 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphStorage.allocateGlyphArray(count * 2, FALSE, success); 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (LE_FAILURE(success)) { 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(outChars); 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = LE_MEMORY_ALLOCATION_ERROR; 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphCount = ThaiShaping::compose(chars, offset, count, fGlyphSet, fErrorChar, outChars, glyphStorage); 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mapCharsToGlyphs(outChars, 0, glyphCount, FALSE, FALSE, glyphStorage, success); 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LE_DELETE_ARRAY(outChars); 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru glyphStorage.adoptGlyphCount(glyphCount); 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return glyphCount; 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 9985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// This is the same as LayoutEngline::adjustGlyphPositions() except that it doesn't call adjustMarkGlyphs 10085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid ThaiLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, 10185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho LEGlyphStorage &glyphStorage, LEErrorCode &success) 10285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{ 10385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (LE_FAILURE(success)) { 10485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 10585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 10685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 10785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (chars == NULL || offset < 0 || count < 0) { 10885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho success = LE_ILLEGAL_ARGUMENT_ERROR; 10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (fTypoFlags & 0x1) { /* kerning enabled */ 11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; 11485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 11585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho KernTable kt(fFontInstance, getFontTable(kernTableTag)); 11685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho kt.process(glyphStorage); 11785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 11885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // default is no adjustments 12085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 12285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 124