diff -ur icu-4.6.orig/source/layout/AlternateSubstSubtables.cpp icu-4.6/source/layout/AlternateSubstSubtables.cpp --- icu-4.6.orig/source/layout/AlternateSubstSubtables.cpp 2004-05-08 01:29:16.000000000 +0200 +++ icu-4.6/source/layout/AlternateSubstSubtables.cpp 2010-12-02 14:04:56.000000000 +0100 @@ -27,13 +27,19 @@ Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]); const AlternateSetTable *alternateSetTable = (const AlternateSetTable *) ((char *) this + alternateSetTableOffset); - TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]); + le_int32 altIndex = glyphIterator->getFeatureParam(); - if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) { - glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0])); + if (altIndex < SWAPW(alternateSetTable->glyphCount)) { + TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[altIndex]); + + if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) { + glyphIterator->setCurrGlyphID(alternate); + } + + return 1; } - return 1; + // feature param was out of range for the glyph } // XXXX If we get here, the table's mal-formed... diff -ur icu-4.6.orig/source/layout/GlyphIterator.cpp icu-4.6/source/layout/GlyphIterator.cpp --- icu-4.6.orig/source/layout/GlyphIterator.cpp 2008-10-28 15:50:15.000000000 +0100 +++ icu-4.6/source/layout/GlyphIterator.cpp 2010-12-02 14:12:48.000000000 +0100 @@ -19,7 +19,7 @@ FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) : direction(1), position(-1), nextLimit(-1), prevLimit(-1), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), - srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0), + srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), featureParam(0), glyphGroup(0), glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL) { @@ -53,12 +53,13 @@ destIndex = that.destIndex; lookupFlags = that.lookupFlags; featureMask = that.featureMask; + featureParam = that.featureParam; glyphGroup = that.glyphGroup; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; } -GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask) +GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask, le_int32 newFeatureParam) : glyphStorage(that.glyphStorage) { direction = that.direction; @@ -71,6 +72,7 @@ destIndex = that.destIndex; lookupFlags = that.lookupFlags; featureMask = newFeatureMask; + featureParam = newFeatureParam; glyphGroup = 0; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; @@ -89,6 +91,7 @@ destIndex = that.destIndex; lookupFlags = newLookupFlags; featureMask = that.featureMask; + featureParam = that.featureParam; glyphGroup = that.glyphGroup; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; @@ -103,6 +106,7 @@ { position = prevLimit; featureMask = newFeatureMask; + featureParam = 0; glyphGroup = 0; lookupFlags = newLookupFlags; } @@ -130,6 +134,11 @@ return position; } +le_int32 GlyphIterator::getFeatureParam() const +{ + return featureParam; +} + le_bool GlyphIterator::isRightToLeft() const { return direction < 0; @@ -400,8 +409,10 @@ } } -le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const +le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) { + featureParam = 0; + if (featureMask == 0) { return TRUE; } @@ -409,7 +420,20 @@ LEErrorCode success = LE_NO_ERROR; FeatureMask fm = glyphStorage.getAuxData(position, success); - return ((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup); + if (((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup)) { + const le_int32 *paramList = (const le_int32 *) glyphStorage.getAuxParam(position, success); + if (paramList != NULL) { + fm = featureMask; + while ((fm & 0x80000000UL) == 0) { + ++paramList; + fm <<= 1; + } + featureParam = *paramList; + } + return TRUE; + } + + return FALSE; } le_bool GlyphIterator::findFeatureTag() diff -ur icu-4.6.orig/source/layout/GlyphIterator.h icu-4.6/source/layout/GlyphIterator.h --- icu-4.6.orig/source/layout/GlyphIterator.h 2008-10-28 15:50:15.000000000 +0100 +++ icu-4.6/source/layout/GlyphIterator.h 2010-12-02 14:16:51.000000000 +0100 @@ -28,7 +28,7 @@ GlyphIterator(GlyphIterator &that); - GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask); + GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask, le_int32 featureParam = 0); GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags); @@ -51,6 +51,8 @@ le_int32 getMarkComponent(le_int32 markPosition) const; le_bool findMark2Glyph(); + le_int32 getFeatureParam() const; + void getCursiveEntryPoint(LEPoint &entryPoint) const; void getCursiveExitPoint(LEPoint &exitPoint) const; @@ -74,7 +76,7 @@ private: le_bool filterGlyph(le_uint32 index) const; - le_bool hasFeatureTag(le_bool matchGroup) const; + le_bool hasFeatureTag(le_bool matchGroup); /* not const because it updates the featureParam field */ le_bool nextInternal(le_uint32 delta = 1); le_bool prevInternal(le_uint32 delta = 1); @@ -90,6 +92,7 @@ le_int32 destIndex; le_uint16 lookupFlags; FeatureMask featureMask; + le_int32 featureParam; le_int32 glyphGroup; const GlyphClassDefinitionTable *glyphClassDefinitionTable; diff -ur icu-4.6.orig/source/layout/LEGlyphStorage.cpp icu-4.6/source/layout/LEGlyphStorage.cpp --- icu-4.6.orig/source/layout/LEGlyphStorage.cpp 2009-06-12 00:08:54.000000000 +0200 +++ icu-4.6/source/layout/LEGlyphStorage.cpp 2010-12-02 14:32:28.000000000 +0100 @@ -20,7 +20,7 @@ LEGlyphStorage::LEGlyphStorage() : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL), - fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0) + fAuxData(NULL), fAuxParam(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0) { // nothing else to do! } @@ -44,6 +44,11 @@ fAuxData = NULL; } + if (fAuxParam != NULL) { + LE_DELETE_ARRAY(fAuxParam); + fAuxParam = NULL; + } + if (fInsertionList != NULL) { delete fInsertionList; fInsertionList = NULL; @@ -151,14 +156,15 @@ return -1; } - if (fAuxData != NULL) { + if (fAuxData != NULL || fAuxParam != NULL) { success = LE_INTERNAL_ERROR; return -1; } fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount); + fAuxParam = LE_NEW_ARRAY(void *, fGlyphCount); - if (fAuxData == NULL) { + if (fAuxData == NULL || fAuxParam == NULL) { success = LE_MEMORY_ALLOCATION_ERROR; return -1; } @@ -365,13 +371,32 @@ return fAuxData[glyphIndex]; } -void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success) +void *LEGlyphStorage::getAuxParam(le_int32 glyphIndex, LEErrorCode &success) const +{ + if (LE_FAILURE(success)) { + return NULL; + } + + if (fAuxParam == NULL) { + success = LE_NO_LAYOUT_ERROR; + return NULL; + } + + if (glyphIndex < 0 || glyphIndex >= fGlyphCount) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + return NULL; + } + + return fAuxParam[glyphIndex]; +} + +void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, void *auxParam, LEErrorCode &success) { if (LE_FAILURE(success)) { return; } - if (fAuxData == NULL) { + if (fAuxData == NULL || fAuxParam == NULL) { success = LE_NO_LAYOUT_ERROR; return; } @@ -382,6 +407,7 @@ } fAuxData[glyphIndex] = auxData; + fAuxParam[glyphIndex] = auxParam; } void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const @@ -496,8 +522,14 @@ LE_DELETE_ARRAY(fAuxData); } + if (fAuxParam != NULL) { + LE_DELETE_ARRAY(fAuxParam); + } + fAuxData = from.fAuxData; from.fAuxData = NULL; + fAuxParam = from.fAuxParam; + from.fAuxParam = NULL; } void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from) @@ -588,6 +620,15 @@ fAuxData = (le_uint32 *)newAuxData; } + if (fAuxParam != NULL) { + void **newAuxParam = (void **) LE_GROW_ARRAY(fAuxParam, newGlyphCount); + if (newAuxParam == NULL) { + // could not grow the aux param array + return fGlyphCount; + } + fAuxParam = (void **)newAuxParam; + } + fSrcIndex = fGlyphCount - 1; fDestIndex = newGlyphCount - 1; @@ -640,6 +681,18 @@ } } + if (fAuxParam != NULL) { + le_int32 src = fSrcIndex, dest = fDestIndex; + + while (src > atPosition) { + fAuxParam[dest--] = fAuxParam[src--]; + } + + for (le_int32 i = count - 1; i >= 0; i -= 1) { + fAuxParam[dest--] = fAuxParam[atPosition]; + } + } + while (fSrcIndex > atPosition) { fGlyphs[fDestIndex] = fGlyphs[fSrcIndex]; fCharIndices[fDestIndex] = fCharIndices[fSrcIndex]; diff -ur icu-4.6.orig/source/layout/LEGlyphStorage.h icu-4.6/source/layout/LEGlyphStorage.h --- icu-4.6.orig/source/layout/LEGlyphStorage.h 2010-02-11 01:53:57.000000000 +0100 +++ icu-4.6/source/layout/LEGlyphStorage.h 2010-12-02 14:40:13.000000000 +0100 @@ -63,12 +63,12 @@ float *fPositions; /** - * The auxillary data array. + * The auxillary data arrays. * * @internal */ le_uint32 *fAuxData; - + void **fAuxParam; /** * The insertion list, used to grow the above arrays. @@ -299,6 +299,7 @@ * @stable ICU 3.6 */ le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const; + void *getAuxParam(le_int32 glyphIndex, LEErrorCode &success) const; /** * This operator allows direct access to the glyph array @@ -427,15 +428,20 @@ void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success); /** - * Set the auxillary data for a particular glyph. + * Set the auxiliary data for a particular glyph. * * @param glyphIndex the index of the glyph - * @param auxData the new auxillary data - * @param success will be set to an error code if the auxillary data cannot be set. + * @param auxData the new auxiliary data + * @param auxParam the new secondary auxiliary data (parameter) + * @param success will be set to an error code if the auxiliary data cannot be set. * - * @stable ICU 3.6 + * @stable ICU 3.6 - mod for XeTeX + */ + void setAuxData(le_int32 glyphIndex, le_uint32 auxData, void *auxParam, LEErrorCode &success); + /** + * The common case when @param auxParam is NULL. */ - void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success); + inline void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success); /** * Delete the glyph array and replace it with the one @@ -540,6 +546,10 @@ return fGlyphs[glyphIndex]; } +inline void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success) +{ + setAuxData(glyphIndex, auxData, NULL, success); +} U_NAMESPACE_END #endif diff -ur icu-4.6.orig/source/layout/OpenTypeLayoutEngine.cpp icu-4.6/source/layout/OpenTypeLayoutEngine.cpp --- icu-4.6.orig/source/layout/OpenTypeLayoutEngine.cpp 2010-01-07 23:32:53.000000000 +0100 +++ icu-4.6/source/layout/OpenTypeLayoutEngine.cpp 2010-12-02 14:42:26.000000000 +0100 @@ -78,7 +78,7 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureMask(minimalFeatures), - fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE), + fFeatureMap(featureMap), fFeatureParamList(NULL), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE), fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) { static const le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG; @@ -216,7 +216,7 @@ glyphStorage.allocateAuxData(success); for (le_int32 i = 0; i < count; i += 1) { - glyphStorage.setAuxData(i, fFeatureMask, success); + glyphStorage.setAuxData(i, fFeatureMask, (void *) fFeatureParamList, success); } return count; diff -ur icu-4.6.orig/source/layout/OpenTypeLayoutEngine.h icu-4.6/source/layout/OpenTypeLayoutEngine.h --- icu-4.6.orig/source/layout/OpenTypeLayoutEngine.h 2009-03-03 00:35:48.000000000 +0100 +++ icu-4.6/source/layout/OpenTypeLayoutEngine.h 2010-12-02 14:45:47.000000000 +0100 @@ -194,6 +194,13 @@ le_bool fFeatureOrder; /** + * The list of what? FIXME.. + * + * @internal + */ + const le_int32 *fFeatureParamList; + + /** * The address of the GSUB table. * * @internal