18393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* 28393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * 3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * (C) Copyright IBM Corp and Others. 1998-2014 - All Rights Reserved 48393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * 58393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius */ 68393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 78393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "LETypes.h" 88393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "MorphTables.h" 98393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "StateTables.h" 108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "MorphStateTables.h" 118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "SubtableProcessor2.h" 128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "StateTableProcessor2.h" 138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "LigatureSubstProc2.h" 148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "LEGlyphStorage.h" 158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "LESwaps.h" 168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_NAMESPACE_BEGIN 188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m)))) 208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m)) 218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v)) 228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2) 248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 2559d709d503bab6e2b61931737e662dd293b40578ccorneliusLigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) 26fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius : StateTableProcessor2(morphSubtableHeader, success), 27fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ligActionOffset(0), 28fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius componentOffset(0), ligatureOffset(0), entryTable(), ligatureSubstitutionHeader(morphSubtableHeader, success) 298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{ 3059d709d503bab6e2b61931737e662dd293b40578ccornelius if (LE_FAILURE(success)) return; 3159d709d503bab6e2b61931737e662dd293b40578ccornelius 328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset); 338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset); 348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset); 358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 3659d709d503bab6e2b61931737e662dd293b40578ccornelius entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY); 378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusLigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2() 408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{ 418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusvoid LigatureSubstitutionProcessor2::beginStateTable() 448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{ 458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius m = -1; 468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 4859d709d503bab6e2b61931737e662dd293b40578ccorneliusle_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success) 498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{ 5059d709d503bab6e2b61931737e662dd293b40578ccornelius const LigatureSubstitutionStateEntry2 *entry = entryTable.getAlias(index, success); 5159d709d503bab6e2b61931737e662dd293b40578ccornelius if(LE_FAILURE(success)) return 0; 5259d709d503bab6e2b61931737e662dd293b40578ccornelius 538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex); 548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius le_uint16 flags = SWAPW(entry->entryFlags); 558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex); 568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (flags & lsfSetComponent) { 588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (++m >= nComponents) { 598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius m = 0; 608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius componentStack[m] = currGlyph; 6259d709d503bab6e2b61931737e662dd293b40578ccornelius } else if ( m == -1) { 6359d709d503bab6e2b61931737e662dd293b40578ccornelius // bad font- skip this glyph. 6459d709d503bab6e2b61931737e662dd293b40578ccornelius //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)") 6559d709d503bab6e2b61931737e662dd293b40578ccornelius currGlyph+= dir; 6659d709d503bab6e2b61931737e662dd293b40578ccornelius return nextStateIndex; 678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ByteOffset actionOffset = flags & lsfPerformAction; 708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (actionOffset != 0) { 7259d709d503bab6e2b61931737e662dd293b40578ccornelius LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset 7359d709d503bab6e2b61931737e662dd293b40578ccornelius ap.addObject(ligActionIndex - 1, success); // index offset ( one before the actual start, because we will pre-increment) 7459d709d503bab6e2b61931737e662dd293b40578ccornelius LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY); 758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LigatureActionEntry action; 768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius le_int32 offset, i = 0; 778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius le_int32 stack[nComponents]; 788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius le_int16 mm = -1; 798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 8059d709d503bab6e2b61931737e662dd293b40578ccornelius LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY); 8159d709d503bab6e2b61931737e662dd293b40578ccornelius if(LE_FAILURE(success)) { 8259d709d503bab6e2b61931737e662dd293b40578ccornelius currGlyph+= dir; 8359d709d503bab6e2b61931737e662dd293b40578ccornelius return nextStateIndex; // get out! bad font 8459d709d503bab6e2b61931737e662dd293b40578ccornelius } 858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius do { 87fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius le_int32 componentGlyph = componentStack[m--]; // pop off 888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 8959d709d503bab6e2b61931737e662dd293b40578ccornelius ap.addObject(success); 9059d709d503bab6e2b61931737e662dd293b40578ccornelius action = SWAPL(*ap.getAlias()); 918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (m < 0) { 938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius m = nComponents - 1; 948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = action & lafComponentOffsetMask; 978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (offset != 0) { 98fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(componentGlyph > glyphStorage.getGlyphCount() || componentGlyph < 0) { 9959d709d503bab6e2b61931737e662dd293b40578ccornelius LE_DEBUG_BAD_FONT("preposterous componentGlyph"); 10059d709d503bab6e2b61931737e662dd293b40578ccornelius currGlyph+= dir; 10159d709d503bab6e2b61931737e662dd293b40578ccornelius return nextStateIndex; // get out! bad font 10259d709d503bab6e2b61931737e662dd293b40578ccornelius } 10359d709d503bab6e2b61931737e662dd293b40578ccornelius i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success)); 1048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (action & (lafLast | lafStore)) { 10659d709d503bab6e2b61931737e662dd293b40578ccornelius TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success)); 1078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph); 10859d709d503bab6e2b61931737e662dd293b40578ccornelius if(mm==nComponents) { 10959d709d503bab6e2b61931737e662dd293b40578ccornelius LE_DEBUG_BAD_FONT("exceeded nComponents"); 11059d709d503bab6e2b61931737e662dd293b40578ccornelius mm--; // don't overrun the stack. 11159d709d503bab6e2b61931737e662dd293b40578ccornelius } 1128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius stack[++mm] = componentGlyph; 1138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius i = 0; 1148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 1158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF); 1168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 11859d709d503bab6e2b61931737e662dd293b40578ccornelius#if LE_ASSERT_BAD_FONT 11959d709d503bab6e2b61931737e662dd293b40578ccornelius if(m<0) { 12059d709d503bab6e2b61931737e662dd293b40578ccornelius LE_DEBUG_BAD_FONT("m<0") 12159d709d503bab6e2b61931737e662dd293b40578ccornelius } 12259d709d503bab6e2b61931737e662dd293b40578ccornelius#endif 12359d709d503bab6e2b61931737e662dd293b40578ccornelius } while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items 1248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius while (mm >= 0) { 1268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (++m >= nComponents) { 1278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius m = 0; 1288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius componentStack[m] = stack[mm--]; 1318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (!(flags & lsfDontAdvance)) { 1358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius currGlyph += dir; 1368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return nextStateIndex; 1398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 1408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusvoid LigatureSubstitutionProcessor2::endStateTable() 1428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{ 1438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 1448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_NAMESPACE_END 146