ICU-10107 LayoutEngine improvements

X-SVN-Rev: 33535
This commit is contained in:
Steven R. Loomis 2013-04-18 21:24:51 +00:00
parent 37aa0f8445
commit f2fbc8c394
142 changed files with 6569 additions and 5213 deletions

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -14,25 +14,26 @@
U_NAMESPACE_BEGIN
le_uint32 AlternateSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSubstitutionSubtable> &base,
GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
{
// NOTE: For now, we'll just pick the first alternative...
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) {
if (coverageIndex >= 0 && LE_SUCCESS(success)) {
le_uint16 altSetCount = SWAPW(alternateSetCount);
if (coverageIndex < altSetCount) {
Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
const AlternateSetTable *alternateSetTable =
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset);
const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
}
return 1;
}

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -26,13 +26,17 @@ struct AlternateSetTable
TTGlyphID alternateArray[ANY_NUMBER];
};
LE_VAR_ARRAY(AlternateSetTable, alternateArray)
struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable
{
le_uint16 alternateSetCount;
Offset alternateSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
le_uint32 process(const LEReferenceTo<AlternateSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
};
LE_VAR_ARRAY(AlternateSubstitutionSubtable, alternateSetTableOffsetArray)
U_NAMESPACE_END
#endif

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -33,15 +33,18 @@ le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
le_int32 languageCode, le_int32 typoFlags,
const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
}
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
@ -63,8 +66,9 @@ ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
// Input: characters
// Output: characters, char indices, tags
// Returns: output character count
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return 0;
@ -112,32 +116,30 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
return;
}
if (fGPOSTable != NULL) {
if (!fGPOSTable.isEmpty()) {
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
} else if (fGDEFTable != NULL) {
GDEFMarkFilter filter(fGDEFTable);
} else if (!fGDEFTable.isEmpty()) {
GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success);
} else {
GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
GDEFMarkFilter filter(gdefTable);
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
}
}
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
{
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
/* OpenTypeLayoutEngine will allocate a substitution filter */
}
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
{
delete fSubstitutionFilter;
/* OpenTypeLayoutEngine will cleanup the substitution filter */
}
// "glyphs", "indices" -> glyphs, indices
@ -208,7 +210,7 @@ void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode cha
return;
}
GDEFMarkFilter filter(fGDEFTable);
GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
}

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -50,7 +50,7 @@ public:
* @internal
*/
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -27,20 +27,22 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
/*
shaping array holds types for Arabic chars between 0610 and 0700
other values are either unshaped, or transparent if a mark or format
code, except for format codes 200c (zero-width non-joiner) and 200d
code, except for format codes 200c (zero-width non-joiner) and 200d
(dual-width joiner) which are both unshaped and non_joining or
dual-joining, respectively.
*/
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
{
const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable;
le_int32 joiningType = joiningTypes->getGlyphClass(c);
LEErrorCode success = LE_NO_ERROR;
const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
ArabicShaping::shapingTypeTableLen);
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT) {
return ArabicShaping::shapeTypes[joiningType];
}
if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) {
return ArabicShaping::shapeTypes[joiningType];
}
return ArabicShaping::ST_NOSHAPE_NONE;
return ArabicShaping::ST_NOSHAPE_NONE;
}
#define isolFeatureTag LE_ISOL_FEATURE_TAG
@ -124,8 +126,8 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
le_bool rightToLeft, LEGlyphStorage &glyphStorage)
{
// iterate in logical order, store tags in visible order
//
// the effective right char is the most recently encountered
//
// the effective right char is the most recently encountered
// non-transparent char
//
// four boolean states:
@ -133,7 +135,7 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
// the effective right char causes left shaping
// the current char shapes
// the current char causes right shaping
//
//
// if both cause shaping, then
// shaper.shape(errout, 2) (isolate to initial, or final to medial)
// shaper.shape(out, 1) (isolate to final)
@ -144,7 +146,7 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
for (i = offset - 1; i >= 0; i -= 1) {
rightType = getShapeType(chars[i]);
if (rightType != ST_TRANSPARENT) {
break;
}

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -68,9 +68,11 @@ private:
static ShapeType getShapeType(LEUnicode c);
static const le_uint8 shapingTypeTable[];
static const size_t shapingTypeTableLen;
static const ShapeType shapeTypes[];
static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
};
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -27,14 +27,14 @@ struct AttachmentPositioningSubtable : GlyphPositioningSubtable
Offset markArrayOffset;
Offset baseArrayOffset;
inline le_int32 getBaseCoverage(LEGlyphID baseGlyphId) const;
inline le_int32 getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphId, LEErrorCode &success) const;
le_uint32 process(GlyphIterator *glyphIterator) const;
};
inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(LEGlyphID baseGlyphID) const
inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphID, LEErrorCode &success) const
{
return getGlyphCoverage(baseCoverageTableOffset, baseGlyphID);
return getGlyphCoverage(base, baseCoverageTableOffset, baseGlyphID, success);
}
U_NAMESPACE_END

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -34,15 +34,15 @@ void CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses
void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{
const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable;
const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable();
LEErrorCode success = LE_NO_ERROR;
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
LEErrorCode status = LE_NO_ERROR;
le_int32 i;
for (i = 0; i < charCount; i += 1) {
combiningClasses[i] = classTable->getGlyphClass((LEGlyphID) inChars[i]);
combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success);
indices[i] = i;
}
@ -71,7 +71,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
le_int32 index = indices[i];
outChars[i] = inChars[index];
glyphStorage.setCharIndex(out, index, status);
glyphStorage.setCharIndex(out, index, success);
}
LE_DELETE_ARRAY(indices);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -17,7 +17,9 @@ class U_LAYOUT_API CanonShaping /* not : public UObject because all members are
{
public:
static const le_uint8 glyphSubstitutionTable[];
static const size_t glyphSubstitutionTableLen;
static const le_uint8 glyphDefinitionTable[];
static const size_t glyphDefinitionTableLen;
static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
LEUnicode *outChars, LEGlyphStorage &glyphStorage);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -12,24 +12,51 @@
U_NAMESPACE_BEGIN
le_int32 ClassDefinitionTable::getGlyphClass(LEGlyphID glyphID) const
le_int32 ClassDefinitionTable::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{
LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
if (LE_FAILURE(success)) return 0;
switch(SWAPW(classFormat)) {
case 0:
return 0;
case 1:
{
const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
return f1Table->getGlyphClass(f1Table, glyphID, success);
}
case 2:
{
const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
return f2Table->getGlyphClass(f2Table, glyphID, success);
}
default:
return 0;
}
}
le_bool ClassDefinitionTable::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
{
LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
if (LE_FAILURE(success)) return 0;
switch(SWAPW(classFormat)) {
case 0:
return 0;
case 1:
{
const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
return f1Table->getGlyphClass(glyphID);
const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
return f1Table->hasGlyphClass(f1Table, glyphClass, success);
}
case 2:
{
const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
return f2Table->getGlyphClass(glyphID);
const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
return f2Table->hasGlyphClass(f2Table, glyphClass, success);
}
default:
@ -37,51 +64,32 @@ le_int32 ClassDefinitionTable::getGlyphClass(LEGlyphID glyphID) const
}
}
le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const
le_int32 ClassDefFormat1Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{
switch(SWAPW(classFormat)) {
case 0:
return 0;
if(LE_FAILURE(success)) return 0;
case 1:
{
const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
return f1Table->hasGlyphClass(glyphClass);
}
case 2:
{
const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
return f2Table->hasGlyphClass(glyphClass);
}
default:
return 0;
}
}
le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const
{
le_uint16 count = SWAPW(glyphCount);
LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
TTGlyphID firstGlyph = SWAPW(startGlyph);
TTGlyphID lastGlyph = firstGlyph + SWAPW(glyphCount);
TTGlyphID lastGlyph = firstGlyph + count;
if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
return SWAPW(classValueArray[ttGlyphID - firstGlyph]);
if (LE_SUCCESS(success) && ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
return SWAPW( classValueArrayRef(ttGlyphID - firstGlyph, success) );
}
return 0;
}
le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const
le_bool ClassDefFormat1Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
{
le_uint16 count = SWAPW(glyphCount);
if(LE_FAILURE(success)) return 0;
le_uint16 count = SWAPW(glyphCount);
LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
int i;
for (i = 0; i < count; i += 1) {
if (SWAPW(classValueArray[i]) == glyphClass) {
for (i = 0; LE_SUCCESS(success)&& (i < count); i += 1) {
if (SWAPW(classValueArrayRef(i,success)) == glyphClass) {
return TRUE;
}
}
@ -89,27 +97,31 @@ le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const
return FALSE;
}
le_int32 ClassDefFormat2Table::getGlyphClass(LEGlyphID glyphID) const
le_int32 ClassDefFormat2Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{
if(LE_FAILURE(success)) return 0;
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphID);
le_uint16 rangeCount = SWAPW(classRangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
le_int32 rangeIndex =
OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArray, rangeCount);
OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArrayRef, success);
if (rangeIndex < 0) {
if (rangeIndex < 0 || LE_FAILURE(success)) {
return 0;
}
return SWAPW(classRangeRecordArray[rangeIndex].rangeValue);
return SWAPW(classRangeRecordArrayRef(rangeIndex, success).rangeValue);
}
le_bool ClassDefFormat2Table::hasGlyphClass(le_int32 glyphClass) const
le_bool ClassDefFormat2Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
{
if(LE_FAILURE(success)) return 0;
le_uint16 rangeCount = SWAPW(classRangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
int i;
for (i = 0; i < rangeCount; i += 1) {
if (SWAPW(classRangeRecordArray[i].rangeValue) == glyphClass) {
for (i = 0; i < rangeCount && LE_SUCCESS(success); i += 1) {
if (SWAPW(classRangeRecordArrayRef(i,success).rangeValue) == glyphClass) {
return TRUE;
}
}

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -21,8 +21,20 @@ struct ClassDefinitionTable
{
le_uint16 classFormat;
le_int32 getGlyphClass(LEGlyphID glyphID) const;
le_bool hasGlyphClass(le_int32 glyphClass) const;
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
le_int32 getGlyphClass(LEGlyphID glyphID) const {
LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR;
return getGlyphClass(base,glyphID,ignored);
}
le_bool hasGlyphClass(le_int32 glyphClass) const {
LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR;
return hasGlyphClass(base,glyphClass,ignored);
}
};
struct ClassDefFormat1Table : ClassDefinitionTable
@ -31,9 +43,11 @@ struct ClassDefFormat1Table : ClassDefinitionTable
le_uint16 glyphCount;
le_uint16 classValueArray[ANY_NUMBER];
le_int32 getGlyphClass(LEGlyphID glyphID) const;
le_bool hasGlyphClass(le_int32 glyphClass) const;
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
};
LE_VAR_ARRAY(ClassDefFormat1Table, classValueArray)
struct ClassRangeRecord
{
@ -47,9 +61,10 @@ struct ClassDefFormat2Table : ClassDefinitionTable
le_uint16 classRangeCount;
GlyphRangeRecord classRangeRecordArray[ANY_NUMBER];
le_int32 getGlyphClass(LEGlyphID glyphID) const;
le_bool hasGlyphClass(le_int32 glyphClass) const;
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
};
LE_VAR_ARRAY(ClassDefFormat2Table, classRangeRecordArray)
U_NAMESPACE_END
#endif

View file

@ -18,13 +18,15 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
: StateTableProcessor2(morphSubtableHeader)
ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader, success)
{
contextualGlyphHeader = (const ContextualGlyphInsertionHeader2 *) morphSubtableHeader;
le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
insertionTable = ((le_uint16 *) ((char *)&stateTableHeader->stHeader + insertionTableOffset));
entryTable = (const ContextualGlyphInsertionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
}
ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
@ -36,95 +38,64 @@ void ContextualGlyphInsertionProcessor2::beginStateTable()
markGlyph = 0;
}
le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage,
le_int16 atGlyph,
le_int16 &index,
le_int16 count,
le_bool /* isKashidaLike */,
le_bool isBefore,
LEErrorCode &success) {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success);
if(LE_FAILURE(success) || insertGlyphs==NULL) {
return;
}
// Note: Kashida vs Split Vowel seems to only affect selection and highlighting.
// We note the flag, but do not layout different.
// https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html
le_int16 targetIndex = 0;
if(isBefore) {
// insert at beginning
insertGlyphs[targetIndex++] = glyphStorage[atGlyph];
} else {
// insert at end
insertGlyphs[count] = glyphStorage[atGlyph];
}
while(count--) {
insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success);
}
glyphStorage.applyInsertions();
}
le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
EntryTableIndex2 index, LEErrorCode &success)
{
const ContextualGlyphInsertionStateEntry2 *entry = &entryTable[index];
const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success);
if(LE_FAILURE(success)) return 0; // TODO- which state?
le_uint16 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags);
le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
int i = 0;
le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
if (markIndex > 0) {
le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
if (!(flags & cgiMarkedIsKashidaLike)) {
// extra glyph(s) will be added directly before/after the specified marked glyph
if (!(flags & cgiMarkInsertBefore)) {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
for (i = 0; i < count; i++, markIndex++) {
insertGlyphs[i] = insertionTable[markIndex];
}
insertGlyphs[i] = glyphStorage[markGlyph];
glyphStorage.applyInsertions();
} else {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
insertGlyphs[0] = glyphStorage[markGlyph];
for (i = 1; i < count + 1; i++, markIndex++) {
insertGlyphs[i] = insertionTable[markIndex];
}
glyphStorage.applyInsertions();
}
} else {
// inserted as a split-vowel-like insertion
// extra glyph(s) will be inserted some distance away from the marked glyph
if (!(flags & cgiMarkInsertBefore)) {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
for (i = 0; i < count; i++, markIndex++) {
insertGlyphs[i] = insertionTable[markIndex];
}
insertGlyphs[i] = glyphStorage[markGlyph];
glyphStorage.applyInsertions();
} else {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
insertGlyphs[0] = glyphStorage[markGlyph];
for (i = 1; i < count + 1; i++, markIndex++) {
insertGlyphs[i] = insertionTable[markIndex];
}
glyphStorage.applyInsertions();
}
}
le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
le_bool isBefore = (flags & cgiMarkInsertBefore);
doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
}
le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
if (currIndex > 0) {
le_int16 count = flags & cgiCurrentInsertCountMask;
if (!(flags & cgiCurrentIsKashidaLike)) {
// extra glyph(s) will be added directly before/after the specified current glyph
if (!(flags & cgiCurrentInsertBefore)) {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
for (i = 0; i < count; i++, currIndex++) {
insertGlyphs[i] = insertionTable[currIndex];
}
insertGlyphs[i] = glyphStorage[currGlyph];
glyphStorage.applyInsertions();
} else {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
insertGlyphs[0] = glyphStorage[currGlyph];
for (i = 1; i < count + 1; i++, currIndex++) {
insertGlyphs[i] = insertionTable[currIndex];
}
glyphStorage.applyInsertions();
}
} else {
// inserted as a split-vowel-like insertion
// extra glyph(s) will be inserted some distance away from the current glyph
if (!(flags & cgiCurrentInsertBefore)) {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
for (i = 0; i < count; i++, currIndex++) {
insertGlyphs[i] = insertionTable[currIndex];
}
insertGlyphs[i] = glyphStorage[currGlyph];
glyphStorage.applyInsertions();
} else {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
insertGlyphs[0] = glyphStorage[currGlyph];
for (i = 1; i < count + 1; i++, currIndex++) {
insertGlyphs[i] = insertionTable[currIndex];
}
glyphStorage.applyInsertions();
}
}
le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
le_bool isBefore = (flags & cgiCurrentInsertBefore);
doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
}
if (flags & cgiSetMark) {
markGlyph = currGlyph;
}

View file

