1/* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 27/* 28 * 29 * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved 30 * 31 */ 32 33#include "LETypes.h" 34#include "LayoutEngine.h" 35#include "ThaiLayoutEngine.h" 36#include "ScriptAndLanguageTags.h" 37#include "LEGlyphStorage.h" 38 39#include "KernTable.h" 40 41#include "ThaiShaping.h" 42 43U_NAMESPACE_BEGIN 44 45UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ThaiLayoutEngine) 46 47ThaiLayoutEngine::ThaiLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) 48 : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) 49{ 50 fErrorChar = 0x25CC; 51 52 // Figure out which presentation forms the font uses 53 if (! fontInstance->canDisplay(0x0E01)) { 54 // No Thai in font; don't use presentation forms. 55 fGlyphSet = 3; 56 } else if (fontInstance->canDisplay(0x0E64)) { 57 // WorldType uses reserved space in Thai block 58 fGlyphSet = 0; 59 } else if (fontInstance->canDisplay(0xF701)) { 60 // Microsoft corporate zone 61 fGlyphSet = 1; 62 63 if (!fontInstance->canDisplay(fErrorChar)) { 64 fErrorChar = 0xF71B; 65 } 66 } else if (fontInstance->canDisplay(0xF885)) { 67 // Apple corporate zone 68 fGlyphSet = 2; 69 } else { 70 // no presentation forms in the font 71 fGlyphSet = 3; 72 } 73} 74 75ThaiLayoutEngine::~ThaiLayoutEngine() 76{ 77 // nothing to do 78} 79 80// Input: characters (0..max provided for context) 81// Output: glyphs, char indices 82// Returns: the glyph count 83// NOTE: this assumes that ThaiShaping::compose will allocate the outChars array... 84le_int32 ThaiLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/, LEGlyphStorage &glyphStorage, LEErrorCode &success) 85{ 86 if (LE_FAILURE(success)) { 87 return 0; 88 } 89 90 if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { 91 success = LE_ILLEGAL_ARGUMENT_ERROR; 92 return 0; 93 } 94 95 LEUnicode *outChars; 96 le_int32 glyphCount; 97 98 // This is enough room for the worst-case expansion 99 // (it says here...) 100 outChars = LE_NEW_ARRAY(LEUnicode, count * 2); 101 102 if (outChars == NULL) { 103 success = LE_MEMORY_ALLOCATION_ERROR; 104 return 0; 105 } 106 107 glyphStorage.allocateGlyphArray(count * 2, FALSE, success); 108 109 if (LE_FAILURE(success)) { 110 LE_DELETE_ARRAY(outChars); 111 success = LE_MEMORY_ALLOCATION_ERROR; 112 return 0; 113 } 114 115 glyphCount = ThaiShaping::compose(chars, offset, count, fGlyphSet, fErrorChar, outChars, glyphStorage); 116 mapCharsToGlyphs(outChars, 0, glyphCount, FALSE, FALSE, glyphStorage, success); 117 118 LE_DELETE_ARRAY(outChars); 119 120 glyphStorage.adoptGlyphCount(glyphCount); 121 return glyphCount; 122} 123 124// This is the same as LayoutEngline::adjustGlyphPositions() except that it doesn't call adjustMarkGlyphs 125void ThaiLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, 126 LEGlyphStorage &glyphStorage, LEErrorCode &success) 127{ 128 if (LE_FAILURE(success)) { 129 return; 130 } 131 132 if (chars == NULL || offset < 0 || count < 0) { 133 success = LE_ILLEGAL_ARGUMENT_ERROR; 134 return; 135 } 136 137 if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ 138 LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); 139 KernTable kt(kernTable, success); 140 kt.process(glyphStorage, success); 141 } 142 143 // default is no adjustments 144 return; 145} 146 147U_NAMESPACE_END 148