X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..d5d484b0fbe924d3663b177965538d517ee412c1:/icuSources/layout/OpenTypeLayoutEngine.cpp diff --git a/icuSources/layout/OpenTypeLayoutEngine.cpp b/icuSources/layout/OpenTypeLayoutEngine.cpp index 9709e6ac..fbbfc0e6 100644 --- a/icuSources/layout/OpenTypeLayoutEngine.cpp +++ b/icuSources/layout/OpenTypeLayoutEngine.cpp @@ -1,7 +1,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -12,12 +12,14 @@ #include "LayoutEngine.h" #include "OpenTypeLayoutEngine.h" #include "ScriptAndLanguageTags.h" +#include "CharSubstitutionFilter.h" #include "GlyphSubstitutionTables.h" #include "GlyphDefinitionTables.h" #include "GlyphPositioningTables.h" #include "LEGlyphStorage.h" +#include "GlyphPositionAdjustments.h" #include "GDEFMarkFilter.h" @@ -25,27 +27,68 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine) -static const LETag emptyTag = 0x00000000; - -static const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG; -static const LETag ligaFeatureTag = LE_LIGA_FEATURE_TAG; -static const LETag cligFeatureTag = LE_CLIG_FEATURE_TAG; -static const LETag kernFeatureTag = LE_KERN_FEATURE_TAG; -static const LETag markFeatureTag = LE_MARK_FEATURE_TAG; -static const LETag mkmkFeatureTag = LE_MKMK_FEATURE_TAG; - -static const LETag defaultFeatures[] = {ccmpFeatureTag, ligaFeatureTag, cligFeatureTag, kernFeatureTag, markFeatureTag, mkmkFeatureTag, emptyTag}; +#define ccmpFeatureTag LE_CCMP_FEATURE_TAG +#define ligaFeatureTag LE_LIGA_FEATURE_TAG +#define cligFeatureTag LE_CLIG_FEATURE_TAG +#define kernFeatureTag LE_KERN_FEATURE_TAG +#define markFeatureTag LE_MARK_FEATURE_TAG +#define mkmkFeatureTag LE_MKMK_FEATURE_TAG + +// 'dlig' not used at the moment +#define dligFeatureTag 0x646C6967 + +// 'palt' +#define paltFeatureTag 0x70616C74 + +#define ccmpFeatureMask 0x80000000UL +#define ligaFeatureMask 0x40000000UL +#define cligFeatureMask 0x20000000UL +#define kernFeatureMask 0x10000000UL +#define paltFeatureMask 0x08000000UL +#define markFeatureMask 0x04000000UL +#define mkmkFeatureMask 0x02000000UL + +#define minimalFeatures (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask) +#define ligaFeatures (ligaFeatureMask | cligFeatureMask | minimalFeatures) +#define kernFeatures (kernFeatureMask | paltFeatureMask | minimalFeatures) +#define kernAndLigaFeatures (ligaFeatures | kernFeatures) + +static const FeatureMap featureMap[] = +{ + {ccmpFeatureTag, ccmpFeatureMask}, + {ligaFeatureTag, ligaFeatureMask}, + {cligFeatureTag, cligFeatureMask}, + {kernFeatureTag, kernFeatureMask}, + {paltFeatureTag, paltFeatureMask}, + {markFeatureTag, markFeatureMask}, + {mkmkFeatureTag, mkmkFeatureMask} +}; +static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - const GlyphSubstitutionTableHeader *gsubTable) - : LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureList(defaultFeatures), fFeatureOrder(NULL), - fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) + le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) + : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureMask(minimalFeatures), + fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE), + fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL), fFilterZeroWidth(TRUE) { static const le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG; static const le_uint32 gposTableTag = LE_GPOS_TABLE_TAG; const GlyphPositioningTableHeader *gposTable = (const GlyphPositioningTableHeader *) getFontTable(gposTableTag); + // todo: switch to more flags and bitfield rather than list of feature tags? + switch (typoFlags & ~0x80000000L) { + case 0: break; // default + case 1: fFeatureMask = kernFeatures; break; + case 2: fFeatureMask = ligaFeatures; break; + case 3: fFeatureMask = kernAndLigaFeatures; break; + default: break; + } + + if (typoFlags & 0x80000000L) { + fSubstitutionFilter = new CharSubstitutionFilter(fontInstance); + } + setScriptAndLanguageTags(); fGDEFTable = (const GlyphDefinitionTableHeader *) getFontTable(gdefTableTag); @@ -64,15 +107,20 @@ void OpenTypeLayoutEngine::reset() LayoutEngine::reset(); } -OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode) - : LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureOrder(NULL), - fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) +OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, + le_int32 typoFlags) + : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureOrder(FALSE), + fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL), fFilterZeroWidth(TRUE) { setScriptAndLanguageTags(); } OpenTypeLayoutEngine::~OpenTypeLayoutEngine() { + if (fTypoFlags & 0x80000000L) { + delete fSubstitutionFilter; + } + reset(); } @@ -122,7 +170,7 @@ le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_i glyphStorage.allocateAuxData(success); for (le_int32 i = 0; i < outCharCount; i += 1) { - glyphStorage.setAuxData(i, (void *) fFeatureList, success); + glyphStorage.setAuxData(i, fFeatureMask, success); } return outCharCount; @@ -142,14 +190,15 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 return 0; } - mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success); + mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, fFilterZeroWidth, glyphStorage, success); if (LE_FAILURE(success)) { return 0; } if (fGSUBTable != NULL) { - count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureOrder); + count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, + fFeatureMap, fFeatureMapCount, fFeatureOrder); } return count; @@ -186,6 +235,10 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, fakeGlyphStorage, success); + if (LE_FAILURE(success)) { + return 0; + } + if (outChars != NULL) { fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success); LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work... @@ -195,6 +248,10 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o //adjustGlyphs(chars, offset, count, rightToLeft, fakeGlyphs, fakeGlyphCount); } + if (LE_FAILURE(success)) { + return 0; + } + outGlyphCount = glyphPostProcessing(fakeGlyphStorage, glyphStorage, success); return outGlyphCount; @@ -216,7 +273,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 le_int32 glyphCount = glyphStorage.getGlyphCount(); if (glyphCount > 0 && fGPOSTable != NULL) { - GlyphPositionAdjustment *adjustments = new GlyphPositionAdjustment[glyphCount]; + GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount); le_int32 i; if (adjustments == NULL) { @@ -228,23 +285,24 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 // Don't need to do this if we allocate // the adjustments array w/ new... for (i = 0; i < glyphCount; i += 1) { - adjustments[i].setXPlacement(0); - adjustments[i].setYPlacement(0); + adjustments->setXPlacement(i, 0); + adjustments->setYPlacement(i, 0); - adjustments[i].setXAdvance(0); - adjustments[i].setYAdvance(0); + adjustments->setXAdvance(i, 0); + adjustments->setYAdvance(i, 0); - adjustments[i].setBaseOffset(-1); + adjustments->setBaseOffset(i, -1); } #endif - fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance, fFeatureOrder); + fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance, + fFeatureMap, fFeatureMapCount, fFeatureOrder); float xAdjust = 0, yAdjust = 0; for (i = 0; i < glyphCount; i += 1) { - float xAdvance = adjustments[i].getXAdvance(); - float yAdvance = adjustments[i].getYAdvance(); + float xAdvance = adjustments->getXAdvance(i); + float yAdvance = adjustments->getYAdvance(i); float xPlacement = 0; float yPlacement = 0; @@ -256,9 +314,9 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 yAdjust += yKerning; #endif - for (le_int32 base = i; base >= 0; base = adjustments[base].getBaseOffset()) { - xPlacement += adjustments[base].getXPlacement(); - yPlacement += adjustments[base].getYPlacement(); + for (le_int32 base = i; base >= 0; base = adjustments->getBaseOffset(base)) { + xPlacement += adjustments->getXPlacement(base); + yPlacement += adjustments->getYPlacement(base); } xPlacement = fFontInstance->xUnitsToPoints(xPlacement); @@ -271,7 +329,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 glyphStorage.adjustPosition(glyphCount, xAdjust, -yAdjust, success); - delete[] adjustments; + delete adjustments; } #if 0