@ -28,11 +28,12 @@ class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2
public:
virtual void beginStateTable();
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage,
le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
virtual void endStateTable();
ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
ContextualGlyphInsertionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphInsertionProcessor2();
/**
@ -52,12 +53,28 @@ public:
private:
ContextualGlyphInsertionProcessor2();
/**
* Perform the actual insertion
* @param atGlyph index of glyph to insert at
* @param index index into the insertionTable (in/out)
* @param count number of insertions
* @param isKashidaLike Kashida like (vs Split Vowel like). No effect currently.
* @param isBefore if true, insert extra glyphs before the marked glyph
*/
void doInsertion(LEGlyphStorage &glyphStorage,
le_int16 atGlyph,
le_int16 &index,
le_int16 count,
le_bool isKashidaLike,
le_bool isBefore,
LEErrorCode &success);
protected:
le_int32 markGlyph;
const le_uint16* insertionTable;
const ContextualGlyphInsertionStateEntry2 *entryTable;
const ContextualGlyphInsertionHeader2 *contextualGlyphHeader;
LEReferenceToArrayOf<le_uint16> insertionTable;
LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2> entryTable;
LEReferenceTo<ContextualGlyphInsertionHeader2> contextualGlyphHeader;
};
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -18,13 +18,18 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor)
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
: StateTableProcessor(morphSubtableHeader)
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
{
contextualGlyphSubstitutionHeader = (const ContextualGlyphSubstitutionHeader *) morphSubtableHeader;
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
contextualGlyphSubstitutionHeader.orphan();
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
entryTable = (const ContextualGlyphSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
entryTable = LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry>(stateTableHeader, success,
(const ContextualGlyphSubstitutionStateEntry*)(&stateTableHeader->stHeader),
entryTableOffset, LE_UNBOUNDED_ARRAY);
int16Table = LEReferenceToArrayOf<le_int16>(stateTableHeader, success, (const le_int16*)(&stateTableHeader->stHeader),
0, LE_UNBOUNDED_ARRAY); // rest of the table as le_int16s
}
ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor()
@ -38,27 +43,26 @@ void ContextualGlyphSubstitutionProcessor::beginStateTable()
ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{
const ContextualGlyphSubstitutionStateEntry *entry = &entryTable[index];
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
WordOffset currOffset = SWAPW(entry->currOffset);
LEErrorCode success = LE_NO_ERROR;
const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
WordOffset currOffset = SWAPW(entry->currOffset);
if (markOffset != 0 && LE_SUCCESS(success)) {
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
if (markOffset != 0) {
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + markOffset * 2);
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(mGlyph)]);
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
}
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
}
if (currOffset != 0) {
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + currOffset * 2);
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(thisGlyph)]);
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
if (currOffset != 0) {
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
if (flags & cgsSetMark) {
markGlyph = currGlyph;

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -31,7 +31,7 @@ public:
virtual void endStateTable();
ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphSubstitutionProcessor();
/**
@ -53,11 +53,11 @@ private:
protected:
ByteOffset substitutionTableOffset;
const ContextualGlyphSubstitutionStateEntry *entryTable;
LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry> entryTable;
LEReferenceToArrayOf<le_int16> int16Table;
le_int32 markGlyph;
const ContextualGlyphSubstitutionHeader *contextualGlyphSubstitutionHeader;
LEReferenceTo<ContextualGlyphSubstitutionHeader> contextualGlyphSubstitutionHeader;
};

View file

@ -13,19 +13,19 @@
#include "ContextualGlyphSubstProc2.h"
#include "LEGlyphStorage.h"
#include "LESwaps.h"
#include <stdio.h>
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
: StateTableProcessor2(morphSubtableHeader)
ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader, success), contextualGlyphHeader(morphSubtableHeader, success)
{
contextualGlyphHeader = (const ContextualGlyphHeader2 *) morphSubtableHeader;
if(LE_FAILURE(success)) return;
le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
perGlyphTable = ((le_uint32 *) ((char *)&stateTableHeader->stHeader + perGlyphTableOffset));
entryTable = (const ContextualGlyphStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY);
entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
}
ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
@ -37,25 +37,28 @@ void ContextualGlyphSubstitutionProcessor2::beginStateTable()
markGlyph = 0;
}
le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
EntryTableIndex2 index, LEErrorCode &success)
{
const ContextualGlyphStateEntry2 *entry = &entryTable[index];
if(LE_FAILURE(success)) return 0;
const ContextualGlyphStateEntry2 *entry = entryTable.getAlias(index, success);
if(LE_FAILURE(success)) return 0;
le_uint16 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags);
le_int16 markIndex = SWAPW(entry->markIndex);
le_int16 currIndex = SWAPW(entry->currIndex);
if (markIndex != -1) {
le_uint32 offset = SWAPL(perGlyphTable[markIndex]);
le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = lookup(offset, mGlyph);
TTGlyphID newGlyph = lookup(offset, mGlyph, success);
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
}
if (currIndex != -1) {
le_uint32 offset = SWAPL(perGlyphTable[currIndex]);
le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = lookup(offset, thisGlyph);
TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
@ -70,26 +73,30 @@ le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorag
return newState;
}
TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid)
TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success)
{
LookupTable *lookupTable = ((LookupTable *) ((char *)perGlyphTable + offset));
le_int16 format = SWAPW(lookupTable->format);
TTGlyphID newGlyph = 0xFFFF;
if(LE_FAILURE(success)) return newGlyph;
LEReferenceTo<LookupTable> lookupTable(perGlyphTable, success, offset);
if(LE_FAILURE(success)) return newGlyph;
le_int16 format = SWAPW(lookupTable->format);
switch (format) {
case ltfSimpleArray: {
#ifdef TEST_FORMAT
// Disabled pending for design review
SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) lookupTable;
LEReferenceTo<SimpleArrayLookupTable> lookupTable0(lookupTable, success);
LEReferenceToArrayOf<LookupValue> valueArray(lookupTable0, success, &lookupTable0->valueArray[0], LE_UNBOUNDED_ARRAY);
if(LE_FAILURE(success)) return newGlyph;
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
newGlyph = SWAPW(lookupTable0->valueArray[glyphCode]);
newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success));
#endif
break;
}
case ltfSegmentSingle: {
#ifdef TEST_FORMAT
// Disabled pending for design review
SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
if (segment != NULL) {
newGlyph = SWAPW(segment->value);
@ -98,15 +105,15 @@ TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyp
break;
}
case ltfSegmentArray: {
printf("Context Lookup Table Format4: specific interpretation needed!\n");
//printf("Context Lookup Table Format4: specific interpretation needed!\n");
break;
}
case ltfSingleTable:
{
#ifdef TEST_FORMAT
// Disabled pending for design review
SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) lookupTable;
const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable;
const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
if (segment != NULL) {
newGlyph = SWAPW(segment->value);
}
@ -114,12 +121,15 @@ TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyp
break;
}
case ltfTrimmedArray: {
TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) lookupTable;
LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success);
if (LE_FAILURE(success)) return newGlyph;
TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount);
TTGlyphID glyphCount = SWAPW(lookupTable8->glyphCount);
TTGlyphID lastGlyph = firstGlyph + glyphCount;
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
newGlyph = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount);
newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success));
}
}
default:

View file

@ -27,11 +27,11 @@ class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2
public:
virtual void beginStateTable();
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
virtual void endStateTable();
ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
ContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphSubstitutionProcessor2();
/**
@ -50,16 +50,16 @@ public:
private:
ContextualGlyphSubstitutionProcessor2();
TTGlyphID lookup(le_uint32 offset, LEGlyphID gid);
TTGlyphID lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success);
protected:
const le_uint32* perGlyphTable;
const ContextualGlyphStateEntry2 *entryTable;
LEReferenceToArrayOf<le_uint32> perGlyphTable;
LEReferenceToArrayOf<ContextualGlyphStateEntry2> entryTable;
le_int16 perGlyphTableFormat;
le_int32 markGlyph;
const ContextualGlyphHeader2 *contextualGlyphHeader;
LEReferenceTo<ContextualGlyphHeader2> contextualGlyphHeader;
};

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -192,7 +192,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
le_uint16 srSetCount = SWAPW(subRuleSetCount);
@ -241,7 +241,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
const ClassDefinitionTable *classDefinitionTable =
@ -369,7 +369,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
le_uint16 srSetCount = SWAPW(chainSubRuleSetCount);
@ -440,7 +440,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
const ClassDefinitionTable *backtrackClassDefinitionTable =

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -18,6 +18,7 @@
#include "GlyphSubstitutionTables.h"
#include "GlyphIterator.h"
#include "LookupProcessor.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN
@ -63,6 +64,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
struct SubRuleSetTable
{
@ -70,6 +73,7 @@ struct SubRuleSetTable
Offset subRuleTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(SubRuleSetTable, subRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!!
struct SubRuleTable
@ -79,6 +83,7 @@ struct SubRuleTable
TTGlyphID inputGlyphArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
};
LE_VAR_ARRAY(SubRuleTable, inputGlyphArray)
struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
{
@ -88,12 +93,16 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
struct SubClassSetTable
{
le_uint16 subClassRuleCount;
Offset subClassRuleTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(SubClassSetTable, subClassRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!!
struct SubClassRuleTable
@ -103,6 +112,8 @@ struct SubClassRuleTable
le_uint16 classArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
};
LE_VAR_ARRAY(SubClassRuleTable, classArray)
// NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
// it has an array of coverage tables instead of a single coverage table...
@ -118,6 +129,7 @@ struct ContextualSubstitutionFormat3Subtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
{
@ -131,6 +143,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
struct ChainSubRuleSetTable
{
@ -138,6 +152,7 @@ struct ChainSubRuleSetTable
Offset chainSubRuleTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(ChainSubRuleSetTable, chainSubRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!!
struct ChainSubRuleTable
@ -151,6 +166,7 @@ struct ChainSubRuleTable
//le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
};
LE_VAR_ARRAY(ChainSubRuleTable, backtrackGlyphArray)
struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstitutionSubtable
{
@ -162,12 +178,15 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
struct ChainSubClassSetTable
{
le_uint16 chainSubClassRuleCount;
Offset chainSubClassRuleTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(ChainSubClassSetTable, chainSubClassRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!!
struct ChainSubClassRuleTable
@ -181,6 +200,7 @@ struct ChainSubClassRuleTable
//le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
};
LE_VAR_ARRAY(ChainSubClassRuleTable, backtrackClassArray)
// NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
// it has arrays of coverage tables instead of a single coverage table...
@ -200,6 +220,8 @@ struct ChainingContextualSubstitutionFormat3Subtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
U_NAMESPACE_END
#endif

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -31,6 +31,8 @@ struct CoverageFormat1Table : CoverageTable
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
};
LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
struct CoverageFormat2Table : CoverageTable
{
@ -39,6 +41,7 @@ struct CoverageFormat2Table : CoverageTable
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
};
LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
U_NAMESPACE_END
#endif

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998 - 2007 - All Rights Reserved
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
*
*/
@ -14,10 +14,10 @@
U_NAMESPACE_BEGIN
le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{
LEGlyphID glyphID = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyphID);
le_int32 coverageIndex = getGlyphCoverage(base, glyphID, success);
le_uint16 eeCount = SWAPW(entryExitCount);
if (coverageIndex < 0 || coverageIndex >= eeCount) {

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -32,8 +32,9 @@ struct CursiveAttachmentSubtable : GlyphPositioningSubtable
le_uint16 entryExitCount;
EntryExitRecord entryExitRecords[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
};
LE_VAR_ARRAY(CursiveAttachmentSubtable, entryExitRecords)
U_NAMESPACE_END
#endif

View file

@ -1,7 +1,7 @@
/*
* @(#)DeviceTables.h 1.5 00/03/15
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -32,6 +32,7 @@ private:
static const le_uint16 fieldSignBits[];
static const le_uint16 fieldBits[];
};
LE_VAR_ARRAY(DeviceTable, deltaValues)
U_NAMESPACE_END
#endif

View file

@ -1,7 +1,7 @@
/*
* %W% %E%
*
* (C) Copyright IBM Corp. 2008-2011 - All Rights Reserved
* (C) Copyright IBM Corp. 2008-2013 - All Rights Reserved
*
*/
@ -26,6 +26,8 @@ static inline le_uint32 READ_LONG(le_uint32 code) {
le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{
const LEReferenceTo<ExtensionSubtable> thisRef(lookupProcessor->getReference(), success); // create a reference to this
if (LE_FAILURE(success)) {
return 0;
}
@ -34,9 +36,11 @@ le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_
if (elt != lookupType) {
le_uint32 extOffset = READ_LONG(extensionOffset);
LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset);
LEReferenceTo<LookupSubtable> subtable(thisRef, success, extOffset);
return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
if(LE_SUCCESS(success)) {
return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
}
}
return 0;

View file

@ -1,7 +1,7 @@
/*
* @(#)Features.cpp 1.4 00/03/15
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -13,19 +13,20 @@
U_NAMESPACE_BEGIN
const FeatureTable *FeatureListTable::getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const
LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const
{
if (featureIndex >= SWAPW(featureCount)) {
return 0;
}
if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
return LEReferenceTo<FeatureTable>();
}
Offset featureTableOffset = featureRecordArray[featureIndex].featureTableOffset;
*featureTag = SWAPT(featureRecordArray[featureIndex].featureTag);
return (const FeatureTable *) ((char *) this + SWAPW(featureTableOffset));
return LEReferenceTo<FeatureTable>(base, success, SWAPW(featureTableOffset));
}
#if 0
/*
* Note: according to the OpenType Spec. v 1.4, the entries in the Feature
* List Table are sorted alphabetically by feature tag; however, there seem
@ -57,5 +58,6 @@ const FeatureTable *FeatureListTable::getFeatureTable(LETag featureTag) const
return 0;
#endif
}
#endif
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998 - 2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
*
*/
@ -11,9 +11,12 @@
U_NAMESPACE_BEGIN
GDEFMarkFilter::GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
GDEFMarkFilter::GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
: classDefTable(gdefTable->getGlyphClassDefinitionTable(gdefTable, success))
{
classDefTable = gdefTable->getGlyphClassDefinitionTable();
if(!classDefTable.isValid()) {
success = LE_INTERNAL_ERROR;
}
}
GDEFMarkFilter::~GDEFMarkFilter()

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -21,13 +21,13 @@ U_NAMESPACE_BEGIN
class GDEFMarkFilter : public UMemory, public LEGlyphFilter
{
private:
const GlyphClassDefinitionTable *classDefTable;
const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
GDEFMarkFilter(const GDEFMarkFilter &other); // forbid copying of this class
GDEFMarkFilter &operator=(const GDEFMarkFilter &other); // forbid copying of this class
public:
GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~GDEFMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const;

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -16,9 +16,10 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine)
GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success)
GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable)
{
fMorphTable.orphan();
// nothing else to do?
}
@ -45,7 +46,7 @@ le_int32 GXLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset,
return 0;
}
fMorphTable->process(glyphStorage);
fMorphTable->process(fMorphTable, glyphStorage, success);
return count;
}

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -49,7 +49,7 @@ public:
*
* @internal
*/
GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success);
GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
@ -79,7 +79,7 @@ protected:
*
* @internal
*/
const MorphTableHeader *fMorphTable;
LEReferenceTo<MorphTableHeader> fMorphTable;
/**
* This method does GX layout using the font's 'mort' table. It converts the

View file

@ -14,10 +14,10 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2)
GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
{
// nothing else to do?
// nothing else to do?
}
GXLayoutEngine2::~GXLayoutEngine2()
@ -43,7 +43,7 @@ le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset
return 0;
}
fMorphTable->process(glyphStorage, fTypoFlags);
fMorphTable->process(fMorphTable, glyphStorage, fTypoFlags, success);
return count;
}

View file

@ -48,7 +48,7 @@ public:
*
* @internal
*/
GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success);
GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
@ -78,7 +78,7 @@ protected:
*
* @internal
*/
const MorphTableHeader2 *fMorphTable;
const LEReferenceTo<MorphTableHeader2> fMorphTable;
/**
* This method does GX layout using the font's 'mort' table. It converts the

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998 - 2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
*
*/
@ -11,24 +11,36 @@
U_NAMESPACE_BEGIN
const GlyphClassDefinitionTable *GlyphDefinitionTableHeader::getGlyphClassDefinitionTable() const
const LEReferenceTo<GlyphClassDefinitionTable>
GlyphDefinitionTableHeader::getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success) const
{
return (const GlyphClassDefinitionTable *) ((char *) this + SWAPW(glyphClassDefOffset));
if(LE_FAILURE(success)) return LEReferenceTo<GlyphClassDefinitionTable>();
return LEReferenceTo<GlyphClassDefinitionTable>(base, success, SWAPW(glyphClassDefOffset));
}
const AttachmentListTable *GlyphDefinitionTableHeader::getAttachmentListTable() const
const LEReferenceTo<AttachmentListTable>
GlyphDefinitionTableHeader::getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success) const
{
return (const AttachmentListTable *) ((char *) this + SWAPW(attachListOffset));
if(LE_FAILURE(success)) return LEReferenceTo<AttachmentListTable>();
return LEReferenceTo<AttachmentListTable>(base, success, SWAPW(attachListOffset));
}
const LigatureCaretListTable *GlyphDefinitionTableHeader::getLigatureCaretListTable() const
const LEReferenceTo<LigatureCaretListTable>
GlyphDefinitionTableHeader::getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success) const
{
return (const LigatureCaretListTable *) ((char *) this + SWAPW(ligCaretListOffset));
if(LE_FAILURE(success)) return LEReferenceTo<LigatureCaretListTable>();
return LEReferenceTo<LigatureCaretListTable>(base, success, SWAPW(ligCaretListOffset));
}
const MarkAttachClassDefinitionTable *GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable() const
const LEReferenceTo<MarkAttachClassDefinitionTable>
GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success) const
{
return (const MarkAttachClassDefinitionTable *) ((char *) this + SWAPW(MarkAttachClassDefOffset));
if(LE_FAILURE(success)) return LEReferenceTo<MarkAttachClassDefinitionTable>();
return LEReferenceTo<MarkAttachClassDefinitionTable>(base, success, SWAPW(MarkAttachClassDefOffset));
}
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -35,12 +35,14 @@ struct AttachmentListTable
le_uint16 glyphCount;
Offset attachPointTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(AttachmentListTable, attachPointTableOffsetArray)
struct AttachPointTable
{
le_uint16 pointCount;
le_uint16 pointIndexArray[ANY_NUMBER];
};
LE_VAR_ARRAY(AttachPointTable, pointIndexArray)
struct LigatureCaretListTable
{
@ -48,12 +50,14 @@ struct LigatureCaretListTable
le_uint16 ligGlyphCount;
Offset ligGlyphTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(LigatureCaretListTable, ligGlyphTableOffsetArray)
struct LigatureGlyphTable
{
le_uint16 caretCount;
Offset caretValueTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(LigatureGlyphTable, caretValueTableOffsetArray)
struct CaretValueTable
{
@ -86,10 +90,18 @@ struct GlyphDefinitionTableHeader
Offset ligCaretListOffset;
Offset MarkAttachClassDefOffset;
const GlyphClassDefinitionTable *getGlyphClassDefinitionTable() const;
const AttachmentListTable *getAttachmentListTable()const ;
const LigatureCaretListTable *getLigatureCaretListTable() const;
const MarkAttachClassDefinitionTable *getMarkAttachClassDefinitionTable() const;
const LEReferenceTo<GlyphClassDefinitionTable>
getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success) const;
const LEReferenceTo<AttachmentListTable>
getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success)const ;
const LEReferenceTo<LigatureCaretListTable>
getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success) const;
const LEReferenceTo<MarkAttachClassDefinitionTable>
getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
LEErrorCode &success) const;
};
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -16,18 +16,21 @@
U_NAMESPACE_BEGIN
GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader)
: direction(1), position(-1), nextLimit(-1), prevLimit(-1),
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
glyphClassDefinitionTable(), markAttachClassDefinitionTable()
{
LEErrorCode success = LE_NO_ERROR; // TODO
le_int32 glyphCount = glyphStorage.getGlyphCount();
if (theGlyphDefinitionTableHeader != NULL) {
glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
if (theGlyphDefinitionTableHeader.isValid()) {
glyphClassDefinitionTable = theGlyphDefinitionTableHeader
-> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success);
markAttachClassDefinitionTable = theGlyphDefinitionTableHeader
->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success);
}
nextLimit = glyphCount;
@ -355,6 +358,7 @@ void GlyphIterator::setCursiveGlyph()
le_bool GlyphIterator::filterGlyph(le_uint32 index) const
{
LEErrorCode success = LE_NO_ERROR;
LEGlyphID glyphID = glyphStorage[index];
le_int32 glyphClass = gcdNoGlyphClass;
@ -362,8 +366,8 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const
return TRUE;
}
if (glyphClassDefinitionTable != NULL) {
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID);
if (glyphClassDefinitionTable.isValid()) {
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
}
switch (glyphClass)
@ -385,8 +389,9 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) {
return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType;
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
return markAttachClassDefinitionTable
-> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType;
}
return FALSE;
@ -436,6 +441,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta)
while (newPosition != nextLimit && delta > 0) {
do {
newPosition += direction;
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
} while (newPosition != nextLimit && filterGlyph(newPosition));
delta -= 1;
@ -443,6 +449,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta)
position = newPosition;
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
return position != nextLimit;
}
@ -458,6 +465,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta)
while (newPosition != prevLimit && delta > 0) {
do {
newPosition -= direction;
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
} while (newPosition != prevLimit && filterGlyph(newPosition));
delta -= 1;
@ -465,6 +473,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta)
position = newPosition;
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
return position != prevLimit;
}

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -24,7 +24,7 @@ class GlyphPositionAdjustments;
class GlyphIterator : public UMemory {
public:
GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader);
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader);
GlyphIterator(GlyphIterator &that);
@ -92,8 +92,8 @@ private:
FeatureMask featureMask;
le_int32 glyphGroup;
const GlyphClassDefinitionTable *glyphClassDefinitionTable;
const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable;
LEReferenceTo<GlyphClassDefinitionTable> glyphClassDefinitionTable;
LEReferenceTo<MarkAttachClassDefinitionTable> markAttachClassDefinitionTable;
GlyphIterator &operator=(const GlyphIterator &other); // forbid copying of this class
};

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -12,21 +12,22 @@
U_NAMESPACE_BEGIN
le_bool GlyphLookupTableHeader::coversScript(LETag scriptTag) const
le_bool GlyphLookupTableHeader::coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const
{
const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset));
LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
return scriptListOffset != 0 && scriptListTable->findScript(scriptTag) != NULL;
return (scriptListOffset != 0) && scriptListTable->findScript(scriptListTable, scriptTag, success) .isValid();
}
le_bool GlyphLookupTableHeader::coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const
le_bool GlyphLookupTableHeader::coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
{
const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset));
const LangSysTable *langSysTable = scriptListTable->findLanguage(scriptTag, languageTag, exactMatch);
LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
LEReferenceTo<LangSysTable> langSysTable = scriptListTable->findLanguage(scriptListTable,
scriptTag, languageTag, success, exactMatch);
// FIXME: could check featureListOffset, lookupListOffset, and lookup count...
// Note: don't have to SWAPW langSysTable->featureCount to check for non-zero.
return langSysTable != NULL && langSysTable->featureCount != 0;
return LE_SUCCESS(success)&&langSysTable.isValid() && langSysTable->featureCount != 0;
}
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -24,8 +24,8 @@ struct GlyphLookupTableHeader
Offset featureListOffset;
Offset lookupListOffset;
le_bool coversScript(LETag scriptTag) const;
le_bool coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const;
le_bool coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const;
le_bool coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
};
U_NAMESPACE_END

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -16,16 +16,16 @@
U_NAMESPACE_BEGIN
void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
void GlyphPositioningTableHeader::process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
{
if (LE_FAILURE(success)) {
return;
}
GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
GlyphPositioningLookupProcessor processor(base, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
if (LE_FAILURE(success)) {
return;
}

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -15,6 +15,7 @@
#include "OpenTypeTables.h"
#include "Lookups.h"
#include "GlyphLookupTables.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN
@ -26,9 +27,9 @@ struct GlyphDefinitionTableHeader;
struct GlyphPositioningTableHeader : public GlyphLookupTableHeader
{
void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
void process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
};

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998 - 2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
*
*/
@ -32,7 +32,7 @@ typedef ContextualSubstitutionSubtable ContextualPositioningSubtable;
typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubtable;
GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
const GlyphPositioningTableHeader *glyphPositioningTableHeader,
const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
LETag scriptTag,
LETag languageTag,
const FeatureMap *featureMap,
@ -40,7 +40,7 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
le_bool featureOrder,
LEErrorCode& success)
: LookupProcessor(
(char *) glyphPositioningTableHeader,
glyphPositioningTableHeader,
SWAPW(glyphPositioningTableHeader->scriptListOffset),
SWAPW(glyphPositioningTableHeader->featureListOffset),
SWAPW(glyphPositioningTableHeader->lookupListOffset),
@ -59,7 +59,7 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor()
{
}
le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
@ -77,55 +77,55 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
case gpstSingle:
{
const SinglePositioningSubtable *subtable = (const SinglePositioningSubtable *) lookupSubtable;
LEReferenceTo<SinglePositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fontInstance);
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
break;
}
case gpstPair:
{
const PairPositioningSubtable *subtable = (const PairPositioningSubtable *) lookupSubtable;
LEReferenceTo<PairPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fontInstance);
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
break;
}
case gpstCursive:
{
const CursiveAttachmentSubtable *subtable = (const CursiveAttachmentSubtable *) lookupSubtable;
LEReferenceTo<CursiveAttachmentSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fontInstance);
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
break;
}
case gpstMarkToBase:
{
const MarkToBasePositioningSubtable *subtable = (const MarkToBasePositioningSubtable *) lookupSubtable;
LEReferenceTo<MarkToBasePositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fontInstance);
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
break;
}
case gpstMarkToLigature:
{
const MarkToLigaturePositioningSubtable *subtable = (const MarkToLigaturePositioningSubtable *) lookupSubtable;
LEReferenceTo<MarkToLigaturePositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fontInstance);
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
break;
}
case gpstMarkToMark:
{
const MarkToMarkPositioningSubtable *subtable = (const MarkToMarkPositioningSubtable *) lookupSubtable;
LEReferenceTo<MarkToMarkPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fontInstance);
delta = subtable->process(subtable, glyphIterator, fontInstance, success);
break;
}
case gpstContext:
{
const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable;
LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
@ -133,7 +133,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
case gpstChainedContext:
{
const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable;
LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
@ -141,7 +141,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
case gpstExtension:
{
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break;

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -26,7 +26,7 @@ U_NAMESPACE_BEGIN
class GlyphPositioningLookupProcessor : public LookupProcessor
{
public:
GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader,
GlyphPositioningLookupProcessor(const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
LETag scriptTag,
LETag languageTag,
const FeatureMap *featureMap,
@ -36,7 +36,7 @@ public:
virtual ~GlyphPositioningLookupProcessor();
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected:

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -26,7 +26,7 @@
U_NAMESPACE_BEGIN
GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
LETag scriptTag,
LETag languageTag,
const LEGlyphFilter *filter,
@ -35,7 +35,7 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
le_bool featureOrder,
LEErrorCode& success)
: LookupProcessor(
(char *) glyphSubstitutionTableHeader,
glyphSubstitutionTableHeader,
SWAPW(glyphSubstitutionTableHeader->scriptListOffset),
SWAPW(glyphSubstitutionTableHeader->featureListOffset),
SWAPW(glyphSubstitutionTableHeader->lookupListOffset),
@ -48,7 +48,7 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor()
{
}
le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
@ -64,39 +64,39 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
case gsstSingle:
{
const SingleSubstitutionSubtable *subtable = (const SingleSubstitutionSubtable *) lookupSubtable;
const LEReferenceTo<SingleSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fFilter);
delta = subtable->process(subtable, glyphIterator, success, fFilter);
break;
}
case gsstMultiple:
{
const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable;
const LEReferenceTo<MultipleSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, success, fFilter);
delta = subtable->process(subtable, glyphIterator, success, fFilter);
break;
}
case gsstAlternate:
{
const AlternateSubstitutionSubtable *subtable = (const AlternateSubstitutionSubtable *) lookupSubtable;
const LEReferenceTo<AlternateSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fFilter);
delta = subtable->process(subtable, glyphIterator, success, fFilter);
break;
}
case gsstLigature:
{
const LigatureSubstitutionSubtable *subtable = (const LigatureSubstitutionSubtable *) lookupSubtable;
const LEReferenceTo<LigatureSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(glyphIterator, fFilter);
delta = subtable->process(subtable, glyphIterator, success, fFilter);
break;
}
case gsstContext:
{
const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable;
const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
@ -104,7 +104,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
case gsstChainingContext:
{
const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable;
const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
@ -112,7 +112,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
case gsstExtension:
{
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break;

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -27,7 +27,7 @@ U_NAMESPACE_BEGIN
class GlyphSubstitutionLookupProcessor : public LookupProcessor
{
public:
GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
GlyphSubstitutionLookupProcessor(const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
LETag scriptTag,
LETag languageTag,
const LEGlyphFilter *filter,
@ -38,7 +38,7 @@ public:
virtual ~GlyphSubstitutionLookupProcessor();
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected:

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -17,11 +17,12 @@
U_NAMESPACE_BEGIN
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage,
le_int32 GlyphSubstitutionTableHeader::process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
LEGlyphStorage &glyphStorage,
le_bool rightToLeft,
LETag scriptTag,
LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
@ -32,7 +33,7 @@ le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage,
return 0;
}
GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
GlyphSubstitutionLookupProcessor processor(base, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success);
}

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -25,11 +25,12 @@ struct GlyphDefinitionTableHeader;
struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
{
le_int32 process(LEGlyphStorage &glyphStorage,
le_int32 process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
LEGlyphStorage &glyphStorage,
le_bool rightToLeft,
LETag scriptTag,
LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,

View file

@ -1,7 +1,7 @@
/*
* HanLayoutEngine.cpp: OpenType processing for Han fonts.
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved.
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved.
*/
#include "LETypes.h"
@ -39,7 +39,7 @@ static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
#define features (loclFeatureMask)
HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = featureMap;

View file

@ -2,7 +2,7 @@
/*
* HanLayoutEngine.h: OpenType processing for Han fonts.
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved.
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved.
*/
#ifndef __HANLAYOUTENGINE_H
@ -48,7 +48,7 @@ public:
* @internal
*/
HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTablem, LEErrorCode &success);
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTablem, LEErrorCode &success);
/**

View file

@ -1,7 +1,7 @@
/*
* HangulLayoutEngine.cpp: OpenType processing for Han fonts.
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved.
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved.
*/
#include "LETypes.h"
@ -184,7 +184,7 @@ static le_int32 getCharClass(LEUnicode ch, LEUnicode &lead, LEUnicode &vowel, LE
}
HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success)
{
fFeatureMap = featureMap;

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -55,7 +55,7 @@ public:
* @internal
*/
HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -29,16 +29,21 @@ struct FeatureTable
le_uint16 lookupCount;
le_uint16 lookupListIndexArray[ANY_NUMBER];
};
LE_VAR_ARRAY(FeatureTable, lookupListIndexArray)
struct FeatureListTable
{
le_uint16 featureCount;
FeatureRecord featureRecordArray[ANY_NUMBER];
const FeatureTable *getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const;
LEReferenceTo<FeatureTable> getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const;
const FeatureTable *getFeatureTable(LETag featureTag) const;
#if 0
const LEReferenceTo<FeatureTable> getFeatureTable(const LETableReference &base, LETag featureTag, LEErrorCode &success) const;
#endif
};
LE_VAR_ARRAY(FeatureListTable, featureRecordArray)
U_NAMESPACE_END
#endif

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -25,7 +25,7 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
{
if ( version2 ) {

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -56,7 +56,7 @@ public:
* @internal
*/
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -18,11 +18,14 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader)
: StateTableProcessor(morphSubtableHeader)
IndicRearrangementProcessor::IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success),
indicRearrangementSubtableHeader(morphSubtableHeader, success),
entryTable(stateTableHeader, success, (const IndicRearrangementStateEntry*)(&stateTableHeader->stHeader),
entryTableOffset, LE_UNBOUNDED_ARRAY),
int16Table(stateTableHeader, success, (const le_int16*)entryTable.getAlias(), 0, LE_UNBOUNDED_ARRAY)
{
indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader *) morphSubtableHeader;
entryTable = (const IndicRearrangementStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
}
IndicRearrangementProcessor::~IndicRearrangementProcessor()
@ -37,7 +40,8 @@ void IndicRearrangementProcessor::beginStateTable()
ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{
const IndicRearrangementStateEntry *entry = &entryTable[index];
LEErrorCode success = LE_NO_ERROR; // todo- make a param?
const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
ByteOffset newState = SWAPW(entry->newStateOffset);
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -33,7 +33,7 @@ public:
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader);
IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~IndicRearrangementProcessor();
/**
@ -54,8 +54,9 @@ protected:
le_int32 firstGlyph;
le_int32 lastGlyph;
const IndicRearrangementStateEntry *entryTable;
const IndicRearrangementSubtableHeader *indicRearrangementSubtableHeader;
LEReferenceTo<IndicRearrangementSubtableHeader> indicRearrangementSubtableHeader;
LEReferenceToArrayOf<IndicRearrangementStateEntry> entryTable;
LEReferenceToArrayOf<le_int16> int16Table;
};

View file

@ -18,11 +18,11 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
: StateTableProcessor2(morphSubtableHeader)
IndicRearrangementProcessor2::IndicRearrangementProcessor2(
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader, success), indicRearrangementSubtableHeader(morphSubtableHeader, success),
entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY)
{
indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader2 *) morphSubtableHeader;
entryTable = (const IndicRearrangementStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
}
IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
@ -35,9 +35,11 @@ void IndicRearrangementProcessor2::beginStateTable()
lastGlyph = 0;
}
le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
EntryTableIndex2 index, LEErrorCode &success)
{
const IndicRearrangementStateEntry2 *entry = &entryTable[index];
const IndicRearrangementStateEntry2 *entry = entryTable.getAlias(index, success);
if (LE_FAILURE(success)) return 0; // TODO - what to return in bad state?
le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);

View file

@ -27,13 +27,13 @@ class IndicRearrangementProcessor2 : public StateTableProcessor2
public:
virtual void beginStateTable();
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
virtual void endStateTable();
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
IndicRearrangementProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~IndicRearrangementProcessor2();
/**
@ -54,8 +54,8 @@ protected:
le_int32 firstGlyph;
le_int32 lastGlyph;
const IndicRearrangementStateEntry2 *entryTable;
const IndicRearrangementSubtableHeader2 *indicRearrangementSubtableHeader;
LEReferenceToArrayOf<IndicRearrangementStateEntry2> entryTable;
LEReferenceTo<IndicRearrangementSubtableHeader2> indicRearrangementSubtableHeader;
};

View file

@ -1,6 +1,6 @@
/*
/ *
* (C) Copyright IBM Corp. 1998-2012 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -633,6 +633,11 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
MPreFixups *mpreFixups = NULL;
const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
if(classTable==NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
if (classTable->scriptFlags & SF_MPRE_FIXUP) {
mpreFixups = new MPreFixups(charCount);
if (mpreFixups == NULL) {

View file

@ -1,7 +1,7 @@
/*
* @(#)KernTable.cpp 1.1 04/10/13
*
* (C) Copyright IBM Corp. 2004-2007 - All Rights Reserved
* (C) Copyright IBM Corp. 2004-2013 - All Rights Reserved
*
*/
@ -24,6 +24,7 @@ struct PairInfo {
le_int16 value; // fword, kern value in funits
};
#define KERN_PAIRINFO_SIZE 6
LE_CORRECT_SIZE(PairInfo, KERN_PAIRINFO_SIZE)
#define SWAP_KEY(p) (((le_uint32) SWAPW((p)->left) << 16) | SWAPW((p)->right))
@ -34,6 +35,7 @@ struct Subtable_0 {
le_uint16 rangeShift;
};
#define KERN_SUBTABLE_0_HEADER_SIZE 8
LE_CORRECT_SIZE(Subtable_0, KERN_SUBTABLE_0_HEADER_SIZE)
// Kern table version 0 only
struct SubtableHeader {
@ -42,6 +44,7 @@ struct SubtableHeader {
le_uint16 coverage;
};
#define KERN_SUBTABLE_HEADER_SIZE 6
LE_CORRECT_SIZE(SubtableHeader, KERN_SUBTABLE_HEADER_SIZE)
// Version 0 only, version 1 has different layout
struct KernTableHeader {
@ -49,6 +52,7 @@ struct KernTableHeader {
le_uint16 nTables;
};
#define KERN_TABLE_HEADER_SIZE 4
LE_CORRECT_SIZE(KernTableHeader, KERN_TABLE_HEADER_SIZE)
#define COVERAGE_HORIZONTAL 0x1
#define COVERAGE_MINIMUM 0x2
@ -70,21 +74,21 @@ struct KernTableHeader {
* TODO: support multiple subtables
* TODO: respect header flags
*/
KernTable::KernTable(const LEFontInstance* font, const void* tableData)
: pairs(0), font(font)
KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
: pairs(), fTable(base)
{
const KernTableHeader* header = (const KernTableHeader*)tableData;
if (header == 0) {
if(LE_FAILURE(success) || fTable.isEmpty()) {
#if DEBUG
fprintf(stderr, "no kern data\n");
#endif
return;
}
LEReferenceTo<KernTableHeader> header(fTable, success);
#if DEBUG
// dump first 32 bytes of header
for (int i = 0; i < 64; ++i) {
fprintf(stderr, "%0.2x ", ((const char*)tableData)[i]&0xff);
fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
if (((i+1)&0xf) == 0) {
fprintf(stderr, "\n");
} else if (((i+1)&0x7) == 0) {
@ -93,14 +97,18 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData)
}
#endif
if (header->version == 0 && SWAPW(header->nTables) > 0) {
const SubtableHeader* subhead = (const SubtableHeader*)((char*)tableData + KERN_TABLE_HEADER_SIZE);
if(LE_FAILURE(success)) return;
if (subhead->version == 0) {
if (!header.isEmpty() && header->version == 0 && SWAPW(header->nTables) > 0) {
LEReferenceTo<SubtableHeader> subhead(header, success, KERN_TABLE_HEADER_SIZE);
if (LE_SUCCESS(success) && !subhead.isEmpty() && subhead->version == 0) {
coverage = SWAPW(subhead->coverage);
if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning
const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE);
LEReferenceTo<Subtable_0> table(subhead, success, KERN_SUBTABLE_HEADER_SIZE);
if(table.isEmpty() || LE_FAILURE(success)) return;
nPairs = SWAPW(table->nPairs);
@ -114,13 +122,27 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData)
rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange;
#endif
pairs = (const PairInfo*)((char*)table + KERN_SUBTABLE_0_HEADER_SIZE);
if(LE_SUCCESS(success) && nPairs>0) {
// pairs is an instance member, and table is on the stack.
// set 'pairs' based on table.getAlias(). This will range check it.
pairs = LEReferenceToArrayOf<PairInfo>(fTable, // based on overall table
success,
(const PairInfo*)table.getAlias(), // subtable 0 + ..
KERN_SUBTABLE_0_HEADER_SIZE, // .. offset of header size
nPairs); // count
}
#if 0
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs %p\n", coverage, nPairs, pairs.getAlias());
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
#endif
#if DEBUG
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs);
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
{
if(LE_SUCCESS(success) {
// dump part of the pair list
char ids[256];
@ -132,12 +154,13 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData)
}
}
const PairInfo* p = pairs;
for (i = 0; i < nPairs; ++i) {
const PairInfo& p = pairs[i, success];
for (i = 0; i < nPairs; ++i, p = (const PairInfo*)((char*)p+KERN_PAIRINFO_SIZE)) {
le_uint16 left = p->left;
le_uint16 right = p->right;
if (left < 256 && right < 256) {
char c = ids[left];
@ -161,21 +184,20 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData)
}
}
}
/*
* Process the glyph positions. The positions array has two floats for each
* glyph, plus a trailing pair to mark the end of the last glyph.
g * glyph, plus a trailing pair to mark the end of the last glyph.
*/
void KernTable::process(LEGlyphStorage& storage)
void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
{
if (pairs) {
LEErrorCode success = LE_NO_ERROR;
if (LE_SUCCESS(success) && !pairs.isEmpty()) {
le_uint32 key = storage[0]; // no need to mask off high bits
float adjust = 0;
for (int i = 1, e = storage.getGlyphCount(); i < e; ++i) {
for (int i = 1, e = storage.getGlyphCount(); LE_SUCCESS(success)&& i < e; ++i) {
key = key << 16 | (storage[i] & 0xffff);
// argh, to do a binary search, we need to have the pair list in sorted order
@ -183,8 +205,11 @@ void KernTable::process(LEGlyphStorage& storage)
// so either I have to swap the element each time I examine it, or I have to swap
// all the elements ahead of time and store them in the font
const PairInfo* p = pairs;
const PairInfo* tp = (const PairInfo*)((char*)p + rangeShift);
const PairInfo *p = pairs.getAlias(0, success);
LEReferenceTo<PairInfo> tpRef(pairs, success, rangeShift); // ((char*)pairs) + rangeShift
const PairInfo *tp = tpRef.getAlias();
if(LE_FAILURE(success)) return; // get out.
if (key > SWAP_KEY(tp)) {
p = tp;
@ -196,23 +221,24 @@ void KernTable::process(LEGlyphStorage& storage)
le_uint32 probe = searchRange;
while (probe > KERN_PAIRINFO_SIZE) {
while (probe > KERN_PAIRINFO_SIZE && LE_SUCCESS(success)) {
probe >>= 1;
tp = (const PairInfo*)((char*)p + probe);
tpRef = LEReferenceTo<PairInfo>(pairs, success, p, probe); // (char*)p + probe
tp = tpRef.getAlias();
le_uint32 tkey = SWAP_KEY(tp);
if(LE_FAILURE(success)) break;
#if DEBUG
fprintf(stdout, " %.3d (%0.8x)\n", ((char*)tp - (char*)pairs)/KERN_PAIRINFO_SIZE, tkey);
#endif
if (tkey <= key) {
if (tkey <= key && LE_SUCCESS(success)) {
if (tkey == key) {
le_int16 value = SWAPW(tp->value);
#if DEBUG
fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n",
fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n",
storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
fflush(stdout);
#endif
adjust += font->xUnitsToPoints(value);
adjust += fTable.getFont()->xUnitsToPoints(value);
break;
}

View file

@ -1,7 +1,7 @@
/*
* @(#)KernTable.h 1.1 04/10/13
*
* (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 2004-2013 - All Rights Reserved
*
*/
@ -13,6 +13,7 @@
#endif
#include "LETypes.h"
#include "LETableReference.h"
//#include "LEFontInstance.h"
//#include "LEGlyphStorage.h"
@ -31,19 +32,19 @@ class U_LAYOUT_API KernTable
private:
le_uint16 coverage;
le_uint16 nPairs;
const PairInfo* pairs;
const LEFontInstance* font;
LEReferenceToArrayOf<PairInfo> pairs;
const LETableReference &fTable;
le_uint16 searchRange;
le_uint16 entrySelector;
le_uint16 rangeShift;
public:
KernTable(const LEFontInstance* font, const void* tableData);
KernTable(const LETableReference &table, LEErrorCode &success);
/*
* Process the glyph positions.
*/
void process(LEGlyphStorage& storage);
void process(LEGlyphStorage& storage, LEErrorCode &success);
};
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
* This file is a modification of the ICU file IndicLayoutEngine.cpp
* by Jens Herden and Javier Sola for Khmer language
@ -18,7 +18,7 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine)
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);

View file

@ -1,7 +1,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
* This file is a modification of the ICU file IndicLayoutEngine.h
* by Jens Herden and Javier Sola for Khmer language
@ -58,7 +58,7 @@ public:
* @internal
*/
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known

View file

@ -0,0 +1,418 @@
/*
* -*- c++ -*-
*
* (C) Copyright IBM Corp. and others 2013 - All Rights Reserved
*
* Range checking
*
*/
#ifndef __LETABLEREFERENCE_H
#define __LETABLEREFERENCE_H
#include "LETypes.h"
#include "LEFontInstance.h"
#define kQuestionmarkTableTag 0x3F3F3F3FUL
#define kTildeTableTag 0x7e7e7e7eUL
#ifdef __cplusplus
// internal - interface for range checking
U_NAMESPACE_BEGIN
#if LE_ASSERT_BAD_FONT
class LETableReference; // fwd
/**
* defined in OpenTypeUtilities.cpp
* @internal
*/
extern void _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len);
#define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
#define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
#if 0
#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
#else
#define LE_TRACE_TR(x)
#endif
#else
#define LE_DEBUG_TR(x)
#define LE_DEBUG_TR3(x,y,z)
#define LE_TRACE_TR(x)
#endif
/**
* @internal
*/
class LETableReference {
public:
/**
* @internal
* Construct from a specific tag
*/
LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
loadTable(success);
LE_TRACE_TR("INFO: new table load")
}
LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) {
if(LE_FAILURE(success)) {
clear();
}
LE_TRACE_TR("INFO: new clone")
}
LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
LE_TRACE_TR("INFO: new raw")
}
LETableReference() :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
LE_TRACE_TR("INFO: new empty")
}
~LETableReference() {
fTag=kTildeTableTag;
LE_TRACE_TR("INFO: new dtor")
}
/**
* @internal
* @param length if LE_UINTPTR_MAX means "whole table"
* subset
*/
LETableReference(const LETableReference &parent, size_t offset, size_t length,
LEErrorCode &err) :
fFont(parent.fFont), fTag(parent.fTag), fParent(&parent),
fStart((parent.fStart)+offset), fLength(length) {
if(LE_SUCCESS(err)) {
if(isEmpty()) {
//err = LE_MISSING_FONT_TABLE_ERROR;
clear(); // it's just empty. Not an error.
} else if(offset >= fParent->fLength) {
LE_DEBUG_TR3("offset out of range: (%p) +%d", NULL, offset);
err = LE_INDEX_OUT_OF_BOUNDS_ERROR;
clear();
} else {
if(fLength == LE_UINTPTR_MAX &&
fParent->fLength != LE_UINTPTR_MAX) {
fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
}
if(fLength != LE_UINTPTR_MAX) { // if we have bounds:
if(offset+fLength > fParent->fLength) {
LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength);
err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
clear();
}
}
}
} else {
clear();
}
LE_TRACE_TR("INFO: new subset")
}
const void* getAlias() const { return (const void*)fStart; }
const void* getAliasRAW() const { LE_DEBUG_TR("getAliasRAW()"); return (const void*)fStart; }
le_bool isEmpty() const { return fStart==NULL || fLength==0; }
le_bool isValid() const { return !isEmpty(); }
le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
void clear() { fLength=0; fStart=NULL; }
size_t getLength() const { return fLength; }
const LEFontInstance* getFont() const { return fFont; }
LETag getTag() const { return fTag; }
const LETableReference* getParent() const { return fParent; }
void addOffset(size_t offset, LEErrorCode &success) {
if(hasBounds()) {
if(offset > fLength) {
LE_DEBUG_TR("addOffset off end");
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
return;
} else {
fLength -= offset;
}
}
fStart += offset;
}
size_t ptrToOffset(const void *atPtr, LEErrorCode &success) const {
if(atPtr==NULL) return 0;
if(LE_FAILURE(success)) return LE_UINTPTR_MAX;
if((atPtr < fStart) ||
(hasBounds() && (atPtr > fStart+fLength))) {
LE_DEBUG_TR3("ptrToOffset args out of range: %p", atPtr, 0);
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
return LE_UINTPTR_MAX;
}
return ((const le_uint8*)atPtr)-fStart;
}
/**
* Clamp down the length, for range checking.
*/
size_t contractLength(size_t newLength) {
if(fLength!=LE_UINTPTR_MAX&&newLength>0&&newLength<=fLength) {
fLength = newLength;
}
return fLength;
}
/**
* Throw an error if offset+length off end
*/
public:
size_t verifyLength(size_t offset, size_t length, LEErrorCode &success) {
if(isValid()&&
LE_SUCCESS(success) &&
fLength!=LE_UINTPTR_MAX && length!=LE_UINTPTR_MAX && offset!=LE_UINTPTR_MAX &&
(offset+length)>fLength) {
LE_DEBUG_TR3("verifyLength failed (%p) %d",NULL, offset+length);
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
#if LE_ASSERT_BAD_FONT
fprintf(stderr, "offset=%lu, len=%lu, would be at %p, (%lu) off end. End at %p\n", offset,length, fStart+offset+length, (offset+length-fLength), (offset+length-fLength)+fStart);
#endif
}
return fLength;
}
/**
* Change parent link to another
*/
LETableReference &reparent(const LETableReference &base) {
fParent = &base;
return *this;
}
/**
* remove parent link. Factory functions should do this.
*/
void orphan(void) {
fParent=NULL;
}
protected:
const LEFontInstance* fFont;
LETag fTag;
const LETableReference *fParent;
const le_uint8 *fStart; // keep as 8 bit internally, for pointer math
size_t fLength;
void loadTable(LEErrorCode &success) {
if(LE_SUCCESS(success)) {
fStart = (const le_uint8*)(fFont->getFontTable(fTag, fLength)); // note - a null table is not an error.
}
}
void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
fFont = NULL;
fTag = kQuestionmarkTableTag;
fParent = NULL;
fStart = (const le_uint8*)data;
fLength = length;
}
};
template<class T>
class LETableVarSizer {
public:
inline static size_t getSize();
};
// base definition- could override for adjustments
template<class T> inline
size_t LETableVarSizer<T>::getSize() {
return sizeof(T);
}
/**
* \def LE_VAR_ARRAY
* @param x Type (T)
* @param y some member that is of length ANY_NUMBER
* Call this after defining a class, for example:
* LE_VAR_ARRAY(FeatureListTable,featureRecordArray)
* this is roughly equivalent to:
* template<> inline size_t LETableVarSizer<FeatureListTable>::getSize() { return sizeof(FeatureListTable) - (sizeof(le_uint16)*ANY_NUMBER); }
* it's a specialization that informs the LETableReference subclasses to NOT include the variable array in the size.
* dereferencing NULL is valid here because we never actually dereference it, just inside sizeof.
*/
#define LE_VAR_ARRAY(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return sizeof(x) - (sizeof(((const x*)0)->y)); }
/**
* \def LE_CORRECT_SIZE
* @param x type (T)
* @param y fixed size for T
*/
#define LE_CORRECT_SIZE(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return y; }
/**
* Open a new entry based on an existing table
*/
/**
* \def LE_UNBOUNDED_ARRAY
* define an array with no *known* bound. Will trim to available size.
* @internal
*/
#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX
template<class T>
class LEReferenceToArrayOf : public LETableReference {
public:
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
: LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO by offset")
if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
}
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
}
if(LE_FAILURE(success)) {
fCount=0;
clear();
}
}
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
: LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO")
if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
}
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
}
if(LE_FAILURE(success)) clear();
}
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count)
: LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO")
if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
}
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
}
if(LE_FAILURE(success)) clear();
}
LEReferenceToArrayOf() :LETableReference(), fCount(0) {}
le_uint32 getCount() const { return fCount; }
using LETableReference::getAlias;
const T *getAlias(le_uint32 i, LEErrorCode &success) const {
return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success)));
}
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
const T& getObject(le_uint32 i, LEErrorCode &success) const {
return *getAlias(i,success);
}
const T& operator()(le_uint32 i, LEErrorCode &success) const {
return *getAlias(i,success);
}
size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const {
if(LE_SUCCESS(success)&&i<getCount()) {
return LETableVarSizer<T>::getSize()*i;
} else {
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
}
return 0;
}
LEReferenceToArrayOf<T> &reparent(const LETableReference &base) {
fParent = &base;
return *this;
}
LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
LE_TRACE_TR("INFO: null RTAO")
}
private:
le_uint32 fCount;
};
template<class T>
class LEReferenceTo : public LETableReference {
public:
/**
* open a sub reference.
* @param parent parent reference
* @param success error status
* @param atPtr location of reference - if NULL, will be at offset zero (i.e. downcast of parent). Otherwise must be a pointer within parent's bounds.
*/
LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr)
: LETableReference(parent, parent.ptrToOffset(atPtr, success), LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
/**
* ptr plus offset
*/
LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr, size_t offset)
: LETableReference(parent, parent.ptrToOffset(atPtr, success)+offset, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
LEReferenceTo(const LETableReference &parent, LEErrorCode &success, size_t offset)
: LETableReference(parent, offset, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
: LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
: LETableReference(font, tableTag, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
LEReferenceTo() : LETableReference(NULL) {}
LEReferenceTo<T>& operator=(const T* other) {
setRaw(other);
return *this;
}
LEReferenceTo<T> &reparent(const LETableReference &base) {
fParent = &base;
return *this;
}
/**
* roll forward by one <T> size.
* same as addOffset(LETableVarSizer<T>::getSize(),success)
*/
void addObject(LEErrorCode &success) {
addOffset(LETableVarSizer<T>::getSize(), success);
}
void addObject(size_t count, LEErrorCode &success) {
addOffset(LETableVarSizer<T>::getSize()*count, success);
}
const T *operator->() const { return getAlias(); }
const T *getAlias() const { return (const T*)fStart; }
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
};
U_NAMESPACE_END
#endif
#endif

View file

@ -271,6 +271,38 @@ typedef struct LEPoint LEPoint;
#ifndef U_HIDE_INTERNAL_API
#ifndef LE_ASSERT_BAD_FONT
#define LE_ASSERT_BAD_FONT 0
#endif
#if LE_ASSERT_BAD_FONT
#include <stdio.h>
#define LE_DEBUG_BAD_FONT(x) fprintf(stderr,"%s:%d: BAD FONT: %s\n", __FILE__, __LINE__, (x));
#else
#define LE_DEBUG_BAD_FONT(x)
#endif
/**
* Max value representable by a uintptr
*/
#ifndef UINT32_MAX
#define LE_UINT32_MAX 0xFFFFFFFFU
#else
#define LE_UINT32_MAX UINT32_MAX
#endif
#ifndef UINTPTR_MAX
#define LE_UINTPTR_MAX LE_UINT32_MAX
#else
#define LE_UINTPTR_MAX UINTPTR_MAX
#endif
/**
* Range check for overflow
*/
#define LE_RANGE_CHECK(type, count, ptrfn) (( (LE_UINTPTR_MAX / sizeof(type)) < count ) ? NULL : (ptrfn))
/**
* A convenience macro to get the length of an array.
*
@ -292,7 +324,7 @@ typedef struct LEPoint LEPoint;
*
* @internal
*/
#define LE_NEW_ARRAY(type, count) (type *) uprv_malloc((count) * sizeof(type))
#define LE_NEW_ARRAY(type, count) (type *) LE_RANGE_CHECK(type,count,uprv_malloc((count) * sizeof(type)))
/**
* Re-allocate an array of basic types. This is used to isolate the rest of
@ -336,7 +368,7 @@ typedef struct LEPoint LEPoint;
*
* @internal
*/
#define LE_NEW_ARRAY(type, count) (type *) malloc((count) * sizeof(type))
#define LE_NEW_ARRAY(type, count) LE_RANGE_CHECK(type,count,(type *) malloc((count) * sizeof(type)))
/**
* Re-allocate an array of basic types. This is used to isolate the rest of
@ -636,6 +668,8 @@ enum LEFeatureENUMs {
* @}
*/
#define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */
/**
* Error codes returned by the LayoutEngine.
*
@ -681,4 +715,5 @@ typedef enum LEErrorCode LEErrorCode;
*/
#define LE_FAILURE(code) (U_FAILURE((UErrorCode)code))
#endif

View file

@ -94,21 +94,21 @@ CharSubstitutionFilter::~CharSubstitutionFilter()
class CanonMarkFilter : public UMemory, public LEGlyphFilter
{
private:
const GlyphClassDefinitionTable *classDefTable;
const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
public:
CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const;
};
CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
: classDefTable(gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success))
{
classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
}
CanonMarkFilter::~CanonMarkFilter()
@ -118,9 +118,10 @@ CanonMarkFilter::~CanonMarkFilter()
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
{
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
return glyphClass != 0;
LEErrorCode success = LE_NO_ERROR;
le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
if(LE_FAILURE(success)) return false;
return glyphClass != 0;
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
@ -205,20 +206,20 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
return 0;
}
const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable);
LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
le_int32 i, dir = 1, out = 0, outCharCount = count;
if (canonGSUBTable->coversScript(scriptTag)) {
if (canonGSUBTable->coversScript(canonGSUBTable,scriptTag, success) || LE_SUCCESS(success)) {
CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
if (substitutionFilter == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
const LEUnicode *inChars = &chars[offset];
LEUnicode *reordered = NULL;
const LEUnicode *inChars = &chars[offset];
LEUnicode *reordered = NULL;
LEGlyphStorage fakeGlyphStorage;
fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success);
@ -228,20 +229,20 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
return 0;
}
// This is the cheapest way to get mark reordering only for Hebrew.
// We could just do the mark reordering for all scripts, but most
// of them probably don't need it...
if (fScriptCode == hebrScriptCode) {
reordered = LE_NEW_ARRAY(LEUnicode, count);
if (reordered == NULL) {
delete substitutionFilter;
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
inChars = reordered;
// This is the cheapest way to get mark reordering only for Hebrew.
// We could just do the mark reordering for all scripts, but most
// of them probably don't need it...
if (fScriptCode == hebrScriptCode) {
reordered = LE_NEW_ARRAY(LEUnicode, count);
if (reordered == NULL) {
delete substitutionFilter;
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
inChars = reordered;
}
fakeGlyphStorage.allocateAuxData(success);
@ -261,11 +262,11 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
fakeGlyphStorage.setAuxData(out, canonFeatures, success);
}
if (reordered != NULL) {
LE_DELETE_ARRAY(reordered);
}
if (reordered != NULL) {
LE_DELETE_ARRAY(reordered);
}
outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
if (LE_FAILURE(success)) {
delete substitutionFilter;
@ -366,16 +367,16 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset
return;
}
GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
CanonMarkFilter filter(gdefTable);
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen);
CanonMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
if (fTypoFlags & 0x1) { /* kerning enabled */
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
KernTable kt(fFontInstance, getFontTable(kernTableTag));
kt.process(glyphStorage);
if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(kernTable, success);
kt.process(glyphStorage, success);
}
// default is no adjustments
@ -460,9 +461,9 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success);
}
const void *LayoutEngine::getFontTable(LETag tableTag) const
const void *LayoutEngine::getFontTable(LETag tableTag, size_t &length) const
{
return fFontInstance->getFontTable(tableTag);
return fFontInstance->getFontTable(tableTag, length);
}
void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
@ -509,13 +510,16 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_
void LayoutEngine::reset()
{
if(fGlyphStorage!=NULL) {
fGlyphStorage->reset();
fGlyphStorage = NULL;
}
}
LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
{
// 3 -> kerning and ligatures
return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, 3, success);
//kerning and ligatures - by default
return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, LE_DEFAULT_FEATURE_FLAG, success);
}
LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
@ -528,19 +532,19 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
return NULL;
}
const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag);
LEReferenceTo<GlyphSubstitutionTableHeader> gsubTable(fontInstance,gsubTableTag,success);
LayoutEngine *result = NULL;
LETag scriptTag = 0x00000000;
LETag languageTag = 0x00000000;
LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
// Right now, only invoke V2 processing for Devanagari. TODO: Allow more V2 scripts as they are
// properly tested.
if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) {
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
}
else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
if ( v2ScriptTag == dev2ScriptTag && gsubTable.isValid() && gsubTable->coversScript(gsubTable, v2ScriptTag, success )) {
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
}
else if (gsubTable.isValid() && gsubTable->coversScript(gsubTable, scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode), success)) {
switch (scriptCode) {
case bengScriptCode:
case devaScriptCode:
@ -576,10 +580,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case janLanguageCode:
case zhtLanguageCode:
case zhsLanguageCode:
if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) {
if (gsubTable->coversScriptAndLanguage(gsubTable, scriptTag, languageTag, success, TRUE)) {
result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
}
}
// note: falling through to default case.
default:
@ -603,12 +607,12 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
}
} else {
MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag);
if (morxTable != NULL) {
if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) {
result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
} else {
const MorphTableHeader *mortTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
if (mortTable != NULL) { // mort
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
if (LE_SUCCESS(success) && mortTable.isValid() && SWAPL(mortTable->version)==0x00010000) { // mort
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
} else {
switch (scriptCode) {
case bengScriptCode:

View file

@ -252,12 +252,18 @@ protected:
* some other way must override this method.
*
* @param tableTag - the four byte table tag.
* @param length - length to use
*
* @return the address of the table.
*
* @internal
*/
virtual const void *getFontTable(LETag tableTag) const;
virtual const void *getFontTable(LETag tableTag, size_t &length) const;
/**
* @deprecated
*/
virtual const void *getFontTable(LETag tableTag) const { size_t ignored; return getFontTable(tableTag, ignored); }
/**
* This method does character to glyph mapping. The default implementation

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -22,15 +22,15 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor)
LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
: StateTableProcessor(morphSubtableHeader)
LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success), ligatureSubstitutionHeader(morphSubtableHeader, success)
{
ligatureSubstitutionHeader = (const LigatureSubstitutionHeader *) morphSubtableHeader;
if(LE_FAILURE(success)) return;
ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset);
componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset);
ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset);
entryTable = (const LigatureSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
}
LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
@ -44,7 +44,9 @@ void LigatureSubstitutionProcessor::beginStateTable()
ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{
const LigatureSubstitutionStateEntry *entry = &entryTable[index];
LEErrorCode success = LE_NO_ERROR;
const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
@ -54,12 +56,16 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp
}
componentStack[m] = currGlyph;
} else if ( m == -1) {
// bad font- skip this glyph.
currGlyph++;
return newState;
}
ByteOffset actionOffset = flags & lsfActionOffsetMask;
if (actionOffset != 0) {
const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset);
LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
LigatureActionEntry action;
le_int32 offset, i = 0;
le_int32 stack[nComponents];
@ -68,7 +74,8 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp
do {
le_uint32 componentGlyph = componentStack[m--];
action = SWAPL(*ap++);
action = SWAPL(*ap.getAlias());
ap.addObject(success); // ap++
if (m < 0) {
m = nComponents - 1;
@ -76,29 +83,48 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp
offset = action & lafComponentOffsetMask;
if (offset != 0) {
const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask));
LEReferenceToArrayOf<le_int16> offsetTable(stHeader, success, 2 * SignExtend(offset, lafComponentOffsetMask), LE_UNBOUNDED_ARRAY);
i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);
if(LE_FAILURE(success)) {
currGlyph++;
LE_DEBUG_BAD_FONT("off end of ligature substitution header");
return newState; // get out! bad font
}
if(componentGlyph > glyphStorage.getGlyphCount()) {
LE_DEBUG_BAD_FONT("preposterous componentGlyph");
currGlyph++;
return newState; // get out! bad font
}
i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));
if (action & (lafLast | lafStore)) {
const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i);
TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset);
LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i);
TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias());
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
stack[++mm] = componentGlyph;
i = 0;
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
if(mm==nComponents) {
LE_DEBUG_BAD_FONT("exceeded nComponents");
mm--; // don't overrun the stack.
}
stack[++mm] = componentGlyph;
i = 0;
} else {
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
}
}
} while (!(action & lafLast));
#if LE_ASSERT_BAD_FONT
if(m<0) {
LE_DEBUG_BAD_FONT("m<0")
}
#endif
} while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items
while (mm >= 0) {
if (++m >= nComponents) {
m = 0;
}
componentStack[m] = stack[mm--];
if (++m >= nComponents) {
m = 0;
}
componentStack[m] = stack[mm--];
}
}

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -33,7 +33,7 @@ public:
virtual void endStateTable();
LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~LigatureSubstitutionProcessor();
/**
@ -58,12 +58,12 @@ protected:
ByteOffset componentTableOffset;
ByteOffset ligatureTableOffset;
const LigatureSubstitutionStateEntry *entryTable;
LEReferenceToArrayOf<LigatureSubstitutionStateEntry> entryTable;
le_int32 componentStack[nComponents];
le_int16 m;
const LigatureSubstitutionHeader *ligatureSubstitutionHeader;
LEReferenceTo<LigatureSubstitutionHeader> ligatureSubstitutionHeader;
};

View file

@ -22,15 +22,18 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
: StateTableProcessor2(morphSubtableHeader)
LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader, success),
ligActionOffset(0),
ligatureSubstitutionHeader(morphSubtableHeader, success), componentOffset(0), ligatureOffset(0), entryTable()
{
ligatureSubstitutionHeader = (const LigatureSubstitutionHeader2 *) morphSubtableHeader;
if (LE_FAILURE(success)) return;
ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
entryTable = (const LigatureSubstitutionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
}
LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
@ -42,9 +45,11 @@ void LigatureSubstitutionProcessor2::beginStateTable()
m = -1;
}
le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success)
{
const LigatureSubstitutionStateEntry2 *entry = &entryTable[index];
const LigatureSubstitutionStateEntry2 *entry = entryTable.getAlias(index, success);
if(LE_FAILURE(success)) return 0;
le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
le_uint16 flags = SWAPW(entry->entryFlags);
le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
@ -54,24 +59,35 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
m = 0;
}
componentStack[m] = currGlyph;
} else if ( m == -1) {
// bad font- skip this glyph.
//LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)")
currGlyph+= dir;
return nextStateIndex;
}
ByteOffset actionOffset = flags & lsfPerformAction;
if (actionOffset != 0) {
const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + ligActionOffset) + ligActionIndex;
const TTGlyphID *ligatureTable = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + ligatureOffset);
LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
ap.addObject(ligActionIndex - 1, success); // index offset ( one before the actual start, because we will pre-increment)
LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
LigatureActionEntry action;
le_int32 offset, i = 0;
le_int32 stack[nComponents];
le_int16 mm = -1;
const le_uint16 *componentTable = (const le_uint16 *)((char *) &ligatureSubstitutionHeader->stHeader + componentOffset);
LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
if(LE_FAILURE(success)) {
currGlyph+= dir;
return nextStateIndex; // get out! bad font
}
do {
le_uint32 componentGlyph = componentStack[m--]; // pop off
action = SWAPL(*ap++);
ap.addObject(success);
action = SWAPL(*ap.getAlias());
if (m < 0) {
m = nComponents - 1;
@ -79,19 +95,32 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
offset = action & lafComponentOffsetMask;
if (offset != 0) {
i += SWAPW(componentTable[LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask))]);
if(componentGlyph > glyphStorage.getGlyphCount()) {
LE_DEBUG_BAD_FONT("preposterous componentGlyph");
currGlyph+= dir;
return nextStateIndex; // get out! bad font
}
i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
if (action & (lafLast | lafStore)) {
TTGlyphID ligatureGlyph = SWAPW(ligatureTable[i]);
TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
if(mm==nComponents) {
LE_DEBUG_BAD_FONT("exceeded nComponents");
mm--; // don't overrun the stack.
}
stack[++mm] = componentGlyph;
i = 0;
} else {
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
}
}
} while (!(action & lafLast));
#if LE_ASSERT_BAD_FONT
if(m<0) {
LE_DEBUG_BAD_FONT("m<0")
}
#endif
} while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items
while (mm >= 0) {
if (++m >= nComponents) {

View file

@ -29,11 +29,12 @@ class LigatureSubstitutionProcessor2 : public StateTableProcessor2
public:
virtual void beginStateTable();
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
EntryTableIndex2 index, LEErrorCode &success);
virtual void endStateTable();
LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~LigatureSubstitutionProcessor2();
/**
@ -58,12 +59,12 @@ protected:
le_uint32 componentOffset;
le_uint32 ligatureOffset;
const LigatureSubstitutionStateEntry2 *entryTable;
LEReferenceToArrayOf<LigatureSubstitutionStateEntry2> entryTable;
le_int32 componentStack[nComponents];
le_int16 m;
const LigatureSubstitutionHeader2 *ligatureSubstitutionHeader;
const LEReferenceTo<LigatureSubstitutionHeader2> ligatureSubstitutionHeader;
};

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -13,10 +13,10 @@
U_NAMESPACE_BEGIN
le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
{
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) {
Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -25,6 +25,7 @@ struct LigatureSetTable
le_uint16 ligatureCount;
Offset ligatureTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(LigatureSetTable, ligatureTableOffsetArray)
struct LigatureTable
{
@ -32,14 +33,16 @@ struct LigatureTable
le_uint16 compCount;
TTGlyphID componentArray[ANY_NUMBER];
};
LE_VAR_ARRAY(LigatureTable, componentArray)
struct LigatureSubstitutionSubtable : GlyphSubstitutionSubtable
{
le_uint16 ligSetCount;
Offset ligSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
le_uint32 process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
};
LE_VAR_ARRAY(LigatureSubstitutionSubtable, ligSetTableOffsetArray)
U_NAMESPACE_END
#endif

View file

@ -19,7 +19,7 @@
U_NAMESPACE_BEGIN
le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator,
le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
@ -32,7 +32,7 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
le_uint32 delta;
for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
@ -47,7 +47,7 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
}
le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
@ -64,13 +64,13 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
rightToLeft, 0, 0, glyphDefinitionTableHeader);
le_int32 newGlyphCount = glyphCount;
for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
le_uint16 lookup = lookupOrderArray[order];
FeatureMask selectMask = lookupSelectArray[lookup];
if (selectMask != 0) {
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
if (!lookupTable) {
const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
continue;
}
le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
@ -98,8 +98,8 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt
return 0;
}
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
if (lookupTable == NULL) {
const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookupTableIndex, success);
if (!lookupTable.isValid()) {
success = LE_INTERNAL_ERROR;
return 0;
}
@ -110,33 +110,35 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt
return delta;
}
le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order)
le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success)
{
le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0;
le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0;
le_int32 store = order;
LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount);
for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
if (lookupListIndex >= lookupSelectCount) {
continue;
}
lookupSelectArray[lookupListIndex] |= featureMask;
lookupOrderArray[store++] = lookupListIndex;
for (le_uint16 lookup = 0; LE_SUCCESS(success) && lookup < lookupCount; lookup += 1) {
le_uint16 lookupListIndex = SWAPW(lookupListIndexArray.getObject(lookup,success));
if (lookupListIndex >= lookupSelectCount) {
continue;
}
lookupSelectArray[lookupListIndex] |= featureMask;
lookupOrderArray[store++] = lookupListIndex;
}
return store - order;
}
LookupProcessor::LookupProcessor(const char *baseAddress,
LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures,
LEErrorCode& success)
: lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0),
lookupOrderArray(NULL), lookupOrderCount(0)
: lookupListTable(), featureListTable(), lookupSelectArray(NULL), lookupSelectCount(0),
lookupOrderArray(NULL), lookupOrderCount(0), fReference(baseAddress)
{
const ScriptListTable *scriptListTable = NULL;
const LangSysTable *langSysTable = NULL;
LEReferenceTo<ScriptListTable> scriptListTable;
LEReferenceTo<LangSysTable> langSysTable;
le_uint16 featureCount = 0;
le_uint16 lookupListCount = 0;
le_uint16 requiredFeatureIndex;
@ -146,29 +148,33 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
}
if (scriptListOffset != 0) {
scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
scriptListTable = LEReferenceTo<ScriptListTable>(baseAddress, success, scriptListOffset);
langSysTable = scriptListTable->findLanguage(scriptListTable, scriptTag, languageTag, success);
if (langSysTable != 0) {
featureCount = SWAPW(langSysTable->featureCount);
}
if (langSysTable.isValid() && LE_SUCCESS(success)) {
featureCount = SWAPW(langSysTable->featureCount);
}
}
if (featureListOffset != 0) {
featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset);
featureListTable = LEReferenceTo<FeatureListTable>(baseAddress, success, featureListOffset);
}
if (lookupListOffset != 0) {
lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset);
lookupListTable = LEReferenceTo<LookupListTable>(baseAddress,success, lookupListOffset);
if(LE_SUCCESS(success) && lookupListTable.isValid()) {
lookupListCount = SWAPW(lookupListTable->lookupCount);
}
}
if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL ||
if (langSysTable.isEmpty() || featureListTable.isEmpty() || lookupListTable.isEmpty() ||
featureCount == 0 || lookupListCount == 0) {
return;
}
requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
if(langSysTable.isValid()) {
requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
}
lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
if (lookupSelectArray == NULL) {
@ -182,35 +188,39 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
lookupSelectCount = lookupListCount;
le_int32 count, order = 0;
le_int32 featureReferences = 0;
const FeatureTable *featureTable = NULL;
le_uint32 featureReferences = 0;
LEReferenceTo<FeatureTable> featureTable;
LETag featureTag;
const FeatureTable *requiredFeatureTable = NULL;
LEReferenceTo<FeatureTable> requiredFeatureTable;
LETag requiredFeatureTag = 0x00000000U;
// Count the total number of lookups referenced by all features. This will
// be the maximum number of entries in the lookupOrderArray. We can't use
// lookupListCount because some lookups might be referenced by more than
// one feature.
for (le_int32 feature = 0; feature < featureCount; feature += 1) {
le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
if(featureListTable.isValid() && LE_SUCCESS(success)) {
LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
if (!featureTable) {
continue;
for (le_uint32 feature = 0; LE_SUCCESS(success)&&(feature < featureCount); feature += 1) {
le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature, success));
featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
if (!featureTable.isValid() || LE_FAILURE(success)) {
continue;
}
featureReferences += SWAPW(featureTable->lookupCount);
}
}
if (!featureTable) {
if (!featureTable.isValid() || LE_FAILURE(success)) {
success = LE_INTERNAL_ERROR;
return;
}
if (requiredFeatureIndex != 0xFFFF) {
requiredFeatureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &requiredFeatureTag);
featureReferences += SWAPW(featureTable->lookupCount);
requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success);
featureReferences += SWAPW(featureTable->lookupCount);
}
lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
@ -225,7 +235,7 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
// If this is the required feature, add its lookups
if (requiredFeatureTag == fm.tag) {
count += selectLookups(requiredFeatureTable, fm.mask, order);
count += selectLookups(requiredFeatureTable, fm.mask, order, success);
}
if (orderFeatures) {
@ -235,7 +245,8 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
}
for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success));
// don't add the required feature to the list more than once...
// TODO: Do we need this check? (Spec. says required feature won't be in feature list...)
@ -243,10 +254,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
continue;
}
featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
if (featureTag == fm.tag) {
count += selectLookups(featureTable, fm.mask, order + count);
count += selectLookups(featureTable, fm.mask, order + count, success);
}
}
@ -255,9 +266,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
}
order += count;
} else {
for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
} else if(langSysTable.isValid()) {
LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
for (le_uint16 feature = 0; LE_SUCCESS(success)&& (feature < featureCount); feature += 1) {
le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success));
// don't add the required feature to the list more than once...
// NOTE: This check is commented out because the spec. says that
@ -269,10 +281,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
}
#endif
featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
if (featureTag == fm.tag) {
order += selectLookups(featureTable, fm.mask, order);
order += selectLookups(featureTable, fm.mask, order, success);
}
}
}

View file

@ -1,7 +1,7 @@
/*
* %W% %E%
*
* (C) Copyright IBM Corp. 1998-2011 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -16,6 +16,7 @@
#include "LETypes.h"
#include "LEFontInstance.h"
#include "OpenTypeTables.h"
#include "LETableReference.h"
//#include "Lookups.h"
//#include "Features.h"
@ -34,19 +35,21 @@ struct LookupTable;
class LookupProcessor : public UMemory {
public:
le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 subtableType,
virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 subtableType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const = 0;
virtual ~LookupProcessor();
const LETableReference &getReference() const { return fReference; }
protected:
LookupProcessor(const char *baseAddress,
LookupProcessor(const LETableReference &baseAddress,
Offset scriptListOffset,
Offset featureListOffset,
Offset lookupListOffset,
@ -59,10 +62,10 @@ protected:
LookupProcessor();
le_int32 selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order);
le_int32 selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success);
const LookupListTable *lookupListTable;
const FeatureListTable *featureListTable;
LEReferenceTo<LookupListTable> lookupListTable;
LEReferenceTo<FeatureListTable> featureListTable;
FeatureMask *lookupSelectArray;
le_uint32 lookupSelectCount;
@ -70,6 +73,8 @@ protected:
le_uint16 *lookupOrderArray;
le_uint32 lookupOrderCount;
LETableReference fReference;
private:
LookupProcessor(const LookupProcessor &other); // forbid copying of this class

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -24,22 +24,26 @@ U_NAMESPACE_BEGIN
of the derived classes, and implement it in the others by casting
the "this" pointer to the type that has the implementation.
*/
const LookupSegment *BinarySearchLookupTable::lookupSegment(const LookupSegment *segments, LEGlyphID glyph) const
const LookupSegment *BinarySearchLookupTable::lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const
{
le_int16 unity = SWAPW(unitSize);
le_int16 probe = SWAPW(searchRange);
le_int16 extra = SWAPW(rangeShift);
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
const LookupSegment *entry = segments;
const LookupSegment *trial = (const LookupSegment *) ((char *) entry + extra);
LEReferenceTo<LookupSegment> entry(base, success, segments);
LEReferenceTo<LookupSegment> trial(entry, success, extra);
if(LE_FAILURE(success)) return NULL;
if (SWAPW(trial->lastGlyph) <= ttGlyph) {
entry = trial;
}
while (probe > unity) {
while (probe > unity && LE_SUCCESS(success)) {
probe >>= 1;
trial = (const LookupSegment *) ((char *) entry + probe);
trial = entry; // copy
trial.addOffset(probe, success);
if (SWAPW(trial->lastGlyph) <= ttGlyph) {
entry = trial;
@ -47,28 +51,29 @@ const LookupSegment *BinarySearchLookupTable::lookupSegment(const LookupSegment
}
if (SWAPW(entry->firstGlyph) <= ttGlyph) {
return entry;
return entry.getAlias();
}
return NULL;
}
const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const
const LookupSingle *BinarySearchLookupTable::lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const
{
le_int16 unity = SWAPW(unitSize);
le_int16 probe = SWAPW(searchRange);
le_int16 extra = SWAPW(rangeShift);
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
const LookupSingle *entry = entries;
const LookupSingle *trial = (const LookupSingle *) ((char *) entry + extra);
LEReferenceTo<LookupSingle> entry(base, success, entries);
LEReferenceTo<LookupSingle> trial(entry, success, extra);
if (SWAPW(trial->glyph) <= ttGlyph) {
entry = trial;
}
while (probe > unity) {
while (probe > unity && LE_SUCCESS(success)) {
probe >>= 1;
trial = (const LookupSingle *) ((char *) entry + probe);
trial = entry;
trial.addOffset(probe, success);
if (SWAPW(trial->glyph) <= ttGlyph) {
entry = trial;
@ -76,7 +81,7 @@ const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *en
}
if (SWAPW(entry->glyph) == ttGlyph) {
return entry;
return entry.getAlias();
}
return NULL;

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -14,6 +14,7 @@
#include "LETypes.h"
#include "LayoutTables.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN
@ -54,30 +55,34 @@ struct BinarySearchLookupTable : LookupTable
le_int16 entrySelector;
le_int16 rangeShift;
const LookupSegment *lookupSegment(const LookupSegment *segments, LEGlyphID glyph) const;
const LookupSegment *lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const;
const LookupSingle *lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const;
const LookupSingle *lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const;
};
struct SimpleArrayLookupTable : LookupTable
{
LookupValue valueArray[ANY_NUMBER];
};
LE_VAR_ARRAY(SimpleArrayLookupTable, valueArray)
struct SegmentSingleLookupTable : BinarySearchLookupTable
{
LookupSegment segments[ANY_NUMBER];
};
LE_VAR_ARRAY(SegmentSingleLookupTable, segments)
struct SegmentArrayLookupTable : BinarySearchLookupTable
{
LookupSegment segments[ANY_NUMBER];
};
LE_VAR_ARRAY(SegmentArrayLookupTable, segments)
struct SingleTableLookupTable : BinarySearchLookupTable
{
LookupSingle entries[ANY_NUMBER];
};
LE_VAR_ARRAY(SingleTableLookupTable, entries)
struct TrimmedArrayLookupTable : LookupTable
{
@ -85,6 +90,7 @@ struct TrimmedArrayLookupTable : LookupTable
TTGlyphID glyphCount;
LookupValue valueArray[ANY_NUMBER];
};
LE_VAR_ARRAY(TrimmedArrayLookupTable, valueArray)
U_NAMESPACE_END
#endif

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -12,33 +12,35 @@
U_NAMESPACE_BEGIN
const LookupTable *LookupListTable::getLookupTable(le_uint16 lookupTableIndex) const
const LEReferenceTo<LookupTable> LookupListTable::getLookupTable(const LEReferenceTo<LookupListTable> &base, le_uint16 lookupTableIndex, LEErrorCode &success) const
{
if (lookupTableIndex >= SWAPW(lookupCount)) {
return 0;
}
LEReferenceToArrayOf<Offset> lookupTableOffsetArrayRef(base, success, (const Offset*)&lookupTableOffsetArray, SWAPW(lookupCount));
Offset lookupTableOffset = lookupTableOffsetArray[lookupTableIndex];
return (const LookupTable *) ((char *) this + SWAPW(lookupTableOffset));
if(LE_FAILURE(success) || lookupTableIndex>lookupTableOffsetArrayRef.getCount()) {
return LEReferenceTo<LookupTable>();
} else {
return LEReferenceTo<LookupTable>(base, success, SWAPW(lookupTableOffsetArrayRef.getObject(lookupTableIndex, success)));
}
}
const LookupSubtable *LookupTable::getLookupSubtable(le_uint16 subtableIndex) const
const LEReferenceTo<LookupSubtable> LookupTable::getLookupSubtable(const LEReferenceTo<LookupTable> &base, le_uint16 subtableIndex, LEErrorCode &success) const
{
if (subtableIndex >= SWAPW(subTableCount)) {
return 0;
}
LEReferenceToArrayOf<Offset> subTableOffsetArrayRef(base, success, (const Offset*)&subTableOffsetArray, SWAPW(subTableCount));
Offset subtableOffset = subTableOffsetArray[subtableIndex];
return (const LookupSubtable *) ((char *) this + SWAPW(subtableOffset));
if(LE_FAILURE(success) || subtableIndex>subTableOffsetArrayRef.getCount()) {
return LEReferenceTo<LookupSubtable>();
} else {
return LEReferenceTo<LookupSubtable>(base, success, SWAPW(subTableOffsetArrayRef.getObject(subtableIndex, success)));
}
}
le_int32 LookupSubtable::getGlyphCoverage(Offset tableOffset, LEGlyphID glyphID) const
le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const
{
const CoverageTable *coverageTable = (const CoverageTable *) ((char *) this + SWAPW(tableOffset));
const LEReferenceTo<CoverageTable> coverageTable(base, success, SWAPW(tableOffset));
return coverageTable->getGlyphCoverage(glyphID);
if(LE_FAILURE(success)) return 0;
return coverageTable->getGlyphCoverage(glyphID);
}
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -33,9 +33,14 @@ struct LookupSubtable
le_uint16 subtableFormat;
Offset coverageTableOffset;
inline le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
inline le_int32 getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_int32 getGlyphCoverage(Offset tableOffset, LEGlyphID glyphID) const;
le_int32 getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const;
// convenience
inline le_int32 getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
inline le_int32 getGlyphCoverage(const LETableReference &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const;
};
struct LookupTable
@ -45,20 +50,32 @@ struct LookupTable
le_uint16 subTableCount;
Offset subTableOffsetArray[ANY_NUMBER];
const LookupSubtable *getLookupSubtable(le_uint16 subtableIndex) const;
const LEReferenceTo<LookupSubtable> getLookupSubtable(const LEReferenceTo<LookupTable> &base, le_uint16 subtableIndex, LEErrorCode &success) const;
};
LE_VAR_ARRAY(LookupTable, subTableOffsetArray)
struct LookupListTable
{
le_uint16 lookupCount;
Offset lookupTableOffsetArray[ANY_NUMBER];
const LookupTable *getLookupTable(le_uint16 lookupTableIndex) const;
const LEReferenceTo<LookupTable> getLookupTable(const LEReferenceTo<LookupListTable> &base, le_uint16 lookupTableIndex, LEErrorCode &success) const;
};
LE_VAR_ARRAY(LookupListTable, lookupTableOffsetArray)
inline le_int32 LookupSubtable::getGlyphCoverage(LEGlyphID glyphID) const
inline le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, LEGlyphID glyphID, LEErrorCode &success) const
{
return getGlyphCoverage(coverageTableOffset, glyphID);
return getGlyphCoverage(base, coverageTableOffset, glyphID, success);
}
inline le_int32 LookupSubtable::getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const {
LEReferenceTo<LookupSubtable> thisRef(base, success, this);
return getGlyphCoverage(thisRef, glyphID, success);
}
inline le_int32 LookupSubtable::getGlyphCoverage(const LETableReference &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const {
LEReferenceTo<LookupSubtable> thisRef(base, success, this);
return getGlyphCoverage(thisRef, tableOffset, glyphID, success);
}
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -32,6 +32,7 @@ struct MarkArray
le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor) const;
};
LE_VAR_ARRAY(MarkArray, markRecordArray)
U_NAMESPACE_END
#endif

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -26,10 +26,10 @@ LEGlyphID MarkToBasePositioningSubtable::findBaseGlyph(GlyphIterator *glyphItera
return 0xFFFF;
}
le_int32 MarkToBasePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{
LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
if (markCoverage < 0) {
// markGlyph isn't a covered mark glyph
@ -50,7 +50,7 @@ le_int32 MarkToBasePositioningSubtable::process(GlyphIterator *glyphIterator, co
// FIXME: We probably don't want to find a base glyph before a previous ligature...
GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
le_int32 baseCoverage = getBaseCoverage((LEGlyphID) baseGlyph);
le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success);
const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset));
le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -23,7 +23,7 @@ U_NAMESPACE_BEGIN
struct MarkToBasePositioningSubtable : AttachmentPositioningSubtable
{
le_int32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_int32 process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
LEGlyphID findBaseGlyph(GlyphIterator *glyphIterator) const;
};
@ -31,12 +31,14 @@ struct BaseRecord
{
Offset baseAnchorTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(BaseRecord, baseAnchorTableOffsetArray)
struct BaseArray
{
le_int16 baseRecordCount;
BaseRecord baseRecordArray[ANY_NUMBER];
};
LE_VAR_ARRAY(BaseArray, baseRecordArray)
U_NAMESPACE_END
#endif

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -25,10 +25,10 @@ LEGlyphID MarkToLigaturePositioningSubtable::findLigatureGlyph(GlyphIterator *gl
return 0xFFFF;
}
le_int32 MarkToLigaturePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{
LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
if (markCoverage < 0) {
// markGlyph isn't a covered mark glyph
@ -49,7 +49,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(GlyphIterator *glyphIterator
// FIXME: we probably don't want to find a ligature before a previous base glyph...
GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
le_int32 ligatureCoverage = getBaseCoverage((LEGlyphID) ligatureGlyph);
le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success);
const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset));
le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -23,7 +23,7 @@ U_NAMESPACE_BEGIN
struct MarkToLigaturePositioningSubtable : AttachmentPositioningSubtable
{
le_int32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_int32 process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
LEGlyphID findLigatureGlyph(GlyphIterator *glyphIterator) const;
};
@ -31,18 +31,21 @@ struct ComponentRecord
{
Offset ligatureAnchorTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(ComponentRecord, ligatureAnchorTableOffsetArray)
struct LigatureAttachTable
{
le_uint16 componentCount;
ComponentRecord componentRecordArray[ANY_NUMBER];
};
LE_VAR_ARRAY(LigatureAttachTable, componentRecordArray)
struct LigatureArray
{
le_uint16 ligatureCount;
Offset ligatureAttachTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(LigatureArray, ligatureAttachTableOffsetArray)
U_NAMESPACE_END
#endif

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -26,10 +26,10 @@ LEGlyphID MarkToMarkPositioningSubtable::findMark2Glyph(GlyphIterator *glyphIter
return 0xFFFF;
}
le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{
LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
if (markCoverage < 0) {
// markGlyph isn't a covered mark glyph
@ -49,7 +49,7 @@ le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, co
GlyphIterator mark2Iterator(*glyphIterator);
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
le_int32 mark2Coverage = getBaseCoverage((LEGlyphID) mark2Glyph);
le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success);
const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset));
le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -23,7 +23,7 @@ U_NAMESPACE_BEGIN
struct MarkToMarkPositioningSubtable : AttachmentPositioningSubtable
{
le_int32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_int32 process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
LEGlyphID findMark2Glyph(GlyphIterator *glyphIterator) const;
};
@ -31,12 +31,14 @@ struct Mark2Record
{
Offset mark2AnchorTableOffsetArray[ANY_NUMBER];
};
LE_VAR_ARRAY(Mark2Record, mark2AnchorTableOffsetArray)
struct Mark2Array
{
le_uint16 mark2RecordCount;
Mark2Record mark2RecordArray[ANY_NUMBER];
};
LE_VAR_ARRAY(Mark2Array, mark2RecordArray)
U_NAMESPACE_END
#endif

View file

@ -1,7 +1,7 @@
/*
* %W% %W%
*
* (C) Copyright IBM Corp. 1998 - 2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998 - 2013 - All Rights Reserved
*
*/
@ -20,61 +20,61 @@
U_NAMESPACE_BEGIN
void MorphTableHeader::process(LEGlyphStorage &glyphStorage) const
void MorphTableHeader::process(const LETableReference &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
{
const ChainHeader *chainHeader = chains;
le_uint32 chainCount = SWAPL(this->nChains);
le_uint32 chainCount = SWAPL(this->nChains);
LEReferenceTo<ChainHeader> chainHeader(base, success, chains); // moving header
LEReferenceToArrayOf<ChainHeader> chainHeaderArray(base, success, chains, chainCount);
le_uint32 chain;
for (chain = 0; chain < chainCount; chain += 1) {
for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain += 1) {
FeatureFlags defaultFlags = SWAPL(chainHeader->defaultFlags);
le_uint32 chainLength = SWAPL(chainHeader->chainLength);
le_int16 nFeatureEntries = SWAPW(chainHeader->nFeatureEntries);
le_int16 nSubtables = SWAPW(chainHeader->nSubtables);
const MorphSubtableHeader *subtableHeader =
(const MorphSubtableHeader *)&chainHeader->featureTable[nFeatureEntries];
LEReferenceTo<MorphSubtableHeader> subtableHeader =
LEReferenceTo<MorphSubtableHeader>(chainHeader,success, &(chainHeader->featureTable[nFeatureEntries]));
le_int16 subtable;
for (subtable = 0; subtable < nSubtables; subtable += 1) {
for (subtable = 0; LE_SUCCESS(success) && (subtable < nSubtables); subtable += 1) {
le_int16 length = SWAPW(subtableHeader->length);
SubtableCoverage coverage = SWAPW(subtableHeader->coverage);
FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
// should check coverage more carefully...
if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0) {
subtableHeader->process(glyphStorage);
if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0 && LE_SUCCESS(success)) {
subtableHeader->process(subtableHeader, glyphStorage, success);
}
subtableHeader = (const MorphSubtableHeader *) ((char *)subtableHeader + length);
subtableHeader.addOffset(length, success);
}
chainHeader = (const ChainHeader *)((char *)chainHeader + chainLength);
chainHeader.addOffset(chainLength, success);
}
}
void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const
void MorphSubtableHeader::process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
{
SubtableProcessor *processor = NULL;
switch (SWAPW(coverage) & scfTypeMask)
{
case mstIndicRearrangement:
processor = new IndicRearrangementProcessor(this);
processor = new IndicRearrangementProcessor(base, success);
break;
case mstContextualGlyphSubstitution:
processor = new ContextualGlyphSubstitutionProcessor(this);
processor = new ContextualGlyphSubstitutionProcessor(base, success);
break;
case mstLigatureSubstitution:
processor = new LigatureSubstitutionProcessor(this);
processor = new LigatureSubstitutionProcessor(base, success);
break;
case mstReservedUnused:
break;
case mstNonContextualGlyphSubstitution:
processor = NonContextualGlyphSubstitutionProcessor::createInstance(this);
processor = NonContextualGlyphSubstitutionProcessor::createInstance(base, success);
break;
/*
@ -88,8 +88,10 @@ void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const
}
if (processor != NULL) {
processor->process(glyphStorage);
delete processor;
if(LE_SUCCESS(success)) {
processor->process(glyphStorage, success);
}
delete processor;
}
}

View file

@ -14,6 +14,7 @@
#include "LETypes.h"
#include "LayoutTables.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN
@ -40,6 +41,7 @@ struct ChainHeader
le_int16 nSubtables;
FeatureTableEntry featureTable[ANY_NUMBER];
};
LE_VAR_ARRAY(ChainHeader, featureTable)
struct MorphTableHeader
{
@ -47,8 +49,9 @@ struct MorphTableHeader
le_uint32 nChains;
ChainHeader chains[ANY_NUMBER];
void process(LEGlyphStorage &glyphStorage) const;
void process(const LETableReference& base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
};
LE_VAR_ARRAY(MorphTableHeader, chains)
typedef le_int16 SubtableCoverage;
typedef le_uint32 SubtableCoverage2;
@ -78,7 +81,7 @@ struct MorphSubtableHeader
SubtableCoverage coverage;
FeatureFlags subtableFeatures;
void process(LEGlyphStorage &glyphStorage) const;
void process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
};
enum SubtableCoverageFlags2
@ -96,7 +99,7 @@ struct MorphSubtableHeader2
SubtableCoverage2 coverage;
FeatureFlags subtableFeatures;
void process(LEGlyphStorage &glyphStorage) const;
void process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
};
struct ChainHeader2
@ -107,6 +110,7 @@ struct ChainHeader2
le_uint32 nSubtables;
FeatureTableEntry featureTable[ANY_NUMBER];
};
LE_VAR_ARRAY(ChainHeader2, featureTable)
struct MorphTableHeader2
{
@ -114,8 +118,9 @@ struct MorphTableHeader2
le_uint32 nChains;
ChainHeader2 chains[ANY_NUMBER];
void process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const;
void process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage, le_int32 typoFlags, LEErrorCode &success) const;
};
LE_VAR_ARRAY(MorphTableHeader2, chains)
/*
* AAT Font Features

View file

@ -17,27 +17,40 @@
U_NAMESPACE_BEGIN
void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const
void MorphTableHeader2::process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage,
le_int32 typoFlags, LEErrorCode &success) const
{
const ChainHeader2 *chainHeader = chains;
le_uint32 chainCount = SWAPL(this->nChains);
le_uint32 chain;
if(LE_FAILURE(success)) return;
for (chain = 0; chain < chainCount; chain++) {
le_uint32 chainCount = SWAPL(this->nChains);
LEReferenceTo<ChainHeader2> chainHeader(base, success, &chains[0]);
/* chainHeader and subtableHeader are implemented as a moving pointer rather than an array dereference
* to (slightly) reduce code churn. However, must be careful to preincrement them the 2nd time through.
* We don't want to increment them at the end of the loop, as that would attempt to dereference
* out of range memory.
*/
le_uint32 chain;
for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain++) {
if (chain>0) {
le_uint32 chainLength = SWAPL(chainHeader->chainLength);
chainHeader.addOffset(chainLength, success); // Don't increment the first time
}
FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
le_uint32 chainLength = SWAPL(chainHeader->chainLength);
le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
const MorphSubtableHeader2 *subtableHeader =
(const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries];
LEReferenceTo<MorphSubtableHeader2> subtableHeader(chainHeader,
success, (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]);
le_uint32 subtable;
if(LE_FAILURE(success)) break; // malformed table
if (typoFlags != 0) {
le_uint32 featureEntry;
LEReferenceToArrayOf<FeatureTableEntry> featureTableRef(chainHeader, success, &chainHeader->featureTable[0], nFeatureEntries);
if(LE_FAILURE(success)) break;
// Feature subtables
for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
FeatureTableEntry featureTableEntry = chains->featureTable[featureEntry];
const FeatureTableEntry &featureTableEntry = featureTableRef(featureEntry, success);
le_int16 featureType = SWAPW(featureTableEntry.featureType);
le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
@ -147,57 +160,63 @@ void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags
}
}
for (subtable = 0; subtable < nSubtables; subtable++) {
le_uint32 length = SWAPL(subtableHeader->length);
for (subtable = 0; LE_SUCCESS(success) && subtable < nSubtables; subtable++) {
if(subtable>0) {
le_uint32 length = SWAPL(subtableHeader->length);
subtableHeader.addOffset(length, success); // Don't addOffset for the last entry.
}
le_uint32 coverage = SWAPL(subtableHeader->coverage);
FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
// should check coverage more carefully...
if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) {
subtableHeader->process(glyphStorage);
subtableHeader->process(subtableHeader, glyphStorage, success);
}
subtableHeader = (const MorphSubtableHeader2 *) ((char *)subtableHeader + length);
}
chainHeader = (const ChainHeader2 *)((char *)chainHeader + chainLength);
}
}
void MorphSubtableHeader2::process(LEGlyphStorage &glyphStorage) const
void MorphSubtableHeader2::process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
{
SubtableProcessor2 *processor = NULL;
switch (SWAPL(coverage) & scfTypeMask2)
{
case mstIndicRearrangement:
processor = new IndicRearrangementProcessor2(this);
processor = new IndicRearrangementProcessor2(base, success);
break;
case mstContextualGlyphSubstitution:
processor = new ContextualGlyphSubstitutionProcessor2(this);
processor = new ContextualGlyphSubstitutionProcessor2(base, success);
break;
case mstLigatureSubstitution:
processor = new LigatureSubstitutionProcessor2(this);
processor = new LigatureSubstitutionProcessor2(base, success);
break;
case mstReservedUnused:
break;
case mstNonContextualGlyphSubstitution:
processor = NonContextualGlyphSubstitutionProcessor2::createInstance(this);
processor = NonContextualGlyphSubstitutionProcessor2::createInstance(base, success);
break;
case mstContextualGlyphInsertion:
processor = new ContextualGlyphInsertionProcessor2(this);
processor = new ContextualGlyphInsertionProcessor2(base, success);
break;
default:
break;
return;
break; /*NOTREACHED*/
}
if (processor != NULL) {
processor->process(glyphStorage);
processor->process(glyphStorage, success);
delete processor;
} else {
if(LE_SUCCESS(success)) {
success = LE_MEMORY_ALLOCATION_ERROR; // because ptr is null and we didn't break out.
}
}
}

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -14,7 +14,7 @@
U_NAMESPACE_BEGIN
le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const
le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const
{
if (LE_FAILURE(success)) {
return 0;
@ -33,7 +33,7 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LE
return 0;
}
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
le_uint16 seqCount = SWAPW(sequenceCount);
if (coverageIndex >= 0 && coverageIndex < seqCount) {

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -25,14 +25,16 @@ struct SequenceTable
le_uint16 glyphCount;
TTGlyphID substituteArray[ANY_NUMBER];
};
LE_VAR_ARRAY(SequenceTable, substituteArray)
struct MultipleSubstitutionSubtable : GlyphSubstitutionSubtable
{
le_uint16 sequenceCount;
Offset sequenceTableOffsetArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const;
le_uint32 process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const;
};
LE_VAR_ARRAY(MultipleSubstitutionSubtable, sequenceTableOffsetArray)
U_NAMESPACE_END
#endif

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -22,8 +22,8 @@ NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor
{
}
NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
: SubtableProcessor(morphSubtableHeader)
NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: SubtableProcessor(morphSubtableHeader, success)
{
}
@ -31,26 +31,27 @@ NonContextualGlyphSubstitutionProcessor::~NonContextualGlyphSubstitutionProcesso
{
}
SubtableProcessor *NonContextualGlyphSubstitutionProcessor::createInstance(const MorphSubtableHeader *morphSubtableHeader)
SubtableProcessor *NonContextualGlyphSubstitutionProcessor::createInstance(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
{
const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader;
LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
switch (SWAPW(header->table.format))
{
if(LE_FAILURE(success)) return NULL;
switch (SWAPW(header->table.format)) {
case ltfSimpleArray:
return new SimpleArrayProcessor(morphSubtableHeader);
return new SimpleArrayProcessor(morphSubtableHeader, success);
case ltfSegmentSingle:
return new SegmentSingleProcessor(morphSubtableHeader);
return new SegmentSingleProcessor(morphSubtableHeader, success);
case ltfSegmentArray:
return new SegmentArrayProcessor(morphSubtableHeader);
return new SegmentArrayProcessor(morphSubtableHeader, success);
case ltfSingleTable:
return new SingleTableProcessor(morphSubtableHeader);
return new SingleTableProcessor(morphSubtableHeader, success);
case ltfTrimmedArray:
return new TrimmedArrayProcessor(morphSubtableHeader);
return new TrimmedArrayProcessor(morphSubtableHeader, success);
default:
return NULL;

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -24,13 +24,13 @@ class LEGlyphStorage;
class NonContextualGlyphSubstitutionProcessor : public SubtableProcessor
{
public:
virtual void process(LEGlyphStorage &glyphStorage) = 0;
virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
static SubtableProcessor *createInstance(const MorphSubtableHeader *morphSubtableHeader);
static SubtableProcessor *createInstance(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
protected:
NonContextualGlyphSubstitutionProcessor();
NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &status);
virtual ~NonContextualGlyphSubstitutionProcessor();

View file

@ -22,8 +22,9 @@ NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcesso
{
}
NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
: SubtableProcessor2(morphSubtableHeader)
NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: SubtableProcessor2(morphSubtableHeader, success)
{
}
@ -31,26 +32,28 @@ NonContextualGlyphSubstitutionProcessor2::~NonContextualGlyphSubstitutionProcess
{
}
SubtableProcessor2 *NonContextualGlyphSubstitutionProcessor2::createInstance(const MorphSubtableHeader2 *morphSubtableHeader)
SubtableProcessor2 *NonContextualGlyphSubstitutionProcessor2::createInstance(
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
{
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
if(LE_FAILURE(success)) return NULL;
switch (SWAPW(header->table.format))
{
case ltfSimpleArray:
return new SimpleArrayProcessor2(morphSubtableHeader);
return new SimpleArrayProcessor2(morphSubtableHeader, success);
case ltfSegmentSingle:
return new SegmentSingleProcessor2(morphSubtableHeader);
return new SegmentSingleProcessor2(morphSubtableHeader, success);
case ltfSegmentArray:
return new SegmentArrayProcessor2(morphSubtableHeader);
return new SegmentArrayProcessor2(morphSubtableHeader, success);
case ltfSingleTable:
return new SingleTableProcessor2(morphSubtableHeader);
return new SingleTableProcessor2(morphSubtableHeader, success);
case ltfTrimmedArray:
return new TrimmedArrayProcessor2(morphSubtableHeader);
return new TrimmedArrayProcessor2(morphSubtableHeader, success);
default:
return NULL;

View file

@ -24,13 +24,13 @@ class LEGlyphStorage;
class NonContextualGlyphSubstitutionProcessor2 : public SubtableProcessor2
{
public:
virtual void process(LEGlyphStorage &glyphStorage) = 0;
virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
static SubtableProcessor2 *createInstance(const MorphSubtableHeader2 *morphSubtableHeader);
static SubtableProcessor2 *createInstance(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
protected:
NonContextualGlyphSubstitutionProcessor2();
NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
NonContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~NonContextualGlyphSubstitutionProcessor2();

View file

@ -126,14 +126,27 @@ static const FeatureMap featureMap[] =
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureMask(minimalFeatures),
fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE),
fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
fGSUBTable(gsubTable),
fGDEFTable(fontInstance, LE_GDEF_TABLE_TAG, success),
fGPOSTable(fontInstance, LE_GPOS_TABLE_TAG, success), fSubstitutionFilter(NULL)
{
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);
applyTypoFlags();
setScriptAndLanguageTags();
// JK patch, 2008-05-30 - see Sinhala bug report and LKLUG font
// if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) {
if (!fGPOSTable.isEmpty()&& !fGPOSTable->coversScript(fGPOSTable, fScriptTag, success)) {
fGPOSTable.clear(); // already loaded
}
}
void OpenTypeLayoutEngine::applyTypoFlags() {
const le_int32& typoFlags = fTypoFlags;
const LEFontInstance *fontInstance = fFontInstance;
switch (typoFlags & (LE_SS01_FEATURE_FLAG
| LE_SS02_FEATURE_FLAG
@ -196,15 +209,6 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, l
fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
}
setScriptAndLanguageTags();
fGDEFTable = (const GlyphDefinitionTableHeader *) getFontTable(gdefTableTag);
// JK patch, 2008-05-30 - see Sinhala bug report and LKLUG font
// if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) {
if (gposTable != NULL && gposTable->coversScript(fScriptTag)) {
fGPOSTable = gposTable;
}
}
void OpenTypeLayoutEngine::reset()
@ -219,15 +223,17 @@ void OpenTypeLayoutEngine::reset()
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureOrder(FALSE),
fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
fGSUBTable(), fGDEFTable(), fGPOSTable(), fSubstitutionFilter(NULL)
{
setScriptAndLanguageTags();
applyTypoFlags();
setScriptAndLanguageTags();
}
OpenTypeLayoutEngine::~OpenTypeLayoutEngine()
{
if (fTypoFlags & 0x80000000L) {
if (fTypoFlags & LE_CHAR_FILTER_FEATURE_FLAG) {
delete fSubstitutionFilter;
fSubstitutionFilter = NULL;
}
reset();
@ -340,13 +346,13 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32
return 0;
}
if (fGSUBTable != NULL) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
if (fGSUBTable.isValid()) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable, fScriptTagV2, fLangSysTag, success)) {
count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} else {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
}
}
@ -367,13 +373,13 @@ le_int32 OpenTypeLayoutEngine::glyphSubstitution(le_int32 count, le_int32 max, l
return 0;
}
if (fGSUBTable != NULL) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
if (fGSUBTable.isValid()) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable,fScriptTagV2,fLangSysTag,success)) {
count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} else {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
}
}
@ -453,7 +459,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
return;
}
if (fGPOSTable != NULL) {
if (!fGPOSTable.isEmpty()) {
GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount);
le_int32 i;
@ -476,19 +482,20 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
}
#endif
if (fGPOSTable != NULL) {
if (fScriptTagV2 != nullScriptTag && fGPOSTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGDEFTable, success, fFontInstance,
fFeatureMap, fFeatureMapCount, fFeatureOrder);
if (!fGPOSTable.isEmpty()) {
if (fScriptTagV2 != nullScriptTag &&
fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) {
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} else {
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, success, fFontInstance,
fFeatureMap, fFeatureMapCount, fFeatureOrder);
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
}
} else if ( fTypoFlags & 0x1 ) {
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
KernTable kt(fFontInstance, getFontTable(kernTableTag));
kt.process(glyphStorage);
} else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(kernTable, success);
kt.process(glyphStorage, success);
}
float xAdjust = 0, yAdjust = 0;

View file

@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -10,6 +10,7 @@
#include "LEGlyphFilter.h"
#include "LEFontInstance.h"
#include "LayoutEngine.h"
#include "LETableReference.h"
#include "GlyphSubstitutionTables.h"
#include "GlyphDefinitionTables.h"
@ -63,7 +64,7 @@ public:
* @internal
*/
OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known
@ -159,6 +160,11 @@ private:
*/
static const LETag scriptTags[];
/**
* apply the typoflags. Only called by the c'tors.
*/
void applyTypoFlags();
protected:
/**
* A set of "default" features. The default characterProcessing method
@ -198,22 +204,22 @@ protected:
*
* @internal
*/
const GlyphSubstitutionTableHeader *fGSUBTable;
LEReferenceTo<GlyphSubstitutionTableHeader> fGSUBTable;
/**
* The address of the GDEF table.
*
* @internal
*/
const GlyphDefinitionTableHeader *fGDEFTable;
LEReferenceTo<GlyphDefinitionTableHeader> fGDEFTable;
/**
* The address of the GPOS table.
*
* @internal
*/
const GlyphPositioningTableHeader *fGPOSTable;
LEReferenceTo<GlyphPositioningTableHeader> fGPOSTable;
/**
* An optional filter used to inhibit substitutions
* preformed by the GSUB table. This is used for some

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -13,6 +13,7 @@
*/
#include "LETypes.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN
@ -25,7 +26,7 @@ typedef le_uint32 fixed32;
#define LE_GLYPH_GROUP_MASK 0x00000001UL
typedef le_uint32 FeatureMask;
#define SWAPT(atag) ((LETag) ((atag[0] << 24) + (atag[1] << 16) + (atag[2] << 8) + atag[3]))
#define SWAPT(atag) ((LETag) (((atag[0]) << 24) + ((atag[1]) << 16) + ((atag[2]) << 8) + (atag[3])))
struct TagAndOffsetRecord
{

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -51,58 +51,74 @@ le_int8 OpenTypeUtilities::highBit(le_int32 value)
return bit;
}
Offset OpenTypeUtilities::getTagOffset(LETag tag, const TagAndOffsetRecord *records, le_int32 recordCount)
Offset OpenTypeUtilities::getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success)
{
le_uint8 bit = highBit(recordCount);
le_int32 power = 1 << bit;
le_int32 extra = recordCount - power;
le_int32 probe = power;
le_int32 index = 0;
if(LE_FAILURE(success)) return 0;
if (SWAPT(records[extra].tag) <= tag) {
index = extra;
le_uint32 recordCount = records.getCount();
le_uint8 bit = highBit(recordCount);
le_int32 power = 1 << bit;
le_int32 extra = recordCount - power;
le_int32 probe = power;
le_int32 index = 0;
{
const ATag &aTag = records.getAlias(extra,success)->tag;
if (SWAPT(aTag) <= tag) {
index = extra;
}
while (probe > (1 << 0)) {
probe >>= 1;
if (SWAPT(records[index + probe].tag) <= tag) {
index += probe;
}
}
while (probe > (1 << 0) && LE_SUCCESS(success)) {
probe >>= 1;
{
const ATag &aTag = records.getAlias(index+probe,success)->tag;
if (SWAPT(aTag) <= tag) {
index += probe;
}
}
if (SWAPT(records[index].tag) == tag) {
return SWAPW(records[index].offset);
}
{
const ATag &aTag = records.getAlias(index,success)->tag;
if (SWAPT(aTag) == tag) {
return SWAPW(records.getAlias(index,success)->offset);
}
}
return 0;
return 0;
}
le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount)
le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success)
{
if(LE_FAILURE(success)) return -1;
le_uint32 recordCount = records.getCount();
le_uint8 bit = highBit(recordCount);
le_int32 power = 1 << bit;
le_int32 extra = recordCount - power;
le_int32 probe = power;
le_int32 range = 0;
if (recordCount == 0) {
return -1;
}
if (recordCount == 0) {
return -1;
}
if (SWAPW(records[extra].firstGlyph) <= glyphID) {
if (SWAPW(records(extra,success).firstGlyph) <= glyphID) {
range = extra;
}
while (probe > (1 << 0)) {
while (probe > (1 << 0) && LE_SUCCESS(success)) {
probe >>= 1;
if (SWAPW(records[range + probe].firstGlyph) <= glyphID) {
if (SWAPW(records(range + probe,success).firstGlyph) <= glyphID) {
range += probe;
}
}
if (SWAPW(records[range].firstGlyph) <= glyphID && SWAPW(records[range].lastGlyph) >= glyphID) {
if (SWAPW(records(range,success).firstGlyph) <= glyphID && SWAPW(records(range,success).lastGlyph) >= glyphID) {
return range;
}
@ -174,6 +190,38 @@ void OpenTypeUtilities::sort(le_uint16 *array, le_int32 count)
}
}
U_NAMESPACE_END
#if LE_ASSERT_BAD_FONT
#include <stdio.h>
static const char *letagToStr(LETag tag, char *str) {
str[0]= 0xFF & (tag>>24);
str[1]= 0xFF & (tag>>16);
str[2]= 0xFF & (tag>>8);
str[3]= 0xFF & (tag>>0);
str[4]= 0;
return str;
}
U_CAPI void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len) {
char tagbuf[5];
fprintf(stderr, "%s:%d: LETableReference@0x%p: ", f, l, what);
fprintf(stderr, msg, ptr, len);
fprintf(stderr, "\n");
for(int depth=0;depth<10&&(what!=NULL);depth++) {
for(int i=0;i<depth;i++) {
fprintf(stderr, " "); // indent
}
if(!what->isValid()) {
fprintf(stderr, "(invalid)");
}
fprintf(stderr, "@%p: tag (%s) font (0x%p), [0x%p+0x%lx]\n", what, letagToStr(what->getTag(), tagbuf), what->getFont(),
what->getAlias(), what->getLength());
what = what->getParent();
}
}
#endif

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -20,8 +20,14 @@ U_NAMESPACE_BEGIN
class OpenTypeUtilities /* not : public UObject because all methods are static */ {
public:
static le_int8 highBit(le_int32 value);
static Offset getTagOffset(LETag tag, const TagAndOffsetRecord *records, le_int32 recordCount);
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount);
static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success);
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) {
LEErrorCode success = LE_NO_ERROR;
LETableReference recordRef0((const le_uint8*)records);
LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount);
return getGlyphRangeIndex(glyphID, recordRef, success);
}
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success);
static le_int32 search(le_uint16 value, const le_uint16 array[], le_int32 count);
static le_int32 search(le_uint32 value, const le_uint32 array[], le_int32 count);
static void sort(le_uint16 *array, le_int32 count);

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
@ -16,7 +16,7 @@
U_NAMESPACE_BEGIN
le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
le_uint32 PairPositioningSubtable::process(const LEReferenceTo<PairPositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{
switch(SWAPW(subtableFormat))
{
@ -25,27 +25,32 @@ le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const L
case 1:
{
const PairPositioningFormat1Subtable *subtable = (const PairPositioningFormat1Subtable *) this;
const LEReferenceTo<PairPositioningFormat1Subtable> subtable(base, success, (const PairPositioningFormat1Subtable *) this);
return subtable->process(glyphIterator, fontInstance);
if(LE_SUCCESS(success))
return subtable->process(subtable, glyphIterator, fontInstance, success);
else
return 0;
}
case 2:
{
const PairPositioningFormat2Subtable *subtable = (const PairPositioningFormat2Subtable *) this;
const LEReferenceTo<PairPositioningFormat2Subtable> subtable(base, success, (const PairPositioningFormat2Subtable *) this);
return subtable->process(glyphIterator, fontInstance);
}
default:
if(LE_SUCCESS(success))
return subtable->process(subtable, glyphIterator, fontInstance, success);
else
return 0;
}
default:
return 0;
}
}
le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{
LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(firstGlyph);
le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
GlyphIterator tempIterator(*glyphIterator);
if (coverageIndex >= 0 && glyphIterator->next()) {
@ -85,10 +90,10 @@ le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator,
return 0;
}
le_uint32 PairPositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{
LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(firstGlyph);
le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
GlyphIterator tempIterator(*glyphIterator);
if (coverageIndex >= 0 && glyphIterator->next()) {

Some files were not shown because too many files have changed in this diff Show more