mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-10107 LayoutEngine improvements
X-SVN-Rev: 33535
This commit is contained in:
parent
37aa0f8445
commit
f2fbc8c394
142 changed files with 6569 additions and 5213 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
418
icu4c/source/layout/LETableReference.h
Normal file
418
icu4c/source/layout/LETableReference.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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--];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue