提交 f1732ae0 编写于 作者: P prr

8001031: Better font processing

Reviewed-by: srl, vadim
上级 ccd00899
...@@ -66,8 +66,21 @@ FontInstanceAdapter::FontInstanceAdapter(JNIEnv *theEnv, ...@@ -66,8 +66,21 @@ FontInstanceAdapter::FontInstanceAdapter(JNIEnv *theEnv,
yScalePixelsToUnits = upem / yppem; yScalePixelsToUnits = upem / yppem;
}; };
const void *FontInstanceAdapter::getFontTable(LETag tableTag) const const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
{ {
size_t ignored = 0;
return getFontTable(tableTag, ignored);
}
static const LETag cacheMap[LAYOUTCACHE_ENTRIES] = {
GPOS_TAG, GDEF_TAG, GSUB_TAG, MORT_TAG, MORX_TAG, KERN_TAG
};
const void *FontInstanceAdapter::getFontTable(LETag tableTag, size_t &length) const
{
length = 0;
if (!layoutTables) { // t1 font if (!layoutTables) { // t1 font
return 0; return 0;
} }
...@@ -75,14 +88,19 @@ const void *FontInstanceAdapter::getFontTable(LETag tableTag) const ...@@ -75,14 +88,19 @@ const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
// cache in font's pscaler object // cache in font's pscaler object
// font disposer will handle for us // font disposer will handle for us
switch(tableTag) { int cacheIdx;
case GSUB_TAG: if (layoutTables->gsub_len != -1) return (void*)layoutTables->gsub; break; for (cacheIdx=0;cacheIdx<LAYOUTCACHE_ENTRIES;cacheIdx++) {
case GPOS_TAG: if (layoutTables->gpos_len != -1) return (void*)layoutTables->gpos; break; if (tableTag==cacheMap[cacheIdx]) break;
case GDEF_TAG: if (layoutTables->gdef_len != -1) return (void*)layoutTables->gdef; break; }
case MORT_TAG: if (layoutTables->mort_len != -1) return (void*)layoutTables->mort; break;
case KERN_TAG: if (layoutTables->kern_len != -1) return (void*)layoutTables->kern; break; if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if found
default: if (layoutTables->entries[cacheIdx].len != -1) {
//fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag); length = layoutTables->entries[cacheIdx].len;
return layoutTables->entries[cacheIdx].ptr;
}
} else {
//fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag);
// (don't load any other tables)
return 0; return 0;
} }
...@@ -96,16 +114,13 @@ const void *FontInstanceAdapter::getFontTable(LETag tableTag) const ...@@ -96,16 +114,13 @@ const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
env->GetByteArrayRegion(tableBytes, 0, len, result); env->GetByteArrayRegion(tableBytes, 0, len, result);
} }
switch(tableTag) { if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if cacheable table
case GSUB_TAG: layoutTables->gsub = (void*)result; layoutTables->gsub_len = len; break; layoutTables->entries[cacheIdx].len = len;
case GPOS_TAG: layoutTables->gpos = (void*)result; layoutTables->gpos_len = len; break; layoutTables->entries[cacheIdx].ptr = (const void*)result;
case GDEF_TAG: layoutTables->gdef = (void*)result; layoutTables->gdef_len = len; break;
case MORT_TAG: layoutTables->mort = (void*)result; layoutTables->mort_len = len; break;
case KERN_TAG: layoutTables->kern = (void*)result; layoutTables->kern_len = len; break;
default: break;
} }
return (void*)result; length = len;
return (const void*)result;
}; };
LEGlyphID FontInstanceAdapter::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const LEGlyphID FontInstanceAdapter::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
......
...@@ -86,6 +86,7 @@ public: ...@@ -86,6 +86,7 @@ public:
// tables are cached with the native font scaler data // tables are cached with the native font scaler data
// only supports gsub, gpos, gdef, mort tables at present // only supports gsub, gpos, gdef, mort tables at present
virtual const void *getFontTable(LETag tableTag) const; virtual const void *getFontTable(LETag tableTag) const;
virtual const void *getFontTable(LETag tableTag, size_t &len) const;
virtual void *getKernPairs() const { virtual void *getKernPairs() const {
return layoutTables->kernPairs; return layoutTables->kernPairs;
......
...@@ -120,20 +120,19 @@ typedef struct GlyphInfo { ...@@ -120,20 +120,19 @@ typedef struct GlyphInfo {
#define GPOS_TAG 0x47504F53 /* 'GPOS' */ #define GPOS_TAG 0x47504F53 /* 'GPOS' */
#define GDEF_TAG 0x47444546 /* 'GDEF' */ #define GDEF_TAG 0x47444546 /* 'GDEF' */
#define MORT_TAG 0x6D6F7274 /* 'mort' */ #define MORT_TAG 0x6D6F7274 /* 'mort' */
#define MORX_TAG 0x6D6F7278 /* 'morx' */
#define KERN_TAG 0x6B65726E /* 'kern' */ #define KERN_TAG 0x6B65726E /* 'kern' */
typedef struct TTLayoutTableCacheEntry {
const void* ptr;
int len;
} TTLayoutTableCacheEntry;
#define LAYOUTCACHE_ENTRIES 6
typedef struct TTLayoutTableCache { typedef struct TTLayoutTableCache {
void* gsub; TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES];
void* gpos; void* kernPairs;
void* gdef;
void* mort;
void* kern;
void* kernPairs;
int gsub_len;
int gpos_len;
int gdef_len;
int mort_len;
int kern_len;
} TTLayoutTableCache; } TTLayoutTableCache;
#include "sunfontids.h" #include "sunfontids.h"
......
...@@ -39,19 +39,20 @@ ...@@ -39,19 +39,20 @@
U_NAMESPACE_BEGIN 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... // NOTE: For now, we'll just pick the first alternative...
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); 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); le_uint16 altSetCount = SWAPW(alternateSetCount);
if (coverageIndex < altSetCount) { if (coverageIndex < altSetCount) {
Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]); Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
const AlternateSetTable *alternateSetTable = const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset); (const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]); TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) { if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
......
...@@ -51,13 +51,17 @@ struct AlternateSetTable ...@@ -51,13 +51,17 @@ struct AlternateSetTable
TTGlyphID alternateArray[ANY_NUMBER]; TTGlyphID alternateArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(AlternateSetTable, alternateArray)
struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable
{ {
le_uint16 alternateSetCount; le_uint16 alternateSetCount;
Offset alternateSetTableOffsetArray[ANY_NUMBER]; 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 U_NAMESPACE_END
#endif #endif
...@@ -58,15 +58,18 @@ le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const ...@@ -58,15 +58,18 @@ le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) le_int32 languageCode, le_int32 typoFlags,
const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE; 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) le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{ {
...@@ -88,8 +91,9 @@ ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine() ...@@ -88,8 +91,9 @@ ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
// Input: characters // Input: characters
// Output: characters, char indices, tags // Output: characters, char indices, tags
// Returns: output character count // Returns: output character count
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return 0; return 0;
...@@ -137,22 +141,21 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l ...@@ -137,22 +141,21 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
return; return;
} }
if (fGPOSTable != NULL) { if (!fGPOSTable.isEmpty()) {
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success); OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
} else if (fGDEFTable != NULL) { } else if (!fGDEFTable.isEmpty()) {
GDEFMarkFilter filter(fGDEFTable); GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success); adjustMarkGlyphs(glyphStorage, &filter, success);
} else { } else {
GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
GDEFMarkFilter filter(gdefTable); GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, 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) UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success) : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
{ {
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
...@@ -232,7 +235,7 @@ void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode cha ...@@ -232,7 +235,7 @@ void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode cha
return; return;
} }
GDEFMarkFilter filter(fGDEFTable); GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
} }
......
...@@ -75,7 +75,7 @@ public: ...@@ -75,7 +75,7 @@ public:
* @internal * @internal
*/ */
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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 * This constructor is used when the font requires a "canned" GSUB table which can't be known
......
...@@ -58,14 +58,16 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] = ...@@ -58,14 +58,16 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
*/ */
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c) ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
{ {
const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable; LEErrorCode success = LE_NO_ERROR;
le_int32 joiningType = joiningTypes->getGlyphClass(c); 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) { if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) {
return ArabicShaping::shapeTypes[joiningType]; return ArabicShaping::shapeTypes[joiningType];
} }
return ArabicShaping::ST_NOSHAPE_NONE; return ArabicShaping::ST_NOSHAPE_NONE;
} }
#define isolFeatureTag LE_ISOL_FEATURE_TAG #define isolFeatureTag LE_ISOL_FEATURE_TAG
......
...@@ -93,6 +93,8 @@ private: ...@@ -93,6 +93,8 @@ private:
static ShapeType getShapeType(LEUnicode c); static ShapeType getShapeType(LEUnicode c);
static const le_uint8 shapingTypeTable[]; static const le_uint8 shapingTypeTable[];
static const size_t shapingTypeTableLen;
static const ShapeType shapeTypes[]; 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);
......
...@@ -52,14 +52,14 @@ struct AttachmentPositioningSubtable : GlyphPositioningSubtable ...@@ -52,14 +52,14 @@ struct AttachmentPositioningSubtable : GlyphPositioningSubtable
Offset markArrayOffset; Offset markArrayOffset;
Offset baseArrayOffset; 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; 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 U_NAMESPACE_END
......
...@@ -3641,4 +3641,9 @@ const le_uint8 CanonShaping::glyphDefinitionTable[] = { ...@@ -3641,4 +3641,9 @@ const le_uint8 CanonShaping::glyphDefinitionTable[] = {
0x00, 0xE6, 0xD2, 0x42, 0xD2, 0x44, 0x00, 0xE6 0x00, 0xE6, 0xD2, 0x42, 0xD2, 0x44, 0x00, 0xE6
}; };
const size_t CanonShaping::glyphSubstitutionTableLen = sizeof(glyphSubstitutionTable)/sizeof(glyphSubstitutionTable[0]);
const size_t CanonShaping::glyphDefinitionTableLen = sizeof(glyphDefinitionTable)/sizeof(glyphDefinitionTable[0]);
U_NAMESPACE_END U_NAMESPACE_END
...@@ -59,15 +59,15 @@ void CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses ...@@ -59,15 +59,15 @@ void CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses
void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft, void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
LEUnicode *outChars, LEGlyphStorage &glyphStorage) LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{ {
const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable; LEErrorCode success = LE_NO_ERROR;
const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable(); 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 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount); le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
LEErrorCode status = LE_NO_ERROR;
le_int32 i; le_int32 i;
for (i = 0; i < charCount; i += 1) { 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; indices[i] = i;
} }
...@@ -96,7 +96,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le ...@@ -96,7 +96,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
le_int32 index = indices[i]; le_int32 index = indices[i];
outChars[i] = inChars[index]; outChars[i] = inChars[index];
glyphStorage.setCharIndex(out, index, status); glyphStorage.setCharIndex(out, index, success);
} }
LE_DELETE_ARRAY(indices); LE_DELETE_ARRAY(indices);
......
...@@ -42,7 +42,9 @@ class U_LAYOUT_API CanonShaping /* not : public UObject because all members are ...@@ -42,7 +42,9 @@ class U_LAYOUT_API CanonShaping /* not : public UObject because all members are
{ {
public: public:
static const le_uint8 glyphSubstitutionTable[]; static const le_uint8 glyphSubstitutionTable[];
static const size_t glyphSubstitutionTableLen;
static const le_uint8 glyphDefinitionTable[]; static const le_uint8 glyphDefinitionTable[];
static const size_t glyphDefinitionTableLen;
static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft, static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
LEUnicode *outChars, LEGlyphStorage &glyphStorage); LEUnicode *outChars, LEGlyphStorage &glyphStorage);
......
...@@ -37,49 +37,51 @@ ...@@ -37,49 +37,51 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_int32 ClassDefinitionTable::getGlyphClass(LEGlyphID glyphID) const le_int32 ClassDefinitionTable::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
switch(SWAPW(classFormat)) { LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
if (LE_FAILURE(success)) return 0;
switch(SWAPW(classFormat)) {
case 0: case 0:
return 0; return 0;
case 1: case 1:
{ {
const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this; const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
return f1Table->getGlyphClass(f1Table, glyphID, success);
return f1Table->getGlyphClass(glyphID);
} }
case 2: case 2:
{ {
const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this; const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
return f2Table->getGlyphClass(f2Table, glyphID, success);
return f2Table->getGlyphClass(glyphID);
} }
default: default:
return 0; return 0;
} }
} }
le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const 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)) { switch(SWAPW(classFormat)) {
case 0: case 0:
return 0; return 0;
case 1: case 1:
{ {
const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this; const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
return f1Table->hasGlyphClass(f1Table, glyphClass, success);
return f1Table->hasGlyphClass(glyphClass);
} }
case 2: case 2:
{ {
const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this; const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
return f2Table->hasGlyphClass(f2Table, glyphClass, success);
return f2Table->hasGlyphClass(glyphClass);
} }
default: default:
...@@ -87,26 +89,32 @@ le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const ...@@ -87,26 +89,32 @@ le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const
} }
} }
le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const le_int32 ClassDefFormat1Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
if(LE_FAILURE(success)) return 0;
le_uint16 count = SWAPW(glyphCount);
LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
TTGlyphID firstGlyph = SWAPW(startGlyph); TTGlyphID firstGlyph = SWAPW(startGlyph);
TTGlyphID lastGlyph = firstGlyph + SWAPW(glyphCount); TTGlyphID lastGlyph = firstGlyph + count;
if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) { if (LE_SUCCESS(success) && ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
return SWAPW(classValueArray[ttGlyphID - firstGlyph]); return SWAPW( classValueArrayRef(ttGlyphID - firstGlyph, success) );
} }
return 0; 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; int i;
for (i = 0; i < count; i += 1) { for (i = 0; LE_SUCCESS(success)&& (i < count); i += 1) {
if (SWAPW(classValueArray[i]) == glyphClass) { if (SWAPW(classValueArrayRef(i,success)) == glyphClass) {
return TRUE; return TRUE;
} }
} }
...@@ -114,27 +122,31 @@ le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const ...@@ -114,27 +122,31 @@ le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const
return FALSE; 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); TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphID);
le_uint16 rangeCount = SWAPW(classRangeCount); le_uint16 rangeCount = SWAPW(classRangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
le_int32 rangeIndex = 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 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); le_uint16 rangeCount = SWAPW(classRangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
int i; int i;
for (i = 0; i < rangeCount; i += 1) { for (i = 0; i < rangeCount && LE_SUCCESS(success); i += 1) {
if (SWAPW(classRangeRecordArray[i].rangeValue) == glyphClass) { if (SWAPW(classRangeRecordArrayRef(i,success).rangeValue) == glyphClass) {
return TRUE; return TRUE;
} }
} }
......
...@@ -46,8 +46,20 @@ struct ClassDefinitionTable ...@@ -46,8 +46,20 @@ struct ClassDefinitionTable
{ {
le_uint16 classFormat; le_uint16 classFormat;
le_int32 getGlyphClass(LEGlyphID glyphID) const; le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(le_int32 glyphClass) 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 struct ClassDefFormat1Table : ClassDefinitionTable
...@@ -56,9 +68,11 @@ struct ClassDefFormat1Table : ClassDefinitionTable ...@@ -56,9 +68,11 @@ struct ClassDefFormat1Table : ClassDefinitionTable
le_uint16 glyphCount; le_uint16 glyphCount;
le_uint16 classValueArray[ANY_NUMBER]; le_uint16 classValueArray[ANY_NUMBER];
le_int32 getGlyphClass(LEGlyphID glyphID) const; le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(le_int32 glyphClass) const; le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(ClassDefFormat1Table, classValueArray)
struct ClassRangeRecord struct ClassRangeRecord
{ {
...@@ -72,9 +86,10 @@ struct ClassDefFormat2Table : ClassDefinitionTable ...@@ -72,9 +86,10 @@ struct ClassDefFormat2Table : ClassDefinitionTable
le_uint16 classRangeCount; le_uint16 classRangeCount;
GlyphRangeRecord classRangeRecordArray[ANY_NUMBER]; GlyphRangeRecord classRangeRecordArray[ANY_NUMBER];
le_int32 getGlyphClass(LEGlyphID glyphID) const; le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(le_int32 glyphClass) const; le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(ClassDefFormat2Table, classRangeRecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -43,13 +43,15 @@ U_NAMESPACE_BEGIN ...@@ -43,13 +43,15 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
: StateTableProcessor2(morphSubtableHeader) const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader, success)
{ {
contextualGlyphHeader = (const ContextualGlyphInsertionHeader2 *) morphSubtableHeader; contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset); if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
insertionTable = ((le_uint16 *) ((char *)&stateTableHeader->stHeader + insertionTableOffset)); le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
entryTable = (const ContextualGlyphInsertionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset); insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
} }
ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2() ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
...@@ -61,93 +63,62 @@ void ContextualGlyphInsertionProcessor2::beginStateTable() ...@@ -61,93 +63,62 @@ void ContextualGlyphInsertionProcessor2::beginStateTable()
markGlyph = 0; 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 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags); 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) { if (markIndex > 0) {
le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5; le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
if (!(flags & cgiMarkedIsKashidaLike)) { le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
// extra glyph(s) will be added directly before/after the specified marked glyph le_bool isBefore = (flags & cgiMarkInsertBefore);
if (!(flags & cgiMarkInsertBefore)) { doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
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_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
if (currIndex > 0) { if (currIndex > 0) {
le_int16 count = flags & cgiCurrentInsertCountMask; le_int16 count = flags & cgiCurrentInsertCountMask;
if (!(flags & cgiCurrentIsKashidaLike)) { le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
// extra glyph(s) will be added directly before/after the specified current glyph le_bool isBefore = (flags & cgiCurrentInsertBefore);
if (!(flags & cgiCurrentInsertBefore)) { doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
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();
}
}
} }
if (flags & cgiSetMark) { if (flags & cgiSetMark) {
......
...@@ -53,11 +53,12 @@ class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2 ...@@ -53,11 +53,12 @@ class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2
public: public:
virtual void beginStateTable(); 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(); virtual void endStateTable();
ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); ContextualGlyphInsertionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphInsertionProcessor2(); virtual ~ContextualGlyphInsertionProcessor2();
/** /**
...@@ -77,12 +78,28 @@ public: ...@@ -77,12 +78,28 @@ public:
private: private:
ContextualGlyphInsertionProcessor2(); 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: protected:
le_int32 markGlyph; le_int32 markGlyph;
const le_uint16* insertionTable; LEReferenceToArrayOf<le_uint16> insertionTable;
const ContextualGlyphInsertionStateEntry2 *entryTable; LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2> entryTable;
const ContextualGlyphInsertionHeader2 *contextualGlyphHeader; LEReferenceTo<ContextualGlyphInsertionHeader2> contextualGlyphHeader;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -43,13 +43,18 @@ U_NAMESPACE_BEGIN ...@@ -43,13 +43,18 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor)
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader) ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader) : StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
{ {
contextualGlyphSubstitutionHeader = (const ContextualGlyphSubstitutionHeader *) morphSubtableHeader; contextualGlyphSubstitutionHeader.orphan();
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset); 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() ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor()
...@@ -63,27 +68,26 @@ void ContextualGlyphSubstitutionProcessor::beginStateTable() ...@@ -63,27 +68,26 @@ void ContextualGlyphSubstitutionProcessor::beginStateTable()
ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{ {
const ContextualGlyphSubstitutionStateEntry *entry = &entryTable[index]; LEErrorCode success = LE_NO_ERROR;
ByteOffset newState = SWAPW(entry->newStateOffset); const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
le_int16 flags = SWAPW(entry->flags); ByteOffset newState = SWAPW(entry->newStateOffset);
WordOffset markOffset = SWAPW(entry->markOffset); le_int16 flags = SWAPW(entry->flags);
WordOffset currOffset = SWAPW(entry->currOffset); WordOffset markOffset = SWAPW(entry->markOffset);
WordOffset currOffset = SWAPW(entry->currOffset);
if (markOffset != 0) {
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + markOffset * 2); if (markOffset != 0 && LE_SUCCESS(success)) {
LEGlyphID mGlyph = glyphStorage[markGlyph]; LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(mGlyph)]); TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
} }
if (currOffset != 0) { if (currOffset != 0) {
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + currOffset * 2); LEGlyphID thisGlyph = glyphStorage[currGlyph];
LEGlyphID thisGlyph = glyphStorage[currGlyph]; TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(thisGlyph)]);
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); }
}
if (flags & cgsSetMark) { if (flags & cgsSetMark) {
markGlyph = currGlyph; markGlyph = currGlyph;
......
...@@ -56,7 +56,7 @@ public: ...@@ -56,7 +56,7 @@ public:
virtual void endStateTable(); virtual void endStateTable();
ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader); ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphSubstitutionProcessor(); virtual ~ContextualGlyphSubstitutionProcessor();
/** /**
...@@ -78,11 +78,11 @@ private: ...@@ -78,11 +78,11 @@ private:
protected: protected:
ByteOffset substitutionTableOffset; ByteOffset substitutionTableOffset;
const ContextualGlyphSubstitutionStateEntry *entryTable; LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry> entryTable;
LEReferenceToArrayOf<le_int16> int16Table;
le_int32 markGlyph; le_int32 markGlyph;
const ContextualGlyphSubstitutionHeader *contextualGlyphSubstitutionHeader; LEReferenceTo<ContextualGlyphSubstitutionHeader> contextualGlyphSubstitutionHeader;
}; };
......
...@@ -43,13 +43,14 @@ U_NAMESPACE_BEGIN ...@@ -43,13 +43,14 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(
: StateTableProcessor2(morphSubtableHeader) 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); le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
perGlyphTable = ((le_uint32 *) ((char *)&stateTableHeader->stHeader + perGlyphTableOffset)); perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY);
entryTable = (const ContextualGlyphStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset); entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
} }
ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2() ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
...@@ -61,25 +62,28 @@ void ContextualGlyphSubstitutionProcessor2::beginStateTable() ...@@ -61,25 +62,28 @@ void ContextualGlyphSubstitutionProcessor2::beginStateTable()
markGlyph = 0; 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 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags); le_uint16 flags = SWAPW(entry->flags);
le_int16 markIndex = SWAPW(entry->markIndex); le_int16 markIndex = SWAPW(entry->markIndex);
le_int16 currIndex = SWAPW(entry->currIndex); le_int16 currIndex = SWAPW(entry->currIndex);
if (markIndex != -1) { if (markIndex != -1) {
le_uint32 offset = SWAPL(perGlyphTable[markIndex]); le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
LEGlyphID mGlyph = glyphStorage[markGlyph]; LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = lookup(offset, mGlyph); TTGlyphID newGlyph = lookup(offset, mGlyph, success);
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
} }
if (currIndex != -1) { if (currIndex != -1) {
le_uint32 offset = SWAPL(perGlyphTable[currIndex]); le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
LEGlyphID thisGlyph = glyphStorage[currGlyph]; LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = lookup(offset, thisGlyph); TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
...@@ -94,26 +98,30 @@ le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorag ...@@ -94,26 +98,30 @@ le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorag
return newState; 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; 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) { switch (format) {
case ltfSimpleArray: { case ltfSimpleArray: {
#ifdef TEST_FORMAT #ifdef TEST_FORMAT
// Disabled pending for design review // 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); TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
newGlyph = SWAPW(lookupTable0->valueArray[glyphCode]); newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success));
#endif #endif
break; break;
} }
case ltfSegmentSingle: { case ltfSegmentSingle: {
#ifdef TEST_FORMAT #ifdef TEST_FORMAT
// Disabled pending for design review // Disabled pending for design review
SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) lookupTable; LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid); const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
if (segment != NULL) { if (segment != NULL) {
newGlyph = SWAPW(segment->value); newGlyph = SWAPW(segment->value);
...@@ -129,8 +137,8 @@ TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyp ...@@ -129,8 +137,8 @@ TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyp
{ {
#ifdef TEST_FORMAT #ifdef TEST_FORMAT
// Disabled pending for design review // Disabled pending for design review
SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) lookupTable; LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable;
const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid); const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
if (segment != NULL) { if (segment != NULL) {
newGlyph = SWAPW(segment->value); newGlyph = SWAPW(segment->value);
} }
...@@ -138,12 +146,15 @@ TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyp ...@@ -138,12 +146,15 @@ TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyp
break; break;
} }
case ltfTrimmedArray: { case ltfTrimmedArray: {
TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) lookupTable; LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success);
if (LE_FAILURE(success)) return newGlyph;
TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); 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); TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { 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: default:
......
...@@ -52,11 +52,11 @@ class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2 ...@@ -52,11 +52,11 @@ class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2
public: public:
virtual void beginStateTable(); 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(); virtual void endStateTable();
ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); ContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphSubstitutionProcessor2(); virtual ~ContextualGlyphSubstitutionProcessor2();
/** /**
...@@ -75,16 +75,16 @@ public: ...@@ -75,16 +75,16 @@ public:
private: private:
ContextualGlyphSubstitutionProcessor2(); ContextualGlyphSubstitutionProcessor2();
TTGlyphID lookup(le_uint32 offset, LEGlyphID gid); TTGlyphID lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success);
protected: protected:
const le_uint32* perGlyphTable; LEReferenceToArrayOf<le_uint32> perGlyphTable;
const ContextualGlyphStateEntry2 *entryTable; LEReferenceToArrayOf<ContextualGlyphStateEntry2> entryTable;
le_int16 perGlyphTableFormat; le_int16 perGlyphTableFormat;
le_int32 markGlyph; le_int32 markGlyph;
const ContextualGlyphHeader2 *contextualGlyphHeader; LEReferenceTo<ContextualGlyphHeader2> contextualGlyphHeader;
}; };
......
...@@ -217,7 +217,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * ...@@ -217,7 +217,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
} }
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
le_uint16 srSetCount = SWAPW(subRuleSetCount); le_uint16 srSetCount = SWAPW(subRuleSetCount);
...@@ -266,7 +266,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * ...@@ -266,7 +266,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
} }
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
const ClassDefinitionTable *classDefinitionTable = const ClassDefinitionTable *classDefinitionTable =
...@@ -394,7 +394,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -394,7 +394,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
} }
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
le_uint16 srSetCount = SWAPW(chainSubRuleSetCount); le_uint16 srSetCount = SWAPW(chainSubRuleSetCount);
...@@ -465,7 +465,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro ...@@ -465,7 +465,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
} }
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
const ClassDefinitionTable *backtrackClassDefinitionTable = const ClassDefinitionTable *backtrackClassDefinitionTable =
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "GlyphSubstitutionTables.h" #include "GlyphSubstitutionTables.h"
#include "GlyphIterator.h" #include "GlyphIterator.h"
#include "LookupProcessor.h" #include "LookupProcessor.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
...@@ -88,6 +89,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable ...@@ -88,6 +89,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
struct SubRuleSetTable struct SubRuleSetTable
{ {
...@@ -95,6 +98,7 @@ struct SubRuleSetTable ...@@ -95,6 +98,7 @@ struct SubRuleSetTable
Offset subRuleTableOffsetArray[ANY_NUMBER]; Offset subRuleTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SubRuleSetTable, subRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!! // NOTE: Multiple variable size arrays!!
struct SubRuleTable struct SubRuleTable
...@@ -104,6 +108,7 @@ struct SubRuleTable ...@@ -104,6 +108,7 @@ struct SubRuleTable
TTGlyphID inputGlyphArray[ANY_NUMBER]; TTGlyphID inputGlyphArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SubRuleTable, inputGlyphArray)
struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
{ {
...@@ -113,12 +118,16 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable ...@@ -113,12 +118,16 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
struct SubClassSetTable struct SubClassSetTable
{ {
le_uint16 subClassRuleCount; le_uint16 subClassRuleCount;
Offset subClassRuleTableOffsetArray[ANY_NUMBER]; Offset subClassRuleTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SubClassSetTable, subClassRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!! // NOTE: Multiple variable size arrays!!
struct SubClassRuleTable struct SubClassRuleTable
...@@ -128,6 +137,8 @@ struct SubClassRuleTable ...@@ -128,6 +137,8 @@ struct SubClassRuleTable
le_uint16 classArray[ANY_NUMBER]; le_uint16 classArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SubClassRuleTable, classArray)
// NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
// it has an array of coverage tables instead of a single coverage table... // it has an array of coverage tables instead of a single coverage table...
...@@ -143,6 +154,7 @@ struct ContextualSubstitutionFormat3Subtable ...@@ -143,6 +154,7 @@ struct ContextualSubstitutionFormat3Subtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
{ {
...@@ -156,6 +168,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit ...@@ -156,6 +168,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
struct ChainSubRuleSetTable struct ChainSubRuleSetTable
{ {
...@@ -163,6 +177,7 @@ struct ChainSubRuleSetTable ...@@ -163,6 +177,7 @@ struct ChainSubRuleSetTable
Offset chainSubRuleTableOffsetArray[ANY_NUMBER]; Offset chainSubRuleTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ChainSubRuleSetTable, chainSubRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!! // NOTE: Multiple variable size arrays!!
struct ChainSubRuleTable struct ChainSubRuleTable
...@@ -176,6 +191,7 @@ struct ChainSubRuleTable ...@@ -176,6 +191,7 @@ struct ChainSubRuleTable
//le_uint16 substCount; //le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ChainSubRuleTable, backtrackGlyphArray)
struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstitutionSubtable struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstitutionSubtable
{ {
...@@ -187,12 +203,15 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit ...@@ -187,12 +203,15 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
struct ChainSubClassSetTable struct ChainSubClassSetTable
{ {
le_uint16 chainSubClassRuleCount; le_uint16 chainSubClassRuleCount;
Offset chainSubClassRuleTableOffsetArray[ANY_NUMBER]; Offset chainSubClassRuleTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ChainSubClassSetTable, chainSubClassRuleTableOffsetArray)
// NOTE: Multiple variable size arrays!! // NOTE: Multiple variable size arrays!!
struct ChainSubClassRuleTable struct ChainSubClassRuleTable
...@@ -206,6 +225,7 @@ struct ChainSubClassRuleTable ...@@ -206,6 +225,7 @@ struct ChainSubClassRuleTable
//le_uint16 substCount; //le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ChainSubClassRuleTable, backtrackClassArray)
// NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
// it has arrays of coverage tables instead of a single coverage table... // it has arrays of coverage tables instead of a single coverage table...
...@@ -225,6 +245,8 @@ struct ChainingContextualSubstitutionFormat3Subtable ...@@ -225,6 +245,8 @@ struct ChainingContextualSubstitutionFormat3Subtable
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -56,6 +56,8 @@ struct CoverageFormat1Table : CoverageTable ...@@ -56,6 +56,8 @@ struct CoverageFormat1Table : CoverageTable
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
}; };
LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
struct CoverageFormat2Table : CoverageTable struct CoverageFormat2Table : CoverageTable
{ {
...@@ -64,6 +66,7 @@ struct CoverageFormat2Table : CoverageTable ...@@ -64,6 +66,7 @@ struct CoverageFormat2Table : CoverageTable
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
}; };
LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -39,10 +39,10 @@ ...@@ -39,10 +39,10 @@
U_NAMESPACE_BEGIN 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(); LEGlyphID glyphID = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyphID); le_int32 coverageIndex = getGlyphCoverage(base, glyphID, success);
le_uint16 eeCount = SWAPW(entryExitCount); le_uint16 eeCount = SWAPW(entryExitCount);
if (coverageIndex < 0 || coverageIndex >= eeCount) { if (coverageIndex < 0 || coverageIndex >= eeCount) {
...@@ -51,7 +51,7 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const ...@@ -51,7 +51,7 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const
} }
LEPoint entryAnchor, exitAnchor; LEPoint entryAnchor, exitAnchor;
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO
Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor); Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
if (entryOffset != 0) { if (entryOffset != 0) {
......
...@@ -57,8 +57,9 @@ struct CursiveAttachmentSubtable : GlyphPositioningSubtable ...@@ -57,8 +57,9 @@ struct CursiveAttachmentSubtable : GlyphPositioningSubtable
le_uint16 entryExitCount; le_uint16 entryExitCount;
EntryExitRecord entryExitRecords[ANY_NUMBER]; 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 U_NAMESPACE_END
#endif #endif
......
...@@ -57,6 +57,7 @@ private: ...@@ -57,6 +57,7 @@ private:
static const le_uint16 fieldSignBits[]; static const le_uint16 fieldSignBits[];
static const le_uint16 fieldBits[]; static const le_uint16 fieldBits[];
}; };
LE_VAR_ARRAY(DeviceTable, deltaValues)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -47,6 +47,8 @@ U_NAMESPACE_BEGIN ...@@ -47,6 +47,8 @@ U_NAMESPACE_BEGIN
le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType, le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{ {
const LEReferenceTo<ExtensionSubtable> thisRef(lookupProcessor->getReference(), success); // create a reference to this
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return 0; return 0;
} }
...@@ -55,9 +57,11 @@ le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_ ...@@ -55,9 +57,11 @@ le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_
if (elt != lookupType) { if (elt != lookupType) {
le_uint32 extOffset = READ_LONG(extensionOffset); 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; return 0;
......
...@@ -38,19 +38,20 @@ ...@@ -38,19 +38,20 @@
U_NAMESPACE_BEGIN 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)) { if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
return 0; return LEReferenceTo<FeatureTable>();
} }
Offset featureTableOffset = featureRecordArray[featureIndex].featureTableOffset; Offset featureTableOffset = featureRecordArray[featureIndex].featureTableOffset;
*featureTag = SWAPT(featureRecordArray[featureIndex].featureTag); *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 * 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 * List Table are sorted alphabetically by feature tag; however, there seem
...@@ -82,5 +83,6 @@ const FeatureTable *FeatureListTable::getFeatureTable(LETag featureTag) const ...@@ -82,5 +83,6 @@ const FeatureTable *FeatureListTable::getFeatureTable(LETag featureTag) const
return 0; return 0;
#endif #endif
} }
#endif
U_NAMESPACE_END U_NAMESPACE_END
...@@ -36,9 +36,12 @@ ...@@ -36,9 +36,12 @@
U_NAMESPACE_BEGIN 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() GDEFMarkFilter::~GDEFMarkFilter()
......
...@@ -46,13 +46,13 @@ U_NAMESPACE_BEGIN ...@@ -46,13 +46,13 @@ U_NAMESPACE_BEGIN
class GDEFMarkFilter : public UMemory, public LEGlyphFilter class GDEFMarkFilter : public UMemory, public LEGlyphFilter
{ {
private: private:
const GlyphClassDefinitionTable *classDefTable; const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
GDEFMarkFilter(const GDEFMarkFilter &other); // forbid copying of this class GDEFMarkFilter(const GDEFMarkFilter &other); // forbid copying of this class
GDEFMarkFilter &operator=(const GDEFMarkFilter &other); // forbid copying of this class GDEFMarkFilter &operator=(const GDEFMarkFilter &other); // forbid copying of this class
public: public:
GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable); GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~GDEFMarkFilter(); virtual ~GDEFMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const; virtual le_bool accept(LEGlyphID glyph) const;
......
...@@ -41,9 +41,10 @@ U_NAMESPACE_BEGIN ...@@ -41,9 +41,10 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine) 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) : LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable)
{ {
fMorphTable.orphan();
// nothing else to do? // nothing else to do?
} }
...@@ -70,7 +71,7 @@ le_int32 GXLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, ...@@ -70,7 +71,7 @@ le_int32 GXLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset,
return 0; return 0;
} }
fMorphTable->process(glyphStorage); fMorphTable->process(fMorphTable, glyphStorage, success);
return count; return count;
} }
......
...@@ -74,7 +74,7 @@ public: ...@@ -74,7 +74,7 @@ public:
* *
* @internal * @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. * The destructor, virtual for correct polymorphic invocation.
...@@ -104,7 +104,7 @@ protected: ...@@ -104,7 +104,7 @@ protected:
* *
* @internal * @internal
*/ */
const MorphTableHeader *fMorphTable; LEReferenceTo<MorphTableHeader> fMorphTable;
/** /**
* This method does GX layout using the font's 'mort' table. It converts the * This method does GX layout using the font's 'mort' table. It converts the
......
...@@ -39,10 +39,10 @@ U_NAMESPACE_BEGIN ...@@ -39,10 +39,10 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2)
GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success) 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) : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
{ {
// nothing else to do? // nothing else to do?
} }
GXLayoutEngine2::~GXLayoutEngine2() GXLayoutEngine2::~GXLayoutEngine2()
...@@ -68,7 +68,7 @@ le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset ...@@ -68,7 +68,7 @@ le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset
return 0; return 0;
} }
fMorphTable->process(glyphStorage, fTypoFlags); fMorphTable->process(fMorphTable, glyphStorage, fTypoFlags, success);
return count; return count;
} }
......
...@@ -73,7 +73,7 @@ public: ...@@ -73,7 +73,7 @@ public:
* *
* @internal * @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. * The destructor, virtual for correct polymorphic invocation.
...@@ -103,7 +103,7 @@ protected: ...@@ -103,7 +103,7 @@ protected:
* *
* @internal * @internal
*/ */
const MorphTableHeader2 *fMorphTable; const LEReferenceTo<MorphTableHeader2> fMorphTable;
/** /**
* This method does GX layout using the font's 'mort' table. It converts the * This method does GX layout using the font's 'mort' table. It converts the
......
...@@ -36,24 +36,36 @@ ...@@ -36,24 +36,36 @@
U_NAMESPACE_BEGIN 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 U_NAMESPACE_END
...@@ -60,12 +60,14 @@ struct AttachmentListTable ...@@ -60,12 +60,14 @@ struct AttachmentListTable
le_uint16 glyphCount; le_uint16 glyphCount;
Offset attachPointTableOffsetArray[ANY_NUMBER]; Offset attachPointTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(AttachmentListTable, attachPointTableOffsetArray)
struct AttachPointTable struct AttachPointTable
{ {
le_uint16 pointCount; le_uint16 pointCount;
le_uint16 pointIndexArray[ANY_NUMBER]; le_uint16 pointIndexArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(AttachPointTable, pointIndexArray)
struct LigatureCaretListTable struct LigatureCaretListTable
{ {
...@@ -73,12 +75,14 @@ struct LigatureCaretListTable ...@@ -73,12 +75,14 @@ struct LigatureCaretListTable
le_uint16 ligGlyphCount; le_uint16 ligGlyphCount;
Offset ligGlyphTableOffsetArray[ANY_NUMBER]; Offset ligGlyphTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(LigatureCaretListTable, ligGlyphTableOffsetArray)
struct LigatureGlyphTable struct LigatureGlyphTable
{ {
le_uint16 caretCount; le_uint16 caretCount;
Offset caretValueTableOffsetArray[ANY_NUMBER]; Offset caretValueTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(LigatureGlyphTable, caretValueTableOffsetArray)
struct CaretValueTable struct CaretValueTable
{ {
...@@ -111,10 +115,18 @@ struct GlyphDefinitionTableHeader ...@@ -111,10 +115,18 @@ struct GlyphDefinitionTableHeader
Offset ligCaretListOffset; Offset ligCaretListOffset;
Offset MarkAttachClassDefOffset; Offset MarkAttachClassDefOffset;
const GlyphClassDefinitionTable *getGlyphClassDefinitionTable() const; const LEReferenceTo<GlyphClassDefinitionTable>
const AttachmentListTable *getAttachmentListTable()const ; getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
const LigatureCaretListTable *getLigatureCaretListTable() const; LEErrorCode &success) const;
const MarkAttachClassDefinitionTable *getMarkAttachClassDefinitionTable() 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 U_NAMESPACE_END
......
...@@ -41,18 +41,21 @@ ...@@ -41,18 +41,21 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, 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), : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0), 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(); le_int32 glyphCount = glyphStorage.getGlyphCount();
if (theGlyphDefinitionTableHeader != NULL) { if (theGlyphDefinitionTableHeader.isValid()) {
glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable(); glyphClassDefinitionTable = theGlyphDefinitionTableHeader
markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable(); -> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success);
markAttachClassDefinitionTable = theGlyphDefinitionTableHeader
->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success);
} }
nextLimit = glyphCount; nextLimit = glyphCount;
...@@ -380,6 +383,7 @@ void GlyphIterator::setCursiveGlyph() ...@@ -380,6 +383,7 @@ void GlyphIterator::setCursiveGlyph()
le_bool GlyphIterator::filterGlyph(le_uint32 index) const le_bool GlyphIterator::filterGlyph(le_uint32 index) const
{ {
LEErrorCode success = LE_NO_ERROR;
LEGlyphID glyphID = glyphStorage[index]; LEGlyphID glyphID = glyphStorage[index];
le_int32 glyphClass = gcdNoGlyphClass; le_int32 glyphClass = gcdNoGlyphClass;
...@@ -387,8 +391,8 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const ...@@ -387,8 +391,8 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const
return TRUE; return TRUE;
} }
if (glyphClassDefinitionTable != NULL) { if (glyphClassDefinitionTable.isValid()) {
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID); glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
} }
switch (glyphClass) switch (glyphClass)
...@@ -410,8 +414,9 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const ...@@ -410,8 +414,9 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift; le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) { if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType; return markAttachClassDefinitionTable
-> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType;
} }
return FALSE; return FALSE;
...@@ -461,6 +466,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta) ...@@ -461,6 +466,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta)
while (newPosition != nextLimit && delta > 0) { while (newPosition != nextLimit && delta > 0) {
do { do {
newPosition += direction; newPosition += direction;
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
} while (newPosition != nextLimit && filterGlyph(newPosition)); } while (newPosition != nextLimit && filterGlyph(newPosition));
delta -= 1; delta -= 1;
...@@ -468,6 +474,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta) ...@@ -468,6 +474,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta)
position = newPosition; position = newPosition;
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
return position != nextLimit; return position != nextLimit;
} }
...@@ -483,6 +490,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta) ...@@ -483,6 +490,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta)
while (newPosition != prevLimit && delta > 0) { while (newPosition != prevLimit && delta > 0) {
do { do {
newPosition -= direction; newPosition -= direction;
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
} while (newPosition != prevLimit && filterGlyph(newPosition)); } while (newPosition != prevLimit && filterGlyph(newPosition));
delta -= 1; delta -= 1;
...@@ -490,6 +498,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta) ...@@ -490,6 +498,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta)
position = newPosition; position = newPosition;
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
return position != prevLimit; return position != prevLimit;
} }
......
...@@ -49,7 +49,7 @@ class GlyphPositionAdjustments; ...@@ -49,7 +49,7 @@ class GlyphPositionAdjustments;
class GlyphIterator : public UMemory { class GlyphIterator : public UMemory {
public: public:
GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, 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); GlyphIterator(GlyphIterator &that);
...@@ -117,8 +117,8 @@ private: ...@@ -117,8 +117,8 @@ private:
FeatureMask featureMask; FeatureMask featureMask;
le_int32 glyphGroup; le_int32 glyphGroup;
const GlyphClassDefinitionTable *glyphClassDefinitionTable; LEReferenceTo<GlyphClassDefinitionTable> glyphClassDefinitionTable;
const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable; LEReferenceTo<MarkAttachClassDefinitionTable> markAttachClassDefinitionTable;
GlyphIterator &operator=(const GlyphIterator &other); // forbid copying of this class GlyphIterator &operator=(const GlyphIterator &other); // forbid copying of this class
}; };
......
...@@ -37,21 +37,22 @@ ...@@ -37,21 +37,22 @@
U_NAMESPACE_BEGIN 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)); LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
const LangSysTable *langSysTable = scriptListTable->findLanguage(scriptTag, languageTag, exactMatch); LEReferenceTo<LangSysTable> langSysTable = scriptListTable->findLanguage(scriptListTable,
scriptTag, languageTag, success, exactMatch);
// FIXME: could check featureListOffset, lookupListOffset, and lookup count... // FIXME: could check featureListOffset, lookupListOffset, and lookup count...
// Note: don't have to SWAPW langSysTable->featureCount to check for non-zero. // 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 U_NAMESPACE_END
...@@ -49,8 +49,8 @@ struct GlyphLookupTableHeader ...@@ -49,8 +49,8 @@ struct GlyphLookupTableHeader
Offset featureListOffset; Offset featureListOffset;
Offset lookupListOffset; Offset lookupListOffset;
le_bool coversScript(LETag scriptTag) const; le_bool coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const;
le_bool coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const; le_bool coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -41,16 +41,16 @@ ...@@ -41,16 +41,16 @@
U_NAMESPACE_BEGIN 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, 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 const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
{ {
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return; return;
} }
GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success); GlyphPositioningLookupProcessor processor(base, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return; return;
} }
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
#include "Lookups.h" #include "Lookups.h"
#include "GlyphLookupTables.h" #include "GlyphLookupTables.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
...@@ -51,9 +52,9 @@ struct GlyphDefinitionTableHeader; ...@@ -51,9 +52,9 @@ struct GlyphDefinitionTableHeader;
struct GlyphPositioningTableHeader : public GlyphLookupTableHeader 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, 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; const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
}; };
......
...@@ -57,7 +57,7 @@ typedef ContextualSubstitutionSubtable ContextualPositioningSubtable; ...@@ -57,7 +57,7 @@ typedef ContextualSubstitutionSubtable ContextualPositioningSubtable;
typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubtable; typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubtable;
GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor( GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
const GlyphPositioningTableHeader *glyphPositioningTableHeader, const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
LETag scriptTag, LETag scriptTag,
LETag languageTag, LETag languageTag,
const FeatureMap *featureMap, const FeatureMap *featureMap,
...@@ -65,7 +65,7 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor( ...@@ -65,7 +65,7 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
le_bool featureOrder, le_bool featureOrder,
LEErrorCode& success) LEErrorCode& success)
: LookupProcessor( : LookupProcessor(
(char *) glyphPositioningTableHeader, glyphPositioningTableHeader,
SWAPW(glyphPositioningTableHeader->scriptListOffset), SWAPW(glyphPositioningTableHeader->scriptListOffset),
SWAPW(glyphPositioningTableHeader->featureListOffset), SWAPW(glyphPositioningTableHeader->featureListOffset),
SWAPW(glyphPositioningTableHeader->lookupListOffset), SWAPW(glyphPositioningTableHeader->lookupListOffset),
...@@ -84,7 +84,7 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor() ...@@ -84,7 +84,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, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
LEErrorCode& success) const LEErrorCode& success) const
...@@ -102,55 +102,55 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l ...@@ -102,55 +102,55 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
case gpstSingle: 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; break;
} }
case gpstPair: 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; break;
} }
case gpstCursive: 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; break;
} }
case gpstMarkToBase: 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; break;
} }
case gpstMarkToLigature: 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; break;
} }
case gpstMarkToMark: 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; break;
} }
case gpstContext: case gpstContext:
{ {
const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable; LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
...@@ -158,7 +158,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l ...@@ -158,7 +158,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
case gpstChainedContext: case gpstChainedContext:
{ {
const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable; LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
...@@ -166,7 +166,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l ...@@ -166,7 +166,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
case gpstExtension: case gpstExtension:
{ {
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success); delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break; break;
......
...@@ -51,7 +51,7 @@ U_NAMESPACE_BEGIN ...@@ -51,7 +51,7 @@ U_NAMESPACE_BEGIN
class GlyphPositioningLookupProcessor : public LookupProcessor class GlyphPositioningLookupProcessor : public LookupProcessor
{ {
public: public:
GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader, GlyphPositioningLookupProcessor(const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
LETag scriptTag, LETag scriptTag,
LETag languageTag, LETag languageTag,
const FeatureMap *featureMap, const FeatureMap *featureMap,
...@@ -61,7 +61,7 @@ public: ...@@ -61,7 +61,7 @@ public:
virtual ~GlyphPositioningLookupProcessor(); 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; const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected: protected:
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor( GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
LETag scriptTag, LETag scriptTag,
LETag languageTag, LETag languageTag,
const LEGlyphFilter *filter, const LEGlyphFilter *filter,
...@@ -60,7 +60,7 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor( ...@@ -60,7 +60,7 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
le_bool featureOrder, le_bool featureOrder,
LEErrorCode& success) LEErrorCode& success)
: LookupProcessor( : LookupProcessor(
(char *) glyphSubstitutionTableHeader, glyphSubstitutionTableHeader,
SWAPW(glyphSubstitutionTableHeader->scriptListOffset), SWAPW(glyphSubstitutionTableHeader->scriptListOffset),
SWAPW(glyphSubstitutionTableHeader->featureListOffset), SWAPW(glyphSubstitutionTableHeader->featureListOffset),
SWAPW(glyphSubstitutionTableHeader->lookupListOffset), SWAPW(glyphSubstitutionTableHeader->lookupListOffset),
...@@ -73,7 +73,7 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor() ...@@ -73,7 +73,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 GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
...@@ -89,39 +89,39 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * ...@@ -89,39 +89,39 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
case gsstSingle: 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; break;
} }
case gsstMultiple: 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; break;
} }
case gsstAlternate: 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; break;
} }
case gsstLigature: 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; break;
} }
case gsstContext: case gsstContext:
{ {
const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable; const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
...@@ -129,7 +129,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * ...@@ -129,7 +129,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
case gsstChainingContext: case gsstChainingContext:
{ {
const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable; const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
...@@ -137,7 +137,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * ...@@ -137,7 +137,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
case gsstExtension: case gsstExtension:
{ {
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success); delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break; break;
......
...@@ -52,7 +52,7 @@ U_NAMESPACE_BEGIN ...@@ -52,7 +52,7 @@ U_NAMESPACE_BEGIN
class GlyphSubstitutionLookupProcessor : public LookupProcessor class GlyphSubstitutionLookupProcessor : public LookupProcessor
{ {
public: public:
GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, GlyphSubstitutionLookupProcessor(const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
LETag scriptTag, LETag scriptTag,
LETag languageTag, LETag languageTag,
const LEGlyphFilter *filter, const LEGlyphFilter *filter,
...@@ -63,7 +63,7 @@ public: ...@@ -63,7 +63,7 @@ public:
virtual ~GlyphSubstitutionLookupProcessor(); 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; const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected: protected:
......
...@@ -42,11 +42,12 @@ ...@@ -42,11 +42,12 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, le_int32 GlyphSubstitutionTableHeader::process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
LEGlyphStorage &glyphStorage,
le_bool rightToLeft, le_bool rightToLeft,
LETag scriptTag, LETag scriptTag,
LETag languageTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
const LEGlyphFilter *filter, const LEGlyphFilter *filter,
const FeatureMap *featureMap, const FeatureMap *featureMap,
le_int32 featureMapCount, le_int32 featureMapCount,
...@@ -57,7 +58,7 @@ le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, ...@@ -57,7 +58,7 @@ le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage,
return 0; 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); return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success);
} }
......
...@@ -50,11 +50,12 @@ struct GlyphDefinitionTableHeader; ...@@ -50,11 +50,12 @@ struct GlyphDefinitionTableHeader;
struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
{ {
le_int32 process(LEGlyphStorage &glyphStorage, le_int32 process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
LEGlyphStorage &glyphStorage,
le_bool rightToLeft, le_bool rightToLeft,
LETag scriptTag, LETag scriptTag,
LETag languageTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
const LEGlyphFilter *filter, const LEGlyphFilter *filter,
const FeatureMap *featureMap, const FeatureMap *featureMap,
le_int32 featureMapCount, le_int32 featureMapCount,
......
...@@ -64,7 +64,7 @@ static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); ...@@ -64,7 +64,7 @@ static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
#define features (loclFeatureMask) #define features (loclFeatureMask)
HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = featureMap; fFeatureMap = featureMap;
......
...@@ -73,7 +73,7 @@ public: ...@@ -73,7 +73,7 @@ public:
* @internal * @internal
*/ */
HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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);
/** /**
......
...@@ -209,7 +209,7 @@ static le_int32 getCharClass(LEUnicode ch, LEUnicode &lead, LEUnicode &vowel, LE ...@@ -209,7 +209,7 @@ static le_int32 getCharClass(LEUnicode ch, LEUnicode &lead, LEUnicode &vowel, LE
} }
HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/, 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) : OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = featureMap; fFeatureMap = featureMap;
......
...@@ -79,7 +79,7 @@ public: ...@@ -79,7 +79,7 @@ public:
* @internal * @internal
*/ */
HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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 * This constructor is used when the font requires a "canned" GSUB table which can't be known
......
...@@ -54,16 +54,21 @@ struct FeatureTable ...@@ -54,16 +54,21 @@ struct FeatureTable
le_uint16 lookupCount; le_uint16 lookupCount;
le_uint16 lookupListIndexArray[ANY_NUMBER]; le_uint16 lookupListIndexArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(FeatureTable, lookupListIndexArray)
struct FeatureListTable struct FeatureListTable
{ {
le_uint16 featureCount; le_uint16 featureCount;
FeatureRecord featureRecordArray[ANY_NUMBER]; 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 U_NAMESPACE_END
#endif #endif
...@@ -50,7 +50,7 @@ U_NAMESPACE_BEGIN ...@@ -50,7 +50,7 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
{ {
if ( version2 ) { if ( version2 ) {
......
...@@ -81,7 +81,7 @@ public: ...@@ -81,7 +81,7 @@ public:
* @internal * @internal
*/ */
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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 * This constructor is used when the font requires a "canned" GSUB table which can't be known
......
...@@ -43,11 +43,14 @@ U_NAMESPACE_BEGIN ...@@ -43,11 +43,14 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader) IndicRearrangementProcessor::IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader) : 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() IndicRearrangementProcessor::~IndicRearrangementProcessor()
...@@ -62,7 +65,8 @@ void IndicRearrangementProcessor::beginStateTable() ...@@ -62,7 +65,8 @@ void IndicRearrangementProcessor::beginStateTable()
ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) 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); ByteOffset newState = SWAPW(entry->newStateOffset);
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags); IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
......
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const; void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader); IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~IndicRearrangementProcessor(); virtual ~IndicRearrangementProcessor();
/** /**
...@@ -79,8 +79,9 @@ protected: ...@@ -79,8 +79,9 @@ protected:
le_int32 firstGlyph; le_int32 firstGlyph;
le_int32 lastGlyph; le_int32 lastGlyph;
const IndicRearrangementStateEntry *entryTable; LEReferenceTo<IndicRearrangementSubtableHeader> indicRearrangementSubtableHeader;
const IndicRearrangementSubtableHeader *indicRearrangementSubtableHeader; LEReferenceToArrayOf<IndicRearrangementStateEntry> entryTable;
LEReferenceToArrayOf<le_int16> int16Table;
}; };
......
...@@ -43,11 +43,11 @@ U_NAMESPACE_BEGIN ...@@ -43,11 +43,11 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) IndicRearrangementProcessor2::IndicRearrangementProcessor2(
: StateTableProcessor2(morphSubtableHeader) 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() IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
...@@ -60,9 +60,11 @@ void IndicRearrangementProcessor2::beginStateTable() ...@@ -60,9 +60,11 @@ void IndicRearrangementProcessor2::beginStateTable()
lastGlyph = 0; 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 le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags); IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
......
...@@ -52,13 +52,13 @@ class IndicRearrangementProcessor2 : public StateTableProcessor2 ...@@ -52,13 +52,13 @@ class IndicRearrangementProcessor2 : public StateTableProcessor2
public: public:
virtual void beginStateTable(); 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(); virtual void endStateTable();
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const; void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); IndicRearrangementProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~IndicRearrangementProcessor2(); virtual ~IndicRearrangementProcessor2();
/** /**
...@@ -79,8 +79,8 @@ protected: ...@@ -79,8 +79,8 @@ protected:
le_int32 firstGlyph; le_int32 firstGlyph;
le_int32 lastGlyph; le_int32 lastGlyph;
const IndicRearrangementStateEntry2 *entryTable; LEReferenceToArrayOf<IndicRearrangementStateEntry2> entryTable;
const IndicRearrangementSubtableHeader2 *indicRearrangementSubtableHeader; LEReferenceTo<IndicRearrangementSubtableHeader2> indicRearrangementSubtableHeader;
}; };
......
...@@ -658,6 +658,11 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le ...@@ -658,6 +658,11 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
MPreFixups *mpreFixups = NULL; MPreFixups *mpreFixups = NULL;
const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode); const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
if(classTable==NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
if (classTable->scriptFlags & SF_MPRE_FIXUP) { if (classTable->scriptFlags & SF_MPRE_FIXUP) {
mpreFixups = new MPreFixups(charCount); mpreFixups = new MPreFixups(charCount);
if (mpreFixups == NULL) { if (mpreFixups == NULL) {
......
...@@ -48,7 +48,7 @@ struct PairInfo { ...@@ -48,7 +48,7 @@ struct PairInfo {
le_int16 value; // fword, kern value in funits le_int16 value; // fword, kern value in funits
}; };
#define KERN_PAIRINFO_SIZE 6 #define KERN_PAIRINFO_SIZE 6
LE_CORRECT_SIZE(PairInfo, KERN_PAIRINFO_SIZE)
struct Subtable_0 { struct Subtable_0 {
le_uint16 nPairs; le_uint16 nPairs;
le_uint16 searchRange; le_uint16 searchRange;
...@@ -56,6 +56,7 @@ struct Subtable_0 { ...@@ -56,6 +56,7 @@ struct Subtable_0 {
le_uint16 rangeShift; le_uint16 rangeShift;
}; };
#define KERN_SUBTABLE_0_HEADER_SIZE 8 #define KERN_SUBTABLE_0_HEADER_SIZE 8
LE_CORRECT_SIZE(Subtable_0, KERN_SUBTABLE_0_HEADER_SIZE)
// Kern table version 0 only // Kern table version 0 only
struct SubtableHeader { struct SubtableHeader {
...@@ -64,6 +65,7 @@ struct SubtableHeader { ...@@ -64,6 +65,7 @@ struct SubtableHeader {
le_uint16 coverage; le_uint16 coverage;
}; };
#define KERN_SUBTABLE_HEADER_SIZE 6 #define KERN_SUBTABLE_HEADER_SIZE 6
LE_CORRECT_SIZE(SubtableHeader, KERN_SUBTABLE_HEADER_SIZE)
// Version 0 only, version 1 has different layout // Version 0 only, version 1 has different layout
struct KernTableHeader { struct KernTableHeader {
...@@ -71,6 +73,7 @@ struct KernTableHeader { ...@@ -71,6 +73,7 @@ struct KernTableHeader {
le_uint16 nTables; le_uint16 nTables;
}; };
#define KERN_TABLE_HEADER_SIZE 4 #define KERN_TABLE_HEADER_SIZE 4
LE_CORRECT_SIZE(KernTableHeader, KERN_TABLE_HEADER_SIZE)
#define COVERAGE_HORIZONTAL 0x1 #define COVERAGE_HORIZONTAL 0x1
#define COVERAGE_MINIMUM 0x2 #define COVERAGE_MINIMUM 0x2
...@@ -92,21 +95,21 @@ struct KernTableHeader { ...@@ -92,21 +95,21 @@ struct KernTableHeader {
* TODO: support multiple subtables * TODO: support multiple subtables
* TODO: respect header flags * TODO: respect header flags
*/ */
KernTable::KernTable(const LEFontInstance* font_, const void* tableData) KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
: pairs(0), font(font_) : pairs(), pairsSwapped(NULL), fTable(base)
{ {
const KernTableHeader* header = (const KernTableHeader*)tableData; if(LE_FAILURE(success) || (fTable.isEmpty())) {
if (header == 0) {
#if DEBUG #if DEBUG
fprintf(stderr, "no kern data\n"); fprintf(stderr, "no kern data\n");
#endif #endif
return; return;
} }
LEReferenceTo<KernTableHeader> header(fTable, success);
#if DEBUG #if DEBUG
// dump first 32 bytes of header // dump first 32 bytes of header
for (int i = 0; i < 64; ++i) { 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) { if (((i+1)&0xf) == 0) {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} else if (((i+1)&0x7) == 0) { } else if (((i+1)&0x7) == 0) {
...@@ -115,12 +118,17 @@ KernTable::KernTable(const LEFontInstance* font_, const void* tableData) ...@@ -115,12 +118,17 @@ KernTable::KernTable(const LEFontInstance* font_, const void* tableData)
} }
#endif #endif
if (header->version == 0 && SWAPW(header->nTables) > 0) { if(LE_FAILURE(success)) return;
const SubtableHeader* subhead = (const SubtableHeader*)((char*)tableData + KERN_TABLE_HEADER_SIZE);
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); coverage = SWAPW(subhead->coverage);
if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning 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); nPairs = SWAPW(table->nPairs);
...@@ -134,19 +142,31 @@ KernTable::KernTable(const LEFontInstance* font_, const void* tableData) ...@@ -134,19 +142,31 @@ KernTable::KernTable(const LEFontInstance* font_, const void* tableData)
rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange; rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange;
#endif #endif
pairs = (PairInfo*)font->getKernPairs(); if(LE_SUCCESS(success) && nPairs>0) {
if (pairs == NULL) { // pairs is an instance member, and table is on the stack.
char *pairData = (char*)table + KERN_SUBTABLE_0_HEADER_SIZE; // set 'pairs' based on table.getAlias(). This will range check it.
char *pptr = pairData;
pairs = (PairInfo*)(malloc(nPairs*sizeof(PairInfo))); pairs = LEReferenceToArrayOf<PairInfo>(fTable, // based on overall table
PairInfo *p = (PairInfo*)pairs; success,
for (int i = 0; i < nPairs; i++, pptr += KERN_PAIRINFO_SIZE, p++) { (const PairInfo*)table.getAlias(), // subtable 0 + ..
memcpy(p, pptr, KERN_PAIRINFO_SIZE); KERN_SUBTABLE_0_HEADER_SIZE, // .. offset of header size
nPairs); // count
}
if (LE_SUCCESS(success) && pairs.isValid()) {
pairsSwapped = (PairInfo*)(malloc(nPairs*sizeof(PairInfo)));
PairInfo *p = (PairInfo*)pairsSwapped;
for (int i = 0; LE_SUCCESS(success) && i < nPairs; i++, p++) {
memcpy(p, pairs.getAlias(i,success), KERN_PAIRINFO_SIZE);
p->key = SWAPL(p->key); p->key = SWAPL(p->key);
} }
font->setKernPairs((void*)pairs); fTable.getFont()->setKernPairs((void*)pairsSwapped); // store it
} }
#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 #if DEBUG
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs); fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs);
fprintf(stderr, fprintf(stderr,
...@@ -194,14 +214,17 @@ KernTable::KernTable(const LEFontInstance* font_, const void* tableData) ...@@ -194,14 +214,17 @@ KernTable::KernTable(const LEFontInstance* font_, const void* tableData)
* Process the glyph positions. The positions array has two floats for each * 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. * 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) { if(LE_FAILURE(success)) return;
LEErrorCode success = LE_NO_ERROR;
if (pairsSwapped) {
success = LE_NO_ERROR;
le_uint32 key = storage[0]; // no need to mask off high bits le_uint32 key = storage[0]; // no need to mask off high bits
float adjust = 0; 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); key = key << 16 | (storage[i] & 0xffff);
// argh, to do a binary search, we need to have the pair list in sorted order // argh, to do a binary search, we need to have the pair list in sorted order
...@@ -209,7 +232,7 @@ void KernTable::process(LEGlyphStorage& storage) ...@@ -209,7 +232,7 @@ void KernTable::process(LEGlyphStorage& storage)
// so either I have to swap the element each time I examine it, or I have to swap // 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 // all the elements ahead of time and store them in the font
const PairInfo* p = pairs; const PairInfo* p = pairsSwapped;
const PairInfo* tp = (const PairInfo*)(p + (rangeShift/KERN_PAIRINFO_SIZE)); /* rangeshift is in original table bytes */ const PairInfo* tp = (const PairInfo*)(p + (rangeShift/KERN_PAIRINFO_SIZE)); /* rangeshift is in original table bytes */
if (key > tp->key) { if (key > tp->key) {
p = tp; p = tp;
...@@ -225,7 +248,7 @@ void KernTable::process(LEGlyphStorage& storage) ...@@ -225,7 +248,7 @@ void KernTable::process(LEGlyphStorage& storage)
tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE)); tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE));
le_uint32 tkey = tp->key; le_uint32 tkey = tp->key;
#if DEBUG #if DEBUG
fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairs), tkey); fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
#endif #endif
if (tkey <= key) { if (tkey <= key) {
if (tkey == key) { if (tkey == key) {
...@@ -240,10 +263,10 @@ void KernTable::process(LEGlyphStorage& storage) ...@@ -240,10 +263,10 @@ void KernTable::process(LEGlyphStorage& storage)
// device transform, or a faster way, such as moving the // device transform, or a faster way, such as moving the
// entire kern table up to Java. // entire kern table up to Java.
LEPoint pt; LEPoint pt;
pt.fX = font->xUnitsToPoints(value); pt.fX = fTable.getFont()->xUnitsToPoints(value);
pt.fY = 0; pt.fY = 0;
font->getKerningAdjustment(pt); fTable.getFont()->getKerningAdjustment(pt);
adjust += pt.fX; adjust += pt.fX;
break; break;
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* *
* (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved * (C) Copyright IBM Corp. 2004-2013 - All Rights Reserved
* *
*/ */
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#endif #endif
#include "LETypes.h" #include "LETypes.h"
#include "LETableReference.h"
//#include "LEFontInstance.h" //#include "LEFontInstance.h"
//#include "LEGlyphStorage.h" //#include "LEGlyphStorage.h"
...@@ -56,19 +57,20 @@ class U_LAYOUT_API KernTable ...@@ -56,19 +57,20 @@ class U_LAYOUT_API KernTable
private: private:
le_uint16 coverage; le_uint16 coverage;
le_uint16 nPairs; le_uint16 nPairs;
const PairInfo* pairs; LEReferenceToArrayOf<PairInfo> pairs;
const LEFontInstance* font; PairInfo *pairsSwapped;
const LETableReference &fTable;
le_uint16 searchRange; le_uint16 searchRange;
le_uint16 entrySelector; le_uint16 entrySelector;
le_uint16 rangeShift; le_uint16 rangeShift;
public: public:
KernTable(const LEFontInstance* font, const void* tableData); KernTable(const LETableReference &table, LEErrorCode &success);
/* /*
* Process the glyph positions. * Process the glyph positions.
*/ */
void process(LEGlyphStorage& storage); void process(LEGlyphStorage& storage, LEErrorCode &success);
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -43,7 +43,7 @@ U_NAMESPACE_BEGIN ...@@ -43,7 +43,7 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine)
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
......
...@@ -83,7 +83,7 @@ public: ...@@ -83,7 +83,7 @@ public:
* @internal * @internal
*/ */
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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 * This constructor is used when the font requires a "canned" GSUB table which can't be known
......
...@@ -258,10 +258,11 @@ enum ScriptCodes { ...@@ -258,10 +258,11 @@ enum ScriptCodes {
* @stable ICU 49 * @stable ICU 49
*/ */
khojScriptCode = 156, hluwScriptCode = 156, /* bump to match current ICU */
tirhScriptCode = 157, khojScriptCode = 157,
tirhScriptCode = 158,
scriptCodeCount = 158 scriptCodeCount = 159
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* -*- 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* getAliasTODO() const { LE_DEBUG_TR("getAliasTODO()"); 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 *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); 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 *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
};
U_NAMESPACE_END
#endif
#endif
...@@ -354,12 +354,15 @@ typedef struct LEPoint LEPoint; ...@@ -354,12 +354,15 @@ typedef struct LEPoint LEPoint;
/** /**
* Max value representable by a uintptr * Max value representable by a uintptr
*/ */
#ifndef UINTPTR_MAX
#ifndef UINT32_MAX #ifndef UINT32_MAX
#define LE_UINTPTR_MAX 0xFFFFFFFFU #define LE_UINT32_MAX 0xFFFFFFFFU
#else #else
#define LE_UINTPTR_MAX UINT32_MAX #define LE_UINT32_MAX UINT32_MAX
#endif #endif
#ifndef UINTPTR_MAX
#define LE_UINTPTR_MAX LE_UINT32_MAX
#else #else
#define LE_UINTPTR_MAX UINTPTR_MAX #define LE_UINTPTR_MAX UINTPTR_MAX
#endif #endif
......
...@@ -147,21 +147,21 @@ CharSubstitutionFilter::~CharSubstitutionFilter() ...@@ -147,21 +147,21 @@ CharSubstitutionFilter::~CharSubstitutionFilter()
class CanonMarkFilter : public UMemory, public LEGlyphFilter class CanonMarkFilter : public UMemory, public LEGlyphFilter
{ {
private: private:
const GlyphClassDefinitionTable *classDefTable; const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
public: public:
CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable); CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~CanonMarkFilter(); virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const; 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() CanonMarkFilter::~CanonMarkFilter()
...@@ -171,9 +171,10 @@ CanonMarkFilter::~CanonMarkFilter() ...@@ -171,9 +171,10 @@ CanonMarkFilter::~CanonMarkFilter()
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
{ {
le_int32 glyphClass = classDefTable->getGlyphClass(glyph); LEErrorCode success = LE_NO_ERROR;
le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
return glyphClass != 0; if(LE_FAILURE(success)) return false;
return glyphClass != 0;
} }
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
...@@ -262,20 +263,20 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -262,20 +263,20 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
return count; return count;
} }
const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable);
LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode); LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode); LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
le_int32 i, dir = 1, out = 0, outCharCount = count; 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); CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
if (substitutionFilter == NULL) { if (substitutionFilter == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
return 0; return 0;
} }
const LEUnicode *inChars = &chars[offset]; const LEUnicode *inChars = &chars[offset];
LEUnicode *reordered = NULL; LEUnicode *reordered = NULL;
LEGlyphStorage fakeGlyphStorage; LEGlyphStorage fakeGlyphStorage;
fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success); fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success);
...@@ -285,20 +286,20 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -285,20 +286,20 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
return 0; return 0;
} }
// This is the cheapest way to get mark reordering only for Hebrew. // This is the cheapest way to get mark reordering only for Hebrew.
// We could just do the mark reordering for all scripts, but most // We could just do the mark reordering for all scripts, but most
// of them probably don't need it... // of them probably don't need it...
if (fScriptCode == hebrScriptCode) { if (fScriptCode == hebrScriptCode) {
reordered = LE_NEW_ARRAY(LEUnicode, count); reordered = LE_NEW_ARRAY(LEUnicode, count);
if (reordered == NULL) { if (reordered == NULL) {
delete substitutionFilter; delete substitutionFilter;
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
return 0; return 0;
} }
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage); CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
inChars = reordered; inChars = reordered;
} }
fakeGlyphStorage.allocateAuxData(success); fakeGlyphStorage.allocateAuxData(success);
...@@ -318,11 +319,11 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -318,11 +319,11 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
fakeGlyphStorage.setAuxData(out, canonFeatures, success); fakeGlyphStorage.setAuxData(out, canonFeatures, success);
} }
if (reordered != NULL) { if (reordered != NULL) {
LE_DELETE_ARRAY(reordered); 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)) { if (LE_FAILURE(success)) {
delete substitutionFilter; delete substitutionFilter;
...@@ -423,16 +424,16 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset ...@@ -423,16 +424,16 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset
return; return;
} }
GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
CanonMarkFilter filter(gdefTable); CanonShaping::glyphDefinitionTableLen);
CanonMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(kernTable, success);
KernTable kt(fFontInstance, getFontTable(kernTableTag)); kt.process(glyphStorage, success);
kt.process(glyphStorage);
} }
// default is no adjustments // default is no adjustments
...@@ -517,9 +518,9 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, ...@@ -517,9 +518,9 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success); 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, void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
...@@ -566,7 +567,10 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_ ...@@ -566,7 +567,10 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_
void LayoutEngine::reset() void LayoutEngine::reset()
{ {
if(fGlyphStorage!=NULL) {
fGlyphStorage->reset(); fGlyphStorage->reset();
fGlyphStorage = NULL;
}
} }
LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success) LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
...@@ -585,19 +589,19 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -585,19 +589,19 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
return NULL; return NULL;
} }
const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag); LEReferenceTo<GlyphSubstitutionTableHeader> gsubTable(fontInstance,gsubTableTag,success);
LayoutEngine *result = NULL; LayoutEngine *result = NULL;
LETag scriptTag = 0x00000000; LETag scriptTag = 0x00000000;
LETag languageTag = 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 // Right now, only invoke V2 processing for Devanagari. TODO: Allow more V2 scripts as they are
// properly tested. // properly tested.
if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) { if ( v2ScriptTag == dev2ScriptTag && gsubTable.isValid() && gsubTable->coversScript(gsubTable, v2ScriptTag, success )) {
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success); result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
} }
else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) { else if (gsubTable.isValid() && gsubTable->coversScript(gsubTable, scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode), success)) {
switch (scriptCode) { switch (scriptCode) {
case bengScriptCode: case bengScriptCode:
case devaScriptCode: case devaScriptCode:
...@@ -633,10 +637,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -633,10 +637,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case janLanguageCode: case janLanguageCode:
case zhtLanguageCode: case zhtLanguageCode:
case zhsLanguageCode: 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); result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break; break;
} }
// note: falling through to default case. // note: falling through to default case.
default: default:
...@@ -663,9 +667,9 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -663,9 +667,9 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) { if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) {
result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success); result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
} else { } else {
const MorphTableHeader *mortTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag); LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
if (mortTable != NULL && SWAPL(mortTable->version)==0x00010000) { // mort if (LE_SUCCESS(success) && mortTable.isValid() && SWAPL(mortTable->version)==0x00010000) { // mort
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success); result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
} else { } else {
switch (scriptCode) { switch (scriptCode) {
case bengScriptCode: case bengScriptCode:
......
...@@ -280,12 +280,18 @@ protected: ...@@ -280,12 +280,18 @@ protected:
* some other way must override this method. * some other way must override this method.
* *
* @param tableTag - the four byte table tag. * @param tableTag - the four byte table tag.
* @param length - length to use
* *
* @return the address of the table. * @return the address of the table.
* *
* @internal * @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 * This method does character to glyph mapping. The default implementation
......
...@@ -47,15 +47,15 @@ U_NAMESPACE_BEGIN ...@@ -47,15 +47,15 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor)
LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader) LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader) : StateTableProcessor(morphSubtableHeader, success), ligatureSubstitutionHeader(morphSubtableHeader, success)
{ {
ligatureSubstitutionHeader = (const LigatureSubstitutionHeader *) morphSubtableHeader; if(LE_FAILURE(success)) return;
ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset); ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset);
componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset); componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset);
ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset); ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset);
entryTable = (const LigatureSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset); entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
} }
LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor() LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
...@@ -69,7 +69,9 @@ void LigatureSubstitutionProcessor::beginStateTable() ...@@ -69,7 +69,9 @@ void LigatureSubstitutionProcessor::beginStateTable()
ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) 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); ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags); le_int16 flags = SWAPW(entry->flags);
...@@ -88,7 +90,7 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp ...@@ -88,7 +90,7 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp
ByteOffset actionOffset = flags & lsfActionOffsetMask; ByteOffset actionOffset = flags & lsfActionOffsetMask;
if (actionOffset != 0) { if (actionOffset != 0) {
const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset); LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
LigatureActionEntry action; LigatureActionEntry action;
le_int32 offset, i = 0; le_int32 offset, i = 0;
le_int32 stack[nComponents]; le_int32 stack[nComponents];
...@@ -97,7 +99,8 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp ...@@ -97,7 +99,8 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp
do { do {
le_uint32 componentGlyph = componentStack[m--]; le_uint32 componentGlyph = componentStack[m--];
action = SWAPL(*ap++); action = SWAPL(*ap.getAlias());
ap.addObject(success); // ap++
if (m < 0) { if (m < 0) {
m = nComponents - 1; m = nComponents - 1;
...@@ -105,37 +108,33 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp ...@@ -105,37 +108,33 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp
offset = action & lafComponentOffsetMask; offset = action & lafComponentOffsetMask;
if (offset != 0) { 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);
const le_int16 *tableEnd = (const le_int16 *)((char *) &ligatureSubstitutionHeader + 1 * SWAPW(ligatureSubstitutionHeader->length));
// Check if the font is internally consistent if(LE_FAILURE(success)) {
if(tableEnd < (const le_int16*)&ligatureSubstitutionHeader // stated end wrapped around?
|| offsetTable > tableEnd) { // offset past end of stated length?
currGlyph++; currGlyph++;
LE_DEBUG_BAD_FONT("off end of ligature substitution header"); LE_DEBUG_BAD_FONT("off end of ligature substitution header");
return newState; // get out! bad font return newState; // get out! bad font
} }
if(componentGlyph > glyphStorage.getGlyphCount()) {
if(componentGlyph > glyphStorage.getGlyphCount()) { LE_DEBUG_BAD_FONT("preposterous componentGlyph");
LE_DEBUG_BAD_FONT("preposterous componentGlyph"); currGlyph++;
currGlyph++; return newState; // get out! bad font
return newState; // get out! bad font }
} i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));
i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);
if (action & (lafLast | lafStore)) { if (action & (lafLast | lafStore)) {
const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i); LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i);
TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset); TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias());
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph); glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
if(mm==nComponents) { if(mm==nComponents) {
LE_DEBUG_BAD_FONT("exceeded nComponents"); LE_DEBUG_BAD_FONT("exceeded nComponents");
mm--; // don't overrun the stack. mm--; // don't overrun the stack.
} }
stack[++mm] = componentGlyph; stack[++mm] = componentGlyph;
i = 0; i = 0;
} else { } else {
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF); glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
} }
} }
#if LE_ASSERT_BAD_FONT #if LE_ASSERT_BAD_FONT
...@@ -146,11 +145,11 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp ...@@ -146,11 +145,11 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyp
} while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items } while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items
while (mm >= 0) { while (mm >= 0) {
if (++m >= nComponents) { if (++m >= nComponents) {
m = 0; m = 0;
} }
componentStack[m] = stack[mm--]; componentStack[m] = stack[mm--];
} }
} }
......
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
virtual void endStateTable(); virtual void endStateTable();
LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader); LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~LigatureSubstitutionProcessor(); virtual ~LigatureSubstitutionProcessor();
/** /**
...@@ -83,12 +83,12 @@ protected: ...@@ -83,12 +83,12 @@ protected:
ByteOffset componentTableOffset; ByteOffset componentTableOffset;
ByteOffset ligatureTableOffset; ByteOffset ligatureTableOffset;
const LigatureSubstitutionStateEntry *entryTable; LEReferenceToArrayOf<LigatureSubstitutionStateEntry> entryTable;
le_int32 componentStack[nComponents]; le_int32 componentStack[nComponents];
le_int16 m; le_int16 m;
const LigatureSubstitutionHeader *ligatureSubstitutionHeader; LEReferenceTo<LigatureSubstitutionHeader> ligatureSubstitutionHeader;
}; };
......
...@@ -47,15 +47,18 @@ U_NAMESPACE_BEGIN ...@@ -47,15 +47,18 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader) : 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); ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset); componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset); ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
entryTable = (const LigatureSubstitutionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset); entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
} }
LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2() LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
...@@ -67,9 +70,11 @@ void LigatureSubstitutionProcessor2::beginStateTable() ...@@ -67,9 +70,11 @@ void LigatureSubstitutionProcessor2::beginStateTable()
m = -1; 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 nextStateIndex = SWAPW(entry->nextStateIndex);
le_uint16 flags = SWAPW(entry->entryFlags); le_uint16 flags = SWAPW(entry->entryFlags);
le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex); le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
...@@ -81,7 +86,7 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp ...@@ -81,7 +86,7 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
componentStack[m] = currGlyph; componentStack[m] = currGlyph;
} else if ( m == -1) { } else if ( m == -1) {
// bad font- skip this glyph. // bad font- skip this glyph.
LE_DEBUG_BAD_FONT("m==-1") //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)")
currGlyph+= dir; currGlyph+= dir;
return nextStateIndex; return nextStateIndex;
} }
...@@ -89,29 +94,25 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp ...@@ -89,29 +94,25 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
ByteOffset actionOffset = flags & lsfPerformAction; ByteOffset actionOffset = flags & lsfPerformAction;
if (actionOffset != 0) { if (actionOffset != 0) {
const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + ligActionOffset) + ligActionIndex; LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
const TTGlyphID *ligatureTable = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + ligatureOffset); 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; LigatureActionEntry action;
le_int32 offset, i = 0; le_int32 offset, i = 0;
le_int32 stack[nComponents]; le_int32 stack[nComponents];
le_int16 mm = -1; 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)) {
const le_uint16 *tableEnd = (const le_uint16 *)((char *) &ligatureSubstitutionHeader + SWAPL(ligatureSubstitutionHeader->length));
// Check if the font is internally consistent
if(tableEnd < (const le_uint16*)&ligatureSubstitutionHeader // stated end wrapped around?
|| componentTable > tableEnd) { // offset past end of stated length?
currGlyph+= dir; currGlyph+= dir;
LE_DEBUG_BAD_FONT("ligatureSubstHeader off end of table")
return nextStateIndex; // get out! bad font return nextStateIndex; // get out! bad font
} }
do { do {
le_uint32 componentGlyph = componentStack[m--]; // pop off le_uint32 componentGlyph = componentStack[m--]; // pop off
action = SWAPL(*ap++); ap.addObject(success);
action = SWAPL(*ap.getAlias());
if (m < 0) { if (m < 0) {
m = nComponents - 1; m = nComponents - 1;
...@@ -124,10 +125,10 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp ...@@ -124,10 +125,10 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
currGlyph+= dir; currGlyph+= dir;
return nextStateIndex; // get out! bad font return nextStateIndex; // get out! bad font
} }
i += SWAPW(componentTable[LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask))]); i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
if (action & (lafLast | lafStore)) { if (action & (lafLast | lafStore)) {
TTGlyphID ligatureGlyph = SWAPW(ligatureTable[i]); TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph); glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
if(mm==nComponents) { if(mm==nComponents) {
LE_DEBUG_BAD_FONT("exceeded nComponents"); LE_DEBUG_BAD_FONT("exceeded nComponents");
......
...@@ -54,11 +54,12 @@ class LigatureSubstitutionProcessor2 : public StateTableProcessor2 ...@@ -54,11 +54,12 @@ class LigatureSubstitutionProcessor2 : public StateTableProcessor2
public: public:
virtual void beginStateTable(); 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(); virtual void endStateTable();
LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~LigatureSubstitutionProcessor2(); virtual ~LigatureSubstitutionProcessor2();
/** /**
...@@ -83,12 +84,12 @@ protected: ...@@ -83,12 +84,12 @@ protected:
le_uint32 componentOffset; le_uint32 componentOffset;
le_uint32 ligatureOffset; le_uint32 ligatureOffset;
const LigatureSubstitutionStateEntry2 *entryTable; LEReferenceToArrayOf<LigatureSubstitutionStateEntry2> entryTable;
le_int32 componentStack[nComponents]; le_int32 componentStack[nComponents];
le_int16 m; le_int16 m;
const LigatureSubstitutionHeader2 *ligatureSubstitutionHeader; const LEReferenceTo<LigatureSubstitutionHeader2> ligatureSubstitutionHeader;
}; };
......
...@@ -40,10 +40,10 @@ ...@@ -40,10 +40,10 @@
U_NAMESPACE_BEGIN 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(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]); Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
......
...@@ -50,6 +50,7 @@ struct LigatureSetTable ...@@ -50,6 +50,7 @@ struct LigatureSetTable
le_uint16 ligatureCount; le_uint16 ligatureCount;
Offset ligatureTableOffsetArray[ANY_NUMBER]; Offset ligatureTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(LigatureSetTable, ligatureTableOffsetArray)
struct LigatureTable struct LigatureTable
{ {
...@@ -57,14 +58,16 @@ struct LigatureTable ...@@ -57,14 +58,16 @@ struct LigatureTable
le_uint16 compCount; le_uint16 compCount;
TTGlyphID componentArray[ANY_NUMBER]; TTGlyphID componentArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(LigatureTable, componentArray)
struct LigatureSubstitutionSubtable : GlyphSubstitutionSubtable struct LigatureSubstitutionSubtable : GlyphSubstitutionSubtable
{ {
le_uint16 ligSetCount; le_uint16 ligSetCount;
Offset ligSetTableOffsetArray[ANY_NUMBER]; 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 U_NAMESPACE_END
#endif #endif
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
U_NAMESPACE_BEGIN 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 const LEFontInstance *fontInstance, LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
...@@ -57,7 +57,7 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp ...@@ -57,7 +57,7 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
le_uint32 delta; le_uint32 delta;
for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) { 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); delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
...@@ -72,7 +72,7 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp ...@@ -72,7 +72,7 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
} }
le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, 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 const LEFontInstance *fontInstance, LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
...@@ -89,13 +89,13 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -89,13 +89,13 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
rightToLeft, 0, 0, glyphDefinitionTableHeader); rightToLeft, 0, 0, glyphDefinitionTableHeader);
le_int32 newGlyphCount = glyphCount; 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]; le_uint16 lookup = lookupOrderArray[order];
FeatureMask selectMask = lookupSelectArray[lookup]; FeatureMask selectMask = lookupSelectArray[lookup];
if (selectMask != 0) { if (selectMask != 0) {
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup); const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
if (!lookupTable) { if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
continue; continue;
} }
le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags); le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
...@@ -103,7 +103,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -103,7 +103,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
glyphIterator.reset(lookupFlags, selectMask); glyphIterator.reset(lookupFlags, selectMask);
while (glyphIterator.findFeatureTag()) { while (glyphIterator.findFeatureTag()) {
applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return 0; return 0;
} }
...@@ -123,8 +123,8 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt ...@@ -123,8 +123,8 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt
return 0; return 0;
} }
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex); const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookupTableIndex, success);
if (lookupTable == NULL) { if (!lookupTable.isValid()) {
success = LE_INTERNAL_ERROR; success = LE_INTERNAL_ERROR;
return 0; return 0;
} }
...@@ -135,33 +135,35 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt ...@@ -135,33 +135,35 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt
return delta; 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; le_int32 store = order;
for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) { LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount);
le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
if (lookupListIndex >= lookupSelectCount) { for (le_uint16 lookup = 0; LE_SUCCESS(success) && lookup < lookupCount; lookup += 1) {
continue; le_uint16 lookupListIndex = SWAPW(lookupListIndexArray.getObject(lookup,success));
} if (lookupListIndex >= lookupSelectCount) {
continue;
}
lookupSelectArray[lookupListIndex] |= featureMask; lookupSelectArray[lookupListIndex] |= featureMask;
lookupOrderArray[store++] = lookupListIndex; lookupOrderArray[store++] = lookupListIndex;
} }
return store - order; return store - order;
} }
LookupProcessor::LookupProcessor(const char *baseAddress, LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset, Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures, LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures,
LEErrorCode& success) LEErrorCode& success)
: lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0), : lookupListTable(), featureListTable(), lookupSelectArray(NULL), lookupSelectCount(0),
lookupOrderArray(NULL), lookupOrderCount(0) lookupOrderArray(NULL), lookupOrderCount(0), fReference(baseAddress)
{ {
const ScriptListTable *scriptListTable = NULL; LEReferenceTo<ScriptListTable> scriptListTable;
const LangSysTable *langSysTable = NULL; LEReferenceTo<LangSysTable> langSysTable;
le_uint16 featureCount = 0; le_uint16 featureCount = 0;
le_uint16 lookupListCount = 0; le_uint16 lookupListCount = 0;
le_uint16 requiredFeatureIndex; le_uint16 requiredFeatureIndex;
...@@ -171,29 +173,33 @@ LookupProcessor::LookupProcessor(const char *baseAddress, ...@@ -171,29 +173,33 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
} }
if (scriptListOffset != 0) { if (scriptListOffset != 0) {
scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset); scriptListTable = LEReferenceTo<ScriptListTable>(baseAddress, success, scriptListOffset);
langSysTable = scriptListTable->findLanguage(scriptTag, languageTag); langSysTable = scriptListTable->findLanguage(scriptListTable, scriptTag, languageTag, success);
if (langSysTable != 0) { if (langSysTable.isValid() && LE_SUCCESS(success)) {
featureCount = SWAPW(langSysTable->featureCount); featureCount = SWAPW(langSysTable->featureCount);
} }
} }
if (featureListOffset != 0) { if (featureListOffset != 0) {
featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset); featureListTable = LEReferenceTo<FeatureListTable>(baseAddress, success, featureListOffset);
} }
if (lookupListOffset != 0) { if (lookupListOffset != 0) {
lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset); lookupListTable = LEReferenceTo<LookupListTable>(baseAddress,success, lookupListOffset);
if(LE_SUCCESS(success) && lookupListTable.isValid()) {
lookupListCount = SWAPW(lookupListTable->lookupCount); lookupListCount = SWAPW(lookupListTable->lookupCount);
}
} }
if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL || if (langSysTable.isEmpty() || featureListTable.isEmpty() || lookupListTable.isEmpty() ||
featureCount == 0 || lookupListCount == 0) { featureCount == 0 || lookupListCount == 0) {
return; return;
} }
requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex); if(langSysTable.isValid()) {
requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
}
lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount); lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
if (lookupSelectArray == NULL) { if (lookupSelectArray == NULL) {
...@@ -209,34 +215,38 @@ LookupProcessor::LookupProcessor(const char *baseAddress, ...@@ -209,34 +215,38 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
le_int32 count, order = 0; le_int32 count, order = 0;
le_uint32 featureReferences = 0; le_uint32 featureReferences = 0;
const FeatureTable *featureTable = NULL; LEReferenceTo<FeatureTable> featureTable;
LETag featureTag; LETag featureTag;
const FeatureTable *requiredFeatureTable = NULL; LEReferenceTo<FeatureTable> requiredFeatureTable;
LETag requiredFeatureTag = 0x00000000U; LETag requiredFeatureTag = 0x00000000U;
// Count the total number of lookups referenced by all features. This will // 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 // be the maximum number of entries in the lookupOrderArray. We can't use
// lookupListCount because some lookups might be referenced by more than // lookupListCount because some lookups might be referenced by more than
// one feature. // one feature.
for (le_uint32 feature = 0; feature < featureCount; feature += 1) { if(featureListTable.isValid() && LE_SUCCESS(success)) {
le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); for (le_uint32 feature = 0; LE_SUCCESS(success)&&(feature < featureCount); feature += 1) {
if (!featureTable) { le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature, success));
continue;
featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
if (!featureTable.isValid() || LE_FAILURE(success)) {
continue;
} }
featureReferences += SWAPW(featureTable->lookupCount); featureReferences += SWAPW(featureTable->lookupCount);
}
} }
if (!featureTable) { if (!featureTable.isValid() || LE_FAILURE(success)) {
success = LE_INTERNAL_ERROR; success = LE_INTERNAL_ERROR;
return; return;
} }
if (requiredFeatureIndex != 0xFFFF) { if (requiredFeatureIndex != 0xFFFF) {
requiredFeatureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &requiredFeatureTag); requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success);
featureReferences += SWAPW(featureTable->lookupCount); featureReferences += SWAPW(featureTable->lookupCount);
} }
lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences); lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
...@@ -251,7 +261,7 @@ LookupProcessor::LookupProcessor(const char *baseAddress, ...@@ -251,7 +261,7 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
// If this is the required feature, add its lookups // If this is the required feature, add its lookups
if (requiredFeatureTag == fm.tag) { if (requiredFeatureTag == fm.tag) {
count += selectLookups(requiredFeatureTable, fm.mask, order); count += selectLookups(requiredFeatureTable, fm.mask, order, success);
} }
if (orderFeatures) { if (orderFeatures) {
...@@ -261,7 +271,8 @@ LookupProcessor::LookupProcessor(const char *baseAddress, ...@@ -261,7 +271,8 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
} }
for (le_uint16 feature = 0; feature < featureCount; feature += 1) { 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... // 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...) // TODO: Do we need this check? (Spec. says required feature won't be in feature list...)
...@@ -269,10 +280,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress, ...@@ -269,10 +280,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
continue; continue;
} }
featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
if (featureTag == fm.tag) { if (featureTag == fm.tag) {
count += selectLookups(featureTable, fm.mask, order + count); count += selectLookups(featureTable, fm.mask, order + count, success);
} }
} }
...@@ -281,9 +292,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress, ...@@ -281,9 +292,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
} }
order += count; order += count;
} else { } else if(langSysTable.isValid()) {
for (le_uint16 feature = 0; feature < featureCount; feature += 1) { LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); 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... // don't add the required feature to the list more than once...
// NOTE: This check is commented out because the spec. says that // NOTE: This check is commented out because the spec. says that
...@@ -295,10 +307,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress, ...@@ -295,10 +307,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
} }
#endif #endif
featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
if (featureTag == fm.tag) { if (featureTag == fm.tag) {
order += selectLookups(featureTable, fm.mask, order); order += selectLookups(featureTable, fm.mask, order, success);
} }
} }
} }
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "LETypes.h" #include "LETypes.h"
#include "LEFontInstance.h" #include "LEFontInstance.h"
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
#include "LETableReference.h"
//#include "Lookups.h" //#include "Lookups.h"
//#include "Features.h" //#include "Features.h"
...@@ -59,19 +60,21 @@ struct LookupTable; ...@@ -59,19 +60,21 @@ struct LookupTable;
class LookupProcessor : public UMemory { class LookupProcessor : public UMemory {
public: public:
le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, 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; 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; GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const = 0;
virtual ~LookupProcessor(); virtual ~LookupProcessor();
const LETableReference &getReference() const { return fReference; }
protected: protected:
LookupProcessor(const char *baseAddress, LookupProcessor(const LETableReference &baseAddress,
Offset scriptListOffset, Offset scriptListOffset,
Offset featureListOffset, Offset featureListOffset,
Offset lookupListOffset, Offset lookupListOffset,
...@@ -84,10 +87,10 @@ protected: ...@@ -84,10 +87,10 @@ protected:
LookupProcessor(); 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; LEReferenceTo<LookupListTable> lookupListTable;
const FeatureListTable *featureListTable; LEReferenceTo<FeatureListTable> featureListTable;
FeatureMask *lookupSelectArray; FeatureMask *lookupSelectArray;
le_uint32 lookupSelectCount; le_uint32 lookupSelectCount;
...@@ -95,6 +98,8 @@ protected: ...@@ -95,6 +98,8 @@ protected:
le_uint16 *lookupOrderArray; le_uint16 *lookupOrderArray;
le_uint32 lookupOrderCount; le_uint32 lookupOrderCount;
LETableReference fReference;
private: private:
LookupProcessor(const LookupProcessor &other); // forbid copying of this class LookupProcessor(const LookupProcessor &other); // forbid copying of this class
......
...@@ -49,22 +49,26 @@ U_NAMESPACE_BEGIN ...@@ -49,22 +49,26 @@ U_NAMESPACE_BEGIN
of the derived classes, and implement it in the others by casting of the derived classes, and implement it in the others by casting
the "this" pointer to the type that has the implementation. 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 unity = SWAPW(unitSize);
le_int16 probe = SWAPW(searchRange); le_int16 probe = SWAPW(searchRange);
le_int16 extra = SWAPW(rangeShift); le_int16 extra = SWAPW(rangeShift);
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph); TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
const LookupSegment *entry = segments; LEReferenceTo<LookupSegment> entry(base, success, segments);
const LookupSegment *trial = (const LookupSegment *) ((char *) entry + extra); LEReferenceTo<LookupSegment> trial(entry, success, extra);
if(LE_FAILURE(success)) return NULL;
if (SWAPW(trial->lastGlyph) <= ttGlyph) { if (SWAPW(trial->lastGlyph) <= ttGlyph) {
entry = trial; entry = trial;
} }
while (probe > unity) { while (probe > unity && LE_SUCCESS(success)) {
probe >>= 1; probe >>= 1;
trial = (const LookupSegment *) ((char *) entry + probe); trial = entry; // copy
trial.addOffset(probe, success);
if (SWAPW(trial->lastGlyph) <= ttGlyph) { if (SWAPW(trial->lastGlyph) <= ttGlyph) {
entry = trial; entry = trial;
...@@ -72,28 +76,29 @@ const LookupSegment *BinarySearchLookupTable::lookupSegment(const LookupSegment ...@@ -72,28 +76,29 @@ const LookupSegment *BinarySearchLookupTable::lookupSegment(const LookupSegment
} }
if (SWAPW(entry->firstGlyph) <= ttGlyph) { if (SWAPW(entry->firstGlyph) <= ttGlyph) {
return entry; return entry.getAlias();
} }
return NULL; 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 unity = SWAPW(unitSize);
le_int16 probe = SWAPW(searchRange); le_int16 probe = SWAPW(searchRange);
le_int16 extra = SWAPW(rangeShift); le_int16 extra = SWAPW(rangeShift);
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph); TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
const LookupSingle *entry = entries; LEReferenceTo<LookupSingle> entry(base, success, entries);
const LookupSingle *trial = (const LookupSingle *) ((char *) entry + extra); LEReferenceTo<LookupSingle> trial(entry, success, extra);
if (SWAPW(trial->glyph) <= ttGlyph) { if (SWAPW(trial->glyph) <= ttGlyph) {
entry = trial; entry = trial;
} }
while (probe > unity) { while (probe > unity && LE_SUCCESS(success)) {
probe >>= 1; probe >>= 1;
trial = (const LookupSingle *) ((char *) entry + probe); trial = entry;
trial.addOffset(probe, success);
if (SWAPW(trial->glyph) <= ttGlyph) { if (SWAPW(trial->glyph) <= ttGlyph) {
entry = trial; entry = trial;
...@@ -101,7 +106,7 @@ const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *en ...@@ -101,7 +106,7 @@ const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *en
} }
if (SWAPW(entry->glyph) == ttGlyph) { if (SWAPW(entry->glyph) == ttGlyph) {
return entry; return entry.getAlias();
} }
return NULL; return NULL;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "LETypes.h" #include "LETypes.h"
#include "LayoutTables.h" #include "LayoutTables.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
...@@ -79,30 +80,34 @@ struct BinarySearchLookupTable : LookupTable ...@@ -79,30 +80,34 @@ struct BinarySearchLookupTable : LookupTable
le_int16 entrySelector; le_int16 entrySelector;
le_int16 rangeShift; 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 struct SimpleArrayLookupTable : LookupTable
{ {
LookupValue valueArray[ANY_NUMBER]; LookupValue valueArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SimpleArrayLookupTable, valueArray)
struct SegmentSingleLookupTable : BinarySearchLookupTable struct SegmentSingleLookupTable : BinarySearchLookupTable
{ {
LookupSegment segments[ANY_NUMBER]; LookupSegment segments[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SegmentSingleLookupTable, segments)
struct SegmentArrayLookupTable : BinarySearchLookupTable struct SegmentArrayLookupTable : BinarySearchLookupTable
{ {
LookupSegment segments[ANY_NUMBER]; LookupSegment segments[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SegmentArrayLookupTable, segments)
struct SingleTableLookupTable : BinarySearchLookupTable struct SingleTableLookupTable : BinarySearchLookupTable
{ {
LookupSingle entries[ANY_NUMBER]; LookupSingle entries[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SingleTableLookupTable, entries)
struct TrimmedArrayLookupTable : LookupTable struct TrimmedArrayLookupTable : LookupTable
{ {
...@@ -110,6 +115,7 @@ struct TrimmedArrayLookupTable : LookupTable ...@@ -110,6 +115,7 @@ struct TrimmedArrayLookupTable : LookupTable
TTGlyphID glyphCount; TTGlyphID glyphCount;
LookupValue valueArray[ANY_NUMBER]; LookupValue valueArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(TrimmedArrayLookupTable, valueArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -37,33 +37,35 @@ ...@@ -37,33 +37,35 @@
U_NAMESPACE_BEGIN 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)) { LEReferenceToArrayOf<Offset> lookupTableOffsetArrayRef(base, success, (const Offset*)&lookupTableOffsetArray, SWAPW(lookupCount));
return 0;
}
Offset lookupTableOffset = lookupTableOffsetArray[lookupTableIndex]; if(LE_FAILURE(success) || lookupTableIndex>lookupTableOffsetArrayRef.getCount()) {
return LEReferenceTo<LookupTable>();
return (const LookupTable *) ((char *) this + SWAPW(lookupTableOffset)); } 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)) { LEReferenceToArrayOf<Offset> subTableOffsetArrayRef(base, success, (const Offset*)&subTableOffsetArray, SWAPW(subTableCount));
return 0;
}
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));
if(LE_FAILURE(success)) return 0;
return coverageTable->getGlyphCoverage(glyphID); return coverageTable->getGlyphCoverage(glyphID);
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -58,9 +58,14 @@ struct LookupSubtable ...@@ -58,9 +58,14 @@ struct LookupSubtable
le_uint16 subtableFormat; le_uint16 subtableFormat;
Offset coverageTableOffset; 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 struct LookupTable
...@@ -70,20 +75,32 @@ struct LookupTable ...@@ -70,20 +75,32 @@ struct LookupTable
le_uint16 subTableCount; le_uint16 subTableCount;
Offset subTableOffsetArray[ANY_NUMBER]; 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 struct LookupListTable
{ {
le_uint16 lookupCount; le_uint16 lookupCount;
Offset lookupTableOffsetArray[ANY_NUMBER]; 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 U_NAMESPACE_END
......
...@@ -57,6 +57,7 @@ struct MarkArray ...@@ -57,6 +57,7 @@ struct MarkArray
le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance, le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor) const; LEPoint &anchor) const;
}; };
LE_VAR_ARRAY(MarkArray, markRecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -51,10 +51,10 @@ LEGlyphID MarkToBasePositioningSubtable::findBaseGlyph(GlyphIterator *glyphItera ...@@ -51,10 +51,10 @@ LEGlyphID MarkToBasePositioningSubtable::findBaseGlyph(GlyphIterator *glyphItera
return 0xFFFF; 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(); LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph); le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
if (markCoverage < 0) { if (markCoverage < 0) {
// markGlyph isn't a covered mark glyph // markGlyph isn't a covered mark glyph
...@@ -75,7 +75,7 @@ le_int32 MarkToBasePositioningSubtable::process(GlyphIterator *glyphIterator, co ...@@ -75,7 +75,7 @@ le_int32 MarkToBasePositioningSubtable::process(GlyphIterator *glyphIterator, co
// FIXME: We probably don't want to find a base glyph before a previous ligature... // FIXME: We probably don't want to find a base glyph before a previous ligature...
GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/)); GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
LEGlyphID baseGlyph = findBaseGlyph(&baseIterator); 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)); const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset));
le_uint16 baseCount = SWAPW(baseArray->baseRecordCount); le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);
......
...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN ...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
struct MarkToBasePositioningSubtable : AttachmentPositioningSubtable 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; LEGlyphID findBaseGlyph(GlyphIterator *glyphIterator) const;
}; };
...@@ -56,12 +56,14 @@ struct BaseRecord ...@@ -56,12 +56,14 @@ struct BaseRecord
{ {
Offset baseAnchorTableOffsetArray[ANY_NUMBER]; Offset baseAnchorTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(BaseRecord, baseAnchorTableOffsetArray)
struct BaseArray struct BaseArray
{ {
le_int16 baseRecordCount; le_int16 baseRecordCount;
BaseRecord baseRecordArray[ANY_NUMBER]; BaseRecord baseRecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(BaseArray, baseRecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -50,10 +50,10 @@ LEGlyphID MarkToLigaturePositioningSubtable::findLigatureGlyph(GlyphIterator *gl ...@@ -50,10 +50,10 @@ LEGlyphID MarkToLigaturePositioningSubtable::findLigatureGlyph(GlyphIterator *gl
return 0xFFFF; 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(); LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph); le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
if (markCoverage < 0) { if (markCoverage < 0) {
// markGlyph isn't a covered mark glyph // markGlyph isn't a covered mark glyph
...@@ -74,7 +74,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(GlyphIterator *glyphIterator ...@@ -74,7 +74,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(GlyphIterator *glyphIterator
// FIXME: we probably don't want to find a ligature before a previous base glyph... // FIXME: we probably don't want to find a ligature before a previous base glyph...
GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/)); GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator); 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)); const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset));
le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount); le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);
......
...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN ...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
struct MarkToLigaturePositioningSubtable : AttachmentPositioningSubtable 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; LEGlyphID findLigatureGlyph(GlyphIterator *glyphIterator) const;
}; };
...@@ -56,18 +56,21 @@ struct ComponentRecord ...@@ -56,18 +56,21 @@ struct ComponentRecord
{ {
Offset ligatureAnchorTableOffsetArray[ANY_NUMBER]; Offset ligatureAnchorTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ComponentRecord, ligatureAnchorTableOffsetArray)
struct LigatureAttachTable struct LigatureAttachTable
{ {
le_uint16 componentCount; le_uint16 componentCount;
ComponentRecord componentRecordArray[ANY_NUMBER]; ComponentRecord componentRecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(LigatureAttachTable, componentRecordArray)
struct LigatureArray struct LigatureArray
{ {
le_uint16 ligatureCount; le_uint16 ligatureCount;
Offset ligatureAttachTableOffsetArray[ANY_NUMBER]; Offset ligatureAttachTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(LigatureArray, ligatureAttachTableOffsetArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -51,10 +51,10 @@ LEGlyphID MarkToMarkPositioningSubtable::findMark2Glyph(GlyphIterator *glyphIter ...@@ -51,10 +51,10 @@ LEGlyphID MarkToMarkPositioningSubtable::findMark2Glyph(GlyphIterator *glyphIter
return 0xFFFF; 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(); LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph); le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
if (markCoverage < 0) { if (markCoverage < 0) {
// markGlyph isn't a covered mark glyph // markGlyph isn't a covered mark glyph
...@@ -74,7 +74,7 @@ le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, co ...@@ -74,7 +74,7 @@ le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, co
GlyphIterator mark2Iterator(*glyphIterator); GlyphIterator mark2Iterator(*glyphIterator);
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator); 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)); const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset));
le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount); le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
......
...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN ...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
struct MarkToMarkPositioningSubtable : AttachmentPositioningSubtable 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; LEGlyphID findMark2Glyph(GlyphIterator *glyphIterator) const;
}; };
...@@ -56,12 +56,14 @@ struct Mark2Record ...@@ -56,12 +56,14 @@ struct Mark2Record
{ {
Offset mark2AnchorTableOffsetArray[ANY_NUMBER]; Offset mark2AnchorTableOffsetArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(Mark2Record, mark2AnchorTableOffsetArray)
struct Mark2Array struct Mark2Array
{ {
le_uint16 mark2RecordCount; le_uint16 mark2RecordCount;
Mark2Record mark2RecordArray[ANY_NUMBER]; Mark2Record mark2RecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(Mark2Array, mark2RecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -44,61 +44,61 @@ ...@@ -44,61 +44,61 @@
U_NAMESPACE_BEGIN 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; 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); FeatureFlags defaultFlags = SWAPL(chainHeader->defaultFlags);
le_uint32 chainLength = SWAPL(chainHeader->chainLength); le_uint32 chainLength = SWAPL(chainHeader->chainLength);
le_int16 nFeatureEntries = SWAPW(chainHeader->nFeatureEntries); le_int16 nFeatureEntries = SWAPW(chainHeader->nFeatureEntries);
le_int16 nSubtables = SWAPW(chainHeader->nSubtables); le_int16 nSubtables = SWAPW(chainHeader->nSubtables);
const MorphSubtableHeader *subtableHeader = LEReferenceTo<MorphSubtableHeader> subtableHeader =
(const MorphSubtableHeader *)&chainHeader->featureTable[nFeatureEntries]; LEReferenceTo<MorphSubtableHeader>(chainHeader,success, &(chainHeader->featureTable[nFeatureEntries]));
le_int16 subtable; 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); le_int16 length = SWAPW(subtableHeader->length);
SubtableCoverage coverage = SWAPW(subtableHeader->coverage); SubtableCoverage coverage = SWAPW(subtableHeader->coverage);
FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures); FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
// should check coverage more carefully... // should check coverage more carefully...
if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0) { if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0 && LE_SUCCESS(success)) {
subtableHeader->process(glyphStorage); subtableHeader->process(subtableHeader, glyphStorage, success);
} }
subtableHeader = (const MorphSubtableHeader *) ((char *)subtableHeader + length); subtableHeader.addOffset(length, success);
} }
chainHeader.addOffset(chainLength, success);
chainHeader = (const ChainHeader *)((char *)chainHeader + chainLength);
} }
} }
void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const void MorphSubtableHeader::process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
{ {
SubtableProcessor *processor = NULL; SubtableProcessor *processor = NULL;
switch (SWAPW(coverage) & scfTypeMask) switch (SWAPW(coverage) & scfTypeMask)
{ {
case mstIndicRearrangement: case mstIndicRearrangement:
processor = new IndicRearrangementProcessor(this); processor = new IndicRearrangementProcessor(base, success);
break; break;
case mstContextualGlyphSubstitution: case mstContextualGlyphSubstitution:
processor = new ContextualGlyphSubstitutionProcessor(this); processor = new ContextualGlyphSubstitutionProcessor(base, success);
break; break;
case mstLigatureSubstitution: case mstLigatureSubstitution:
processor = new LigatureSubstitutionProcessor(this); processor = new LigatureSubstitutionProcessor(base, success);
break; break;
case mstReservedUnused: case mstReservedUnused:
break; break;
case mstNonContextualGlyphSubstitution: case mstNonContextualGlyphSubstitution:
processor = NonContextualGlyphSubstitutionProcessor::createInstance(this); processor = NonContextualGlyphSubstitutionProcessor::createInstance(base, success);
break; break;
/* /*
...@@ -112,8 +112,10 @@ void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const ...@@ -112,8 +112,10 @@ void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const
} }
if (processor != NULL) { if (processor != NULL) {
processor->process(glyphStorage); if(LE_SUCCESS(success)) {
delete processor; processor->process(glyphStorage, success);
}
delete processor;
} }
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "LETypes.h" #include "LETypes.h"
#include "LayoutTables.h" #include "LayoutTables.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
...@@ -65,6 +66,7 @@ struct ChainHeader ...@@ -65,6 +66,7 @@ struct ChainHeader
le_int16 nSubtables; le_int16 nSubtables;
FeatureTableEntry featureTable[ANY_NUMBER]; FeatureTableEntry featureTable[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ChainHeader, featureTable)
struct MorphTableHeader struct MorphTableHeader
{ {
...@@ -72,8 +74,9 @@ struct MorphTableHeader ...@@ -72,8 +74,9 @@ struct MorphTableHeader
le_uint32 nChains; le_uint32 nChains;
ChainHeader chains[ANY_NUMBER]; 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_int16 SubtableCoverage;
typedef le_uint32 SubtableCoverage2; typedef le_uint32 SubtableCoverage2;
...@@ -103,7 +106,7 @@ struct MorphSubtableHeader ...@@ -103,7 +106,7 @@ struct MorphSubtableHeader
SubtableCoverage coverage; SubtableCoverage coverage;
FeatureFlags subtableFeatures; FeatureFlags subtableFeatures;
void process(LEGlyphStorage &glyphStorage) const; void process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
}; };
enum SubtableCoverageFlags2 enum SubtableCoverageFlags2
...@@ -121,7 +124,7 @@ struct MorphSubtableHeader2 ...@@ -121,7 +124,7 @@ struct MorphSubtableHeader2
SubtableCoverage2 coverage; SubtableCoverage2 coverage;
FeatureFlags subtableFeatures; FeatureFlags subtableFeatures;
void process(LEGlyphStorage &glyphStorage) const; void process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
}; };
struct ChainHeader2 struct ChainHeader2
...@@ -132,6 +135,7 @@ struct ChainHeader2 ...@@ -132,6 +135,7 @@ struct ChainHeader2
le_uint32 nSubtables; le_uint32 nSubtables;
FeatureTableEntry featureTable[ANY_NUMBER]; FeatureTableEntry featureTable[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ChainHeader2, featureTable)
struct MorphTableHeader2 struct MorphTableHeader2
{ {
...@@ -139,8 +143,9 @@ struct MorphTableHeader2 ...@@ -139,8 +143,9 @@ struct MorphTableHeader2
le_uint32 nChains; le_uint32 nChains;
ChainHeader2 chains[ANY_NUMBER]; 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 * AAT Font Features
......
...@@ -42,27 +42,40 @@ ...@@ -42,27 +42,40 @@
U_NAMESPACE_BEGIN 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; if(LE_FAILURE(success)) return;
le_uint32 chainCount = SWAPL(this->nChains);
le_uint32 chain; le_uint32 chainCount = SWAPL(this->nChains);
LEReferenceTo<ChainHeader2> chainHeader(base, success, &chains[0]);
for (chain = 0; chain < chainCount; chain++) { /* 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); FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
le_uint32 chainLength = SWAPL(chainHeader->chainLength);
le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries); le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
le_uint32 nSubtables = SWAPL(chainHeader->nSubtables); le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
const MorphSubtableHeader2 *subtableHeader = LEReferenceTo<MorphSubtableHeader2> subtableHeader(chainHeader,
(const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]; success, (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]);
le_uint32 subtable; le_uint32 subtable;
if(LE_FAILURE(success)) break; // malformed table
if (typoFlags != 0) { if (typoFlags != 0) {
le_uint32 featureEntry; le_uint32 featureEntry;
LEReferenceToArrayOf<FeatureTableEntry> featureTableRef(chainHeader, success, &chainHeader->featureTable[0], nFeatureEntries);
if(LE_FAILURE(success)) break;
// Feature subtables // Feature subtables
for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) { 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 featureType = SWAPW(featureTableEntry.featureType);
le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting); le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags); le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
...@@ -172,57 +185,63 @@ void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags ...@@ -172,57 +185,63 @@ void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags
} }
} }
for (subtable = 0; subtable < nSubtables; subtable++) { for (subtable = 0; LE_SUCCESS(success) && subtable < nSubtables; subtable++) {
le_uint32 length = SWAPL(subtableHeader->length); 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); le_uint32 coverage = SWAPL(subtableHeader->coverage);
FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures); FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
// should check coverage more carefully... // should check coverage more carefully...
if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) { 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; SubtableProcessor2 *processor = NULL;
switch (SWAPL(coverage) & scfTypeMask2) switch (SWAPL(coverage) & scfTypeMask2)
{ {
case mstIndicRearrangement: case mstIndicRearrangement:
processor = new IndicRearrangementProcessor2(this); processor = new IndicRearrangementProcessor2(base, success);
break; break;
case mstContextualGlyphSubstitution: case mstContextualGlyphSubstitution:
processor = new ContextualGlyphSubstitutionProcessor2(this); processor = new ContextualGlyphSubstitutionProcessor2(base, success);
break; break;
case mstLigatureSubstitution: case mstLigatureSubstitution:
processor = new LigatureSubstitutionProcessor2(this); processor = new LigatureSubstitutionProcessor2(base, success);
break; break;
case mstReservedUnused: case mstReservedUnused:
break; break;
case mstNonContextualGlyphSubstitution: case mstNonContextualGlyphSubstitution:
processor = NonContextualGlyphSubstitutionProcessor2::createInstance(this); processor = NonContextualGlyphSubstitutionProcessor2::createInstance(base, success);
break; break;
case mstContextualGlyphInsertion: case mstContextualGlyphInsertion:
processor = new ContextualGlyphInsertionProcessor2(this); processor = new ContextualGlyphInsertionProcessor2(base, success);
break; break;
default: default:
break; return;
break; /*NOTREACHED*/
} }
if (processor != NULL) { if (processor != NULL) {
processor->process(glyphStorage); processor->process(glyphStorage, success);
delete processor; delete processor;
} else {
if(LE_SUCCESS(success)) {
success = LE_MEMORY_ALLOCATION_ERROR; // because ptr is null and we didn't break out.
}
} }
} }
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
U_NAMESPACE_BEGIN 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)) { if (LE_FAILURE(success)) {
return 0; return 0;
...@@ -58,7 +58,7 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LE ...@@ -58,7 +58,7 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LE
return 0; return 0;
} }
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
le_uint16 seqCount = SWAPW(sequenceCount); le_uint16 seqCount = SWAPW(sequenceCount);
if (coverageIndex >= 0 && coverageIndex < seqCount) { if (coverageIndex >= 0 && coverageIndex < seqCount) {
......
...@@ -50,14 +50,16 @@ struct SequenceTable ...@@ -50,14 +50,16 @@ struct SequenceTable
le_uint16 glyphCount; le_uint16 glyphCount;
TTGlyphID substituteArray[ANY_NUMBER]; TTGlyphID substituteArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(SequenceTable, substituteArray)
struct MultipleSubstitutionSubtable : GlyphSubstitutionSubtable struct MultipleSubstitutionSubtable : GlyphSubstitutionSubtable
{ {
le_uint16 sequenceCount; le_uint16 sequenceCount;
Offset sequenceTableOffsetArray[ANY_NUMBER]; 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 U_NAMESPACE_END
#endif #endif
...@@ -47,8 +47,8 @@ NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor ...@@ -47,8 +47,8 @@ NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor
{ {
} }
NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader) NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: SubtableProcessor(morphSubtableHeader) : SubtableProcessor(morphSubtableHeader, success)
{ {
} }
...@@ -56,26 +56,27 @@ NonContextualGlyphSubstitutionProcessor::~NonContextualGlyphSubstitutionProcesso ...@@ -56,26 +56,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: case ltfSimpleArray:
return new SimpleArrayProcessor(morphSubtableHeader); return new SimpleArrayProcessor(morphSubtableHeader, success);
case ltfSegmentSingle: case ltfSegmentSingle:
return new SegmentSingleProcessor(morphSubtableHeader); return new SegmentSingleProcessor(morphSubtableHeader, success);
case ltfSegmentArray: case ltfSegmentArray:
return new SegmentArrayProcessor(morphSubtableHeader); return new SegmentArrayProcessor(morphSubtableHeader, success);
case ltfSingleTable: case ltfSingleTable:
return new SingleTableProcessor(morphSubtableHeader); return new SingleTableProcessor(morphSubtableHeader, success);
case ltfTrimmedArray: case ltfTrimmedArray:
return new TrimmedArrayProcessor(morphSubtableHeader); return new TrimmedArrayProcessor(morphSubtableHeader, success);
default: default:
return NULL; return NULL;
......
...@@ -49,13 +49,13 @@ class LEGlyphStorage; ...@@ -49,13 +49,13 @@ class LEGlyphStorage;
class NonContextualGlyphSubstitutionProcessor : public SubtableProcessor class NonContextualGlyphSubstitutionProcessor : public SubtableProcessor
{ {
public: 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: protected:
NonContextualGlyphSubstitutionProcessor(); NonContextualGlyphSubstitutionProcessor();
NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader); NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &status);
virtual ~NonContextualGlyphSubstitutionProcessor(); virtual ~NonContextualGlyphSubstitutionProcessor();
......
...@@ -47,8 +47,9 @@ NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcesso ...@@ -47,8 +47,9 @@ NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcesso
{ {
} }
NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(
: SubtableProcessor2(morphSubtableHeader) const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: SubtableProcessor2(morphSubtableHeader, success)
{ {
} }
...@@ -56,26 +57,28 @@ NonContextualGlyphSubstitutionProcessor2::~NonContextualGlyphSubstitutionProcess ...@@ -56,26 +57,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)) switch (SWAPW(header->table.format))
{ {
case ltfSimpleArray: case ltfSimpleArray:
return new SimpleArrayProcessor2(morphSubtableHeader); return new SimpleArrayProcessor2(morphSubtableHeader, success);
case ltfSegmentSingle: case ltfSegmentSingle:
return new SegmentSingleProcessor2(morphSubtableHeader); return new SegmentSingleProcessor2(morphSubtableHeader, success);
case ltfSegmentArray: case ltfSegmentArray:
return new SegmentArrayProcessor2(morphSubtableHeader); return new SegmentArrayProcessor2(morphSubtableHeader, success);
case ltfSingleTable: case ltfSingleTable:
return new SingleTableProcessor2(morphSubtableHeader); return new SingleTableProcessor2(morphSubtableHeader, success);
case ltfTrimmedArray: case ltfTrimmedArray:
return new TrimmedArrayProcessor2(morphSubtableHeader); return new TrimmedArrayProcessor2(morphSubtableHeader, success);
default: default:
return NULL; return NULL;
......
...@@ -49,13 +49,13 @@ class LEGlyphStorage; ...@@ -49,13 +49,13 @@ class LEGlyphStorage;
class NonContextualGlyphSubstitutionProcessor2 : public SubtableProcessor2 class NonContextualGlyphSubstitutionProcessor2 : public SubtableProcessor2
{ {
public: 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: protected:
NonContextualGlyphSubstitutionProcessor2(); NonContextualGlyphSubstitutionProcessor2();
NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); NonContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~NonContextualGlyphSubstitutionProcessor2(); virtual ~NonContextualGlyphSubstitutionProcessor2();
......
...@@ -151,25 +151,21 @@ static const FeatureMap featureMap[] = ...@@ -151,25 +151,21 @@ static const FeatureMap featureMap[] =
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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), : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureMask(minimalFeatures),
fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE), 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(); applyTypoFlags();
setScriptAndLanguageTags(); setScriptAndLanguageTags();
fGDEFTable = (const GlyphDefinitionTableHeader *) getFontTable(gdefTableTag);
// JK patch, 2008-05-30 - see Sinhala bug report and LKLUG font // JK patch, 2008-05-30 - see Sinhala bug report and LKLUG font
// if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) { // if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) {
if (gposTable != NULL && gposTable->coversScript(fScriptTag)) { if (!fGPOSTable.isEmpty()&& !fGPOSTable->coversScript(fGPOSTable, fScriptTag, success)) {
fGPOSTable = gposTable; fGPOSTable.clear(); // already loaded
} }
} }
...@@ -252,7 +248,7 @@ void OpenTypeLayoutEngine::reset() ...@@ -252,7 +248,7 @@ void OpenTypeLayoutEngine::reset()
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success) le_int32 typoFlags, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureOrder(FALSE), : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureOrder(FALSE),
fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) fGSUBTable(), fGDEFTable(), fGPOSTable(), fSubstitutionFilter(NULL)
{ {
applyTypoFlags(); applyTypoFlags();
setScriptAndLanguageTags(); setScriptAndLanguageTags();
...@@ -375,13 +371,13 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 ...@@ -375,13 +371,13 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32
return 0; return 0;
} }
if (fGSUBTable != NULL) { if (fGSUBTable.isValid()) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) { if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable, fScriptTagV2, fLangSysTag, success)) {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter, count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success); fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} else { } else {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success); fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} }
} }
...@@ -402,13 +398,13 @@ le_int32 OpenTypeLayoutEngine::glyphSubstitution(le_int32 count, le_int32 max, l ...@@ -402,13 +398,13 @@ le_int32 OpenTypeLayoutEngine::glyphSubstitution(le_int32 count, le_int32 max, l
return 0; return 0;
} }
if (fGSUBTable != NULL) { if (fGSUBTable.isValid()) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) { if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable,fScriptTagV2,fLangSysTag,success)) {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter, count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success); fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} else { } else {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success); fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} }
} }
...@@ -488,7 +484,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 ...@@ -488,7 +484,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
return; return;
} }
if (fGPOSTable != NULL) { if (!fGPOSTable.isEmpty()) {
GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount); GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount);
le_int32 i; le_int32 i;
...@@ -511,19 +507,20 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 ...@@ -511,19 +507,20 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
} }
#endif #endif
if (fGPOSTable != NULL) { if (!fGPOSTable.isEmpty()) {
if (fScriptTagV2 != nullScriptTag && fGPOSTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) { if (fScriptTagV2 != nullScriptTag &&
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGDEFTable, success, fFontInstance, fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) {
fFeatureMap, fFeatureMapCount, fFeatureOrder); fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} else { } else {
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, success, fFontInstance, fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag,
fFeatureMap, fFeatureMapCount, fFeatureOrder); fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} }
} else if ( fTypoFlags & 0x1 ) { } else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(fFontInstance, getFontTable(kernTableTag)); KernTable kt(kernTable, success);
kt.process(glyphStorage); kt.process(glyphStorage, success);
} }
float xAdjust = 0, yAdjust = 0; float xAdjust = 0, yAdjust = 0;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "LEGlyphFilter.h" #include "LEGlyphFilter.h"
#include "LEFontInstance.h" #include "LEFontInstance.h"
#include "LayoutEngine.h" #include "LayoutEngine.h"
#include "LETableReference.h"
#include "GlyphSubstitutionTables.h" #include "GlyphSubstitutionTables.h"
#include "GlyphDefinitionTables.h" #include "GlyphDefinitionTables.h"
...@@ -88,7 +89,7 @@ public: ...@@ -88,7 +89,7 @@ public:
* @internal * @internal
*/ */
OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, 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 * This constructor is used when the font requires a "canned" GSUB table which can't be known
...@@ -228,21 +229,21 @@ protected: ...@@ -228,21 +229,21 @@ protected:
* *
* @internal * @internal
*/ */
const GlyphSubstitutionTableHeader *fGSUBTable; LEReferenceTo<GlyphSubstitutionTableHeader> fGSUBTable;
/** /**
* The address of the GDEF table. * The address of the GDEF table.
* *
* @internal * @internal
*/ */
const GlyphDefinitionTableHeader *fGDEFTable; LEReferenceTo<GlyphDefinitionTableHeader> fGDEFTable;
/** /**
* The address of the GPOS table. * The address of the GPOS table.
* *
* @internal * @internal
*/ */
const GlyphPositioningTableHeader *fGPOSTable; LEReferenceTo<GlyphPositioningTableHeader> fGPOSTable;
/** /**
* An optional filter used to inhibit substitutions * An optional filter used to inhibit substitutions
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
*/ */
#include "LETypes.h" #include "LETypes.h"
#include "LETableReference.h"
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
...@@ -50,7 +51,7 @@ typedef le_uint32 fixed32; ...@@ -50,7 +51,7 @@ typedef le_uint32 fixed32;
#define LE_GLYPH_GROUP_MASK 0x00000001UL #define LE_GLYPH_GROUP_MASK 0x00000001UL
typedef le_uint32 FeatureMask; 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 struct TagAndOffsetRecord
{ {
......
...@@ -76,58 +76,74 @@ le_int8 OpenTypeUtilities::highBit(le_int32 value) ...@@ -76,58 +76,74 @@ le_int8 OpenTypeUtilities::highBit(le_int32 value)
return bit; 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); if(LE_FAILURE(success)) return 0;
le_int32 power = 1 << bit;
le_int32 extra = recordCount - power;
le_int32 probe = power;
le_int32 index = 0;
if (SWAPT(records[extra].tag) <= tag) { le_uint32 recordCount = records.getCount();
index = extra; 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)) { while (probe > (1 << 0) && LE_SUCCESS(success)) {
probe >>= 1; probe >>= 1;
if (SWAPT(records[index + probe].tag) <= tag) { {
index += probe; 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_uint8 bit = highBit(recordCount);
le_int32 power = 1 << bit; le_int32 power = 1 << bit;
le_int32 extra = recordCount - power; le_int32 extra = recordCount - power;
le_int32 probe = power; le_int32 probe = power;
le_int32 range = 0; le_int32 range = 0;
if (recordCount == 0) { if (recordCount == 0) {
return -1; return -1;
} }
if (SWAPW(records[extra].firstGlyph) <= glyphID) { if (SWAPW(records(extra,success).firstGlyph) <= glyphID) {
range = extra; range = extra;
} }
while (probe > (1 << 0)) { while (probe > (1 << 0) && LE_SUCCESS(success)) {
probe >>= 1; probe >>= 1;
if (SWAPW(records[range + probe].firstGlyph) <= glyphID) { if (SWAPW(records(range + probe,success).firstGlyph) <= glyphID) {
range += probe; 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; return range;
} }
...@@ -199,6 +215,38 @@ void OpenTypeUtilities::sort(le_uint16 *array, le_int32 count) ...@@ -199,6 +215,38 @@ void OpenTypeUtilities::sort(le_uint16 *array, le_int32 count)
} }
} }
U_NAMESPACE_END
#if LE_ASSERT_BAD_FONT
#include <stdio.h>
U_NAMESPACE_END 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
...@@ -45,8 +45,17 @@ U_NAMESPACE_BEGIN ...@@ -45,8 +45,17 @@ U_NAMESPACE_BEGIN
class OpenTypeUtilities /* not : public UObject because all methods are static */ { class OpenTypeUtilities /* not : public UObject because all methods are static */ {
public: public:
static le_int8 highBit(le_int32 value); static le_int8 highBit(le_int32 value);
static Offset getTagOffset(LETag tag, const TagAndOffsetRecord *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); /**
* @deprecated TODO remove
*/
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_uint16 value, const le_uint16 array[], le_int32 count);
static le_int32 search(le_uint32 value, const le_uint32 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); static void sort(le_uint16 *array, le_int32 count);
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
U_NAMESPACE_BEGIN 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)) switch(SWAPW(subtableFormat))
{ {
...@@ -50,27 +50,32 @@ le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const L ...@@ -50,27 +50,32 @@ le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const L
case 1: 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: case 2:
{ {
const PairPositioningFormat2Subtable *subtable = (const PairPositioningFormat2Subtable *) this; const LEReferenceTo<PairPositioningFormat2Subtable> subtable(base, success, (const PairPositioningFormat2Subtable *) this);
return subtable->process(glyphIterator, fontInstance); if(LE_SUCCESS(success))
return subtable->process(subtable, glyphIterator, fontInstance, success);
else
return 0;
} }
default: default:
return 0; 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(); LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(firstGlyph); le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
if (coverageIndex >= 0 && glyphIterator->next()) { if (coverageIndex >= 0 && glyphIterator->next()) {
...@@ -110,10 +115,10 @@ le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator, ...@@ -110,10 +115,10 @@ le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator,
return 0; 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(); LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(firstGlyph); le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
if (coverageIndex >= 0 && glyphIterator->next()) { if (coverageIndex >= 0 && glyphIterator->next()) {
......
...@@ -59,13 +59,14 @@ struct PairSetTable ...@@ -59,13 +59,14 @@ struct PairSetTable
le_uint16 pairValueCount; le_uint16 pairValueCount;
PairValueRecord pairValueRecordArray[ANY_NUMBER]; PairValueRecord pairValueRecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(PairSetTable, pairValueRecordArray)
struct PairPositioningSubtable : GlyphPositioningSubtable struct PairPositioningSubtable : GlyphPositioningSubtable
{ {
ValueFormat valueFormat1; ValueFormat valueFormat1;
ValueFormat valueFormat2; ValueFormat valueFormat2;
le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LEReferenceTo<PairPositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
}; };
struct PairPositioningFormat1Subtable : PairPositioningSubtable struct PairPositioningFormat1Subtable : PairPositioningSubtable
...@@ -73,12 +74,13 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable ...@@ -73,12 +74,13 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable
le_uint16 pairSetCount; le_uint16 pairSetCount;
Offset pairSetTableOffsetArray[ANY_NUMBER]; Offset pairSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
private: private:
const PairValueRecord *findPairValueRecord(TTGlyphID glyphID, const PairValueRecord *records, const PairValueRecord *findPairValueRecord(TTGlyphID glyphID, const PairValueRecord *records,
le_uint16 recordCount, le_uint16 recordSize) const; le_uint16 recordCount, le_uint16 recordSize) const;
}; };
LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray)
// NOTE: ValueRecord has a variable size // NOTE: ValueRecord has a variable size
struct Class2Record struct Class2Record
...@@ -91,6 +93,7 @@ struct Class1Record ...@@ -91,6 +93,7 @@ struct Class1Record
{ {
Class2Record class2RecordArray[ANY_NUMBER]; Class2Record class2RecordArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(Class1Record, class2RecordArray)
struct PairPositioningFormat2Subtable : PairPositioningSubtable struct PairPositioningFormat2Subtable : PairPositioningSubtable
{ {
...@@ -100,8 +103,9 @@ struct PairPositioningFormat2Subtable : PairPositioningSubtable ...@@ -100,8 +103,9 @@ struct PairPositioningFormat2Subtable : PairPositioningSubtable
le_uint16 class2Count; le_uint16 class2Count;
Class1Record class1RecordArray[ANY_NUMBER]; Class1Record class1RecordArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LEReferenceTo<PairPositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(PairPositioningFormat2Subtable, class1RecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -38,29 +38,33 @@ ...@@ -38,29 +38,33 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMatch) const LEReferenceTo<LangSysTable> ScriptTable::findLanguage(const LETableReference& base, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
{ {
le_uint16 count = SWAPW(langSysCount); le_uint16 count = SWAPW(langSysCount);
Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset); Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset);
if (count > 0) { if (count > 0) {
Offset foundOffset = LEReferenceToArrayOf<TagAndOffsetRecord> langSysRecords(base, success, langSysRecordArray, count);
OpenTypeUtilities::getTagOffset(languageTag, langSysRecordArray, count); Offset foundOffset =
OpenTypeUtilities::getTagOffset(languageTag, langSysRecords, success);
if (foundOffset != 0) { if (foundOffset != 0 && LE_SUCCESS(success)) {
langSysTableOffset = foundOffset; langSysTableOffset = foundOffset;
} }
} }
if (langSysTableOffset != 0) { if (langSysTableOffset != 0) {
return (const LangSysTable *) ((char *)this + langSysTableOffset); return LEReferenceTo<LangSysTable>(base, success, langSysTableOffset);
} }
return NULL; return LEReferenceTo<LangSysTable>();
} }
const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const
{ {
if (LE_FAILURE(success) ) {
return LEReferenceTo<ScriptTable>(); // get out
}
/* /*
* There are some fonts that have a large, bogus value for scriptCount. To try * There are some fonts that have a large, bogus value for scriptCount. To try
* and protect against this, we use the offset in the first scriptRecord, * and protect against this, we use the offset in the first scriptRecord,
...@@ -74,38 +78,53 @@ const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const ...@@ -74,38 +78,53 @@ const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const
* to be unsorted. * to be unsorted.
*/ */
le_uint16 count = SWAPW(scriptCount); le_uint16 count = SWAPW(scriptCount);
if (count == 0) {
return LEReferenceTo<ScriptTable>(); // no items, no search
}
// attempt to construct a ref with at least one element
LEReferenceToArrayOf<ScriptRecord> oneElementTable(base, success, &scriptRecordArray[0], 1);
if( LE_FAILURE(success) ) {
return LEReferenceTo<ScriptTable>(); // couldn't even read the first record - bad font.
}
le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER; le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER;
Offset scriptTableOffset = 0; Offset scriptTableOffset = 0;
if (count > limit) { if (count > limit) {
// the scriptCount value is bogus; do a linear search // the scriptCount value is bogus; do a linear search
// because limit may still be too large. // because limit may still be too large.
for(le_int32 s = 0; s < limit; s += 1) { LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], limit);
if (SWAPT(scriptRecordArray[s].tag) == scriptTag) { for(le_int32 s = 0; (s < limit)&&LE_SUCCESS(success); s += 1) {
scriptTableOffset = SWAPW(scriptRecordArray[s].offset); if (SWAPT(scriptRecordArrayRef(s,success).tag) == scriptTag) {
break; scriptTableOffset = SWAPW(scriptRecordArrayRef(s,success).offset);
} break;
}
} }
} else { } else {
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count); LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count);
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO
} }
if (scriptTableOffset != 0) { if (scriptTableOffset != 0) {
return (const ScriptTable *) ((char *)this + scriptTableOffset); return LEReferenceTo<ScriptTable>(base, success, scriptTableOffset);
} }
return NULL; return LEReferenceTo<ScriptTable>();
} }
const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const LEReferenceTo<LangSysTable> ScriptListTable::findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
{ {
const ScriptTable *scriptTable = findScript(scriptTag); const LEReferenceTo<ScriptTable> scriptTable = findScript(base, scriptTag, success);
if (scriptTable == 0) { if (scriptTable.isEmpty()) {
return NULL; return LEReferenceTo<LangSysTable>();
} }
return scriptTable->findLanguage(languageTag, exactMatch); return scriptTable->findLanguage(scriptTable, languageTag, success, exactMatch).reparent(base);
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -51,6 +51,7 @@ struct LangSysTable ...@@ -51,6 +51,7 @@ struct LangSysTable
le_uint16 featureCount; le_uint16 featureCount;
le_uint16 featureIndexArray[ANY_NUMBER]; le_uint16 featureIndexArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(LangSysTable, featureIndexArray)
struct ScriptTable struct ScriptTable
{ {
...@@ -58,8 +59,9 @@ struct ScriptTable ...@@ -58,8 +59,9 @@ struct ScriptTable
le_uint16 langSysCount; le_uint16 langSysCount;
LangSysRecord langSysRecordArray[ANY_NUMBER]; LangSysRecord langSysRecordArray[ANY_NUMBER];
const LangSysTable *findLanguage(LETag languageTag, le_bool exactMatch = FALSE) const; LEReferenceTo<LangSysTable> findLanguage(const LETableReference &base, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
}; };
LE_VAR_ARRAY(ScriptTable, langSysRecordArray)
typedef TagAndOffsetRecord ScriptRecord; typedef TagAndOffsetRecord ScriptRecord;
...@@ -68,9 +70,10 @@ struct ScriptListTable ...@@ -68,9 +70,10 @@ struct ScriptListTable
le_uint16 scriptCount; le_uint16 scriptCount;
ScriptRecord scriptRecordArray[ANY_NUMBER]; ScriptRecord scriptRecordArray[ANY_NUMBER];
const ScriptTable *findScript(LETag scriptTag) const; LEReferenceTo<ScriptTable> findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const;
const LangSysTable *findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const; LEReferenceTo<LangSysTable> findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
}; };
LE_VAR_ARRAY(ScriptListTable, scriptRecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -46,19 +46,18 @@ SegmentArrayProcessor::SegmentArrayProcessor() ...@@ -46,19 +46,18 @@ SegmentArrayProcessor::SegmentArrayProcessor()
{ {
} }
SegmentArrayProcessor::SegmentArrayProcessor(const MorphSubtableHeader *morphSubtableHeader) SegmentArrayProcessor::SegmentArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
segmentArrayLookupTable = LEReferenceTo<SegmentArrayLookupTable>(morphSubtableHeader, success, (const SegmentArrayLookupTable*)&header->table);
segmentArrayLookupTable = (const SegmentArrayLookupTable *) &header->table;
} }
SegmentArrayProcessor::~SegmentArrayProcessor() SegmentArrayProcessor::~SegmentArrayProcessor()
{ {
} }
void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage) void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
const LookupSegment *segments = segmentArrayLookupTable->segments; const LookupSegment *segments = segmentArrayLookupTable->segments;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
...@@ -66,17 +65,16 @@ void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage) ...@@ -66,17 +65,16 @@ void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage)
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, thisGlyph); const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success);
if (lookupSegment != NULL) { if (lookupSegment != NULL) {
TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph); TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
le_int16 offset = SWAPW(lookupSegment->value); le_int16 offset = SWAPW(lookupSegment->value);
if (offset != 0) { if (offset != 0) {
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset); LEReferenceToArrayOf<TTGlyphID> glyphArray(subtableHeader, success, offset, LE_UNBOUNDED_ARRAY);
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]); TTGlyphID newGlyph = SWAPW(glyphArray(LE_GET_GLYPH(thisGlyph) - firstGlyph, success));
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
} }
} }
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SegmentArrayProcessor : public NonContextualGlyphSubstitutionProcessor class SegmentArrayProcessor : public NonContextualGlyphSubstitutionProcessor
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SegmentArrayProcessor(const MorphSubtableHeader *morphSubtableHeader); SegmentArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~SegmentArrayProcessor(); virtual ~SegmentArrayProcessor();
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
SegmentArrayProcessor(); SegmentArrayProcessor();
protected: protected:
const SegmentArrayLookupTable *segmentArrayLookupTable; LEReferenceTo<SegmentArrayLookupTable> segmentArrayLookupTable;
}; };
......
...@@ -46,19 +46,18 @@ SegmentArrayProcessor2::SegmentArrayProcessor2() ...@@ -46,19 +46,18 @@ SegmentArrayProcessor2::SegmentArrayProcessor2()
{ {
} }
SegmentArrayProcessor2::SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) SegmentArrayProcessor2::SegmentArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader; const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
segmentArrayLookupTable = LEReferenceTo<SegmentArrayLookupTable>(morphSubtableHeader, success, &header->table); // don't parent to 'header' as it is on the stack
segmentArrayLookupTable = (const SegmentArrayLookupTable *) &header->table;
} }
SegmentArrayProcessor2::~SegmentArrayProcessor2() SegmentArrayProcessor2::~SegmentArrayProcessor2()
{ {
} }
void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage) void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
const LookupSegment *segments = segmentArrayLookupTable->segments; const LookupSegment *segments = segmentArrayLookupTable->segments;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
...@@ -66,14 +65,14 @@ void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -66,14 +65,14 @@ void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage)
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, thisGlyph); const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success);
if (lookupSegment != NULL) { if (lookupSegment != NULL) {
TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph); TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
le_int16 offset = SWAPW(lookupSegment->value); le_int16 offset = SWAPW(lookupSegment->value);
if (offset != 0) { if (offset != 0) {
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset); TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader.getAliasTODO() + offset);
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]); TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SegmentArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2 class SegmentArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); SegmentArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~SegmentArrayProcessor2(); virtual ~SegmentArrayProcessor2();
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
SegmentArrayProcessor2(); SegmentArrayProcessor2();
protected: protected:
const SegmentArrayLookupTable *segmentArrayLookupTable; LEReferenceTo<SegmentArrayLookupTable> segmentArrayLookupTable;
}; };
......
...@@ -46,29 +46,28 @@ SegmentSingleProcessor::SegmentSingleProcessor() ...@@ -46,29 +46,28 @@ SegmentSingleProcessor::SegmentSingleProcessor()
{ {
} }
SegmentSingleProcessor::SegmentSingleProcessor(const MorphSubtableHeader *morphSubtableHeader) SegmentSingleProcessor::SegmentSingleProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
segmentSingleLookupTable = LEReferenceTo<SegmentSingleLookupTable>(morphSubtableHeader, success, (const SegmentSingleLookupTable*)&header->table);
segmentSingleLookupTable = (const SegmentSingleLookupTable *) &header->table;
} }
SegmentSingleProcessor::~SegmentSingleProcessor() SegmentSingleProcessor::~SegmentSingleProcessor()
{ {
} }
void SegmentSingleProcessor::process(LEGlyphStorage &glyphStorage) void SegmentSingleProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
const LookupSegment *segments = segmentSingleLookupTable->segments; const LookupSegment *segments = segmentSingleLookupTable->segments;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
le_int32 glyph; le_int32 glyph;
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount && LE_SUCCESS(success); glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph); const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segmentSingleLookupTable, segments, thisGlyph, success);
if (lookupSegment != NULL) { if (lookupSegment != NULL && LE_SUCCESS(success)) {
TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value); TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SegmentSingleProcessor : public NonContextualGlyphSubstitutionProcessor class SegmentSingleProcessor : public NonContextualGlyphSubstitutionProcessor
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SegmentSingleProcessor(const MorphSubtableHeader *morphSubtableHeader); SegmentSingleProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~SegmentSingleProcessor(); virtual ~SegmentSingleProcessor();
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
SegmentSingleProcessor(); SegmentSingleProcessor();
protected: protected:
const SegmentSingleLookupTable *segmentSingleLookupTable; LEReferenceTo<SegmentSingleLookupTable> segmentSingleLookupTable;
}; };
......
...@@ -46,19 +46,19 @@ SegmentSingleProcessor2::SegmentSingleProcessor2() ...@@ -46,19 +46,19 @@ SegmentSingleProcessor2::SegmentSingleProcessor2()
{ {
} }
SegmentSingleProcessor2::SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) SegmentSingleProcessor2::SegmentSingleProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader; const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
segmentSingleLookupTable = (const SegmentSingleLookupTable *) &header->table; segmentSingleLookupTable = LEReferenceTo<SegmentSingleLookupTable>(morphSubtableHeader, success, &header->table);
} }
SegmentSingleProcessor2::~SegmentSingleProcessor2() SegmentSingleProcessor2::~SegmentSingleProcessor2()
{ {
} }
void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage) void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
const LookupSegment *segments = segmentSingleLookupTable->segments; const LookupSegment *segments = segmentSingleLookupTable->segments;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
...@@ -66,9 +66,9 @@ void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -66,9 +66,9 @@ void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage)
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph); const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segmentSingleLookupTable, segments, thisGlyph, success);
if (lookupSegment != NULL) { if (lookupSegment != NULL && LE_SUCCESS(success)) {
TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value); TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SegmentSingleProcessor2 : public NonContextualGlyphSubstitutionProcessor2 class SegmentSingleProcessor2 : public NonContextualGlyphSubstitutionProcessor2
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); SegmentSingleProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~SegmentSingleProcessor2(); virtual ~SegmentSingleProcessor2();
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
SegmentSingleProcessor2(); SegmentSingleProcessor2();
protected: protected:
const SegmentSingleLookupTable *segmentSingleLookupTable; LEReferenceTo<SegmentSingleLookupTable> segmentSingleLookupTable;
}; };
......
...@@ -122,4 +122,6 @@ const le_uint8 ArabicShaping::shapingTypeTable[] = { ...@@ -122,4 +122,6 @@ const le_uint8 ArabicShaping::shapingTypeTable[] = {
0x00, 0x05, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x05, 0xFF, 0xF9, 0xFF, 0xFB, 0x00, 0x05 0x00, 0x05, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x05, 0xFF, 0xF9, 0xFF, 0xFB, 0x00, 0x05
}; };
const size_t ArabicShaping::shapingTypeTableLen = sizeof(shapingTypeTable)/sizeof(shapingTypeTable[0]);
U_NAMESPACE_END U_NAMESPACE_END
...@@ -46,29 +46,29 @@ SimpleArrayProcessor::SimpleArrayProcessor() ...@@ -46,29 +46,29 @@ SimpleArrayProcessor::SimpleArrayProcessor()
{ {
} }
SimpleArrayProcessor::SimpleArrayProcessor(const MorphSubtableHeader *morphSubtableHeader) SimpleArrayProcessor::SimpleArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
simpleArrayLookupTable = LEReferenceTo<SimpleArrayLookupTable>(morphSubtableHeader, success, (const SimpleArrayLookupTable*)&header->table);
simpleArrayLookupTable = (const SimpleArrayLookupTable *) &header->table;
} }
SimpleArrayProcessor::~SimpleArrayProcessor() SimpleArrayProcessor::~SimpleArrayProcessor()
{ {
} }
void SimpleArrayProcessor::process(LEGlyphStorage &glyphStorage) void SimpleArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
le_int32 glyph; le_int32 glyph;
for (glyph = 0; glyph < glyphCount; glyph += 1) { LEReferenceToArrayOf<LookupValue> valueArray(simpleArrayLookupTable, success, (const LookupValue*)&simpleArrayLookupTable->valueArray, LE_UNBOUNDED_ARRAY);
for (glyph = 0; LE_SUCCESS(success) && (glyph < glyphCount); glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) { if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) {
TTGlyphID newGlyph = SWAPW(simpleArrayLookupTable->valueArray[LE_GET_GLYPH(thisGlyph)]); TTGlyphID newGlyph = SWAPW(valueArray.getObject(LE_GET_GLYPH(thisGlyph),success));
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
} }
} }
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SimpleArrayProcessor : public NonContextualGlyphSubstitutionProcessor class SimpleArrayProcessor : public NonContextualGlyphSubstitutionProcessor
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SimpleArrayProcessor(const MorphSubtableHeader *morphSubtableHeader); SimpleArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~SimpleArrayProcessor(); virtual ~SimpleArrayProcessor();
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
SimpleArrayProcessor(); SimpleArrayProcessor();
protected: protected:
const SimpleArrayLookupTable *simpleArrayLookupTable; LEReferenceTo<SimpleArrayLookupTable> simpleArrayLookupTable;
}; };
......
...@@ -46,27 +46,29 @@ SimpleArrayProcessor2::SimpleArrayProcessor2() ...@@ -46,27 +46,29 @@ SimpleArrayProcessor2::SimpleArrayProcessor2()
{ {
} }
SimpleArrayProcessor2::SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) SimpleArrayProcessor2::SimpleArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader; const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
simpleArrayLookupTable = (const SimpleArrayLookupTable *) &header->table; simpleArrayLookupTable = LEReferenceTo<SimpleArrayLookupTable>(morphSubtableHeader, success, &header->table);
valueArray = LEReferenceToArrayOf<LookupValue>(morphSubtableHeader, success, &simpleArrayLookupTable->valueArray[0], LE_UNBOUNDED_ARRAY);
} }
SimpleArrayProcessor2::~SimpleArrayProcessor2() SimpleArrayProcessor2::~SimpleArrayProcessor2()
{ {
} }
void SimpleArrayProcessor2::process(LEGlyphStorage &glyphStorage) void SimpleArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
if (LE_FAILURE(success)) return;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
le_int32 glyph; le_int32 glyph;
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) { if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) {
TTGlyphID newGlyph = SWAPW(simpleArrayLookupTable->valueArray[LE_GET_GLYPH(thisGlyph)]); TTGlyphID newGlyph = SWAPW(valueArray(LE_GET_GLYPH(thisGlyph),success));
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SimpleArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2 class SimpleArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); SimpleArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~SimpleArrayProcessor2(); virtual ~SimpleArrayProcessor2();
...@@ -74,7 +74,8 @@ private: ...@@ -74,7 +74,8 @@ private:
SimpleArrayProcessor2(); SimpleArrayProcessor2();
protected: protected:
const SimpleArrayLookupTable *simpleArrayLookupTable; LEReferenceTo<SimpleArrayLookupTable> simpleArrayLookupTable;
LEReferenceToArrayOf<LookupValue> valueArray;
}; };
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_uint32 SinglePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const le_uint32 SinglePositioningSubtable::process(const LEReferenceTo<SinglePositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{ {
switch(SWAPW(subtableFormat)) switch(SWAPW(subtableFormat))
{ {
...@@ -49,16 +49,16 @@ le_uint32 SinglePositioningSubtable::process(GlyphIterator *glyphIterator, const ...@@ -49,16 +49,16 @@ le_uint32 SinglePositioningSubtable::process(GlyphIterator *glyphIterator, const
case 1: case 1:
{ {
const SinglePositioningFormat1Subtable *subtable = (const SinglePositioningFormat1Subtable *) this; const LEReferenceTo<SinglePositioningFormat1Subtable> subtable(base, success, (const SinglePositioningFormat1Subtable *) this);
return subtable->process(glyphIterator, fontInstance); return subtable->process(subtable, glyphIterator, fontInstance, success);
} }
case 2: case 2:
{ {
const SinglePositioningFormat2Subtable *subtable = (const SinglePositioningFormat2Subtable *) this; const LEReferenceTo<SinglePositioningFormat2Subtable> subtable(base, success, (const SinglePositioningFormat2Subtable *) this);
return subtable->process(glyphIterator, fontInstance); return subtable->process(subtable, glyphIterator, fontInstance, success);
} }
default: default:
...@@ -66,10 +66,10 @@ le_uint32 SinglePositioningSubtable::process(GlyphIterator *glyphIterator, const ...@@ -66,10 +66,10 @@ le_uint32 SinglePositioningSubtable::process(GlyphIterator *glyphIterator, const
} }
} }
le_uint32 SinglePositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{ {
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
valueRecord.adjustPosition(SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance); valueRecord.adjustPosition(SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance);
...@@ -80,10 +80,10 @@ le_uint32 SinglePositioningFormat1Subtable::process(GlyphIterator *glyphIterator ...@@ -80,10 +80,10 @@ le_uint32 SinglePositioningFormat1Subtable::process(GlyphIterator *glyphIterator
return 0; return 0;
} }
le_uint32 SinglePositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
{ {
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int16 coverageIndex = (le_int16) getGlyphCoverage(glyph); le_int16 coverageIndex = (le_int16) getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance); valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance);
......
...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN ...@@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
struct SinglePositioningSubtable : GlyphPositioningSubtable struct SinglePositioningSubtable : GlyphPositioningSubtable
{ {
le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LEReferenceTo<SinglePositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
}; };
struct SinglePositioningFormat1Subtable : SinglePositioningSubtable struct SinglePositioningFormat1Subtable : SinglePositioningSubtable
...@@ -56,7 +56,7 @@ struct SinglePositioningFormat1Subtable : SinglePositioningSubtable ...@@ -56,7 +56,7 @@ struct SinglePositioningFormat1Subtable : SinglePositioningSubtable
ValueFormat valueFormat; ValueFormat valueFormat;
ValueRecord valueRecord; ValueRecord valueRecord;
le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LEReferenceTo<SinglePositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
}; };
struct SinglePositioningFormat2Subtable : SinglePositioningSubtable struct SinglePositioningFormat2Subtable : SinglePositioningSubtable
...@@ -65,8 +65,9 @@ struct SinglePositioningFormat2Subtable : SinglePositioningSubtable ...@@ -65,8 +65,9 @@ struct SinglePositioningFormat2Subtable : SinglePositioningSubtable
le_uint16 valueCount; le_uint16 valueCount;
ValueRecord valueRecordArray[ANY_NUMBER]; ValueRecord valueRecordArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LEReferenceTo<SinglePositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(SinglePositioningFormat2Subtable, valueRecordArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_uint32 SingleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const le_uint32 SingleSubstitutionSubtable::process(const LEReferenceTo<SingleSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
{ {
switch(SWAPW(subtableFormat)) switch(SWAPW(subtableFormat))
{ {
...@@ -48,16 +48,16 @@ le_uint32 SingleSubstitutionSubtable::process(GlyphIterator *glyphIterator, cons ...@@ -48,16 +48,16 @@ le_uint32 SingleSubstitutionSubtable::process(GlyphIterator *glyphIterator, cons
case 1: case 1:
{ {
const SingleSubstitutionFormat1Subtable *subtable = (const SingleSubstitutionFormat1Subtable *) this; const LEReferenceTo<SingleSubstitutionFormat1Subtable> subtable(base, success, (const SingleSubstitutionFormat1Subtable *) this);
return subtable->process(glyphIterator, filter); return subtable->process(subtable, glyphIterator, success, filter);
} }
case 2: case 2:
{ {
const SingleSubstitutionFormat2Subtable *subtable = (const SingleSubstitutionFormat2Subtable *) this; const LEReferenceTo<SingleSubstitutionFormat2Subtable> subtable(base, success, (const SingleSubstitutionFormat2Subtable *) this);
return subtable->process(glyphIterator, filter); return subtable->process(subtable, glyphIterator, success, filter);
} }
default: default:
...@@ -65,10 +65,10 @@ le_uint32 SingleSubstitutionSubtable::process(GlyphIterator *glyphIterator, cons ...@@ -65,10 +65,10 @@ le_uint32 SingleSubstitutionSubtable::process(GlyphIterator *glyphIterator, cons
} }
} }
le_uint32 SingleSubstitutionFormat1Subtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleSubstitutionFormat1Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
{ {
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID); TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID);
...@@ -83,10 +83,10 @@ le_uint32 SingleSubstitutionFormat1Subtable::process(GlyphIterator *glyphIterato ...@@ -83,10 +83,10 @@ le_uint32 SingleSubstitutionFormat1Subtable::process(GlyphIterator *glyphIterato
return 0; return 0;
} }
le_uint32 SingleSubstitutionFormat2Subtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleSubstitutionFormat2Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
{ {
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]); TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]);
......
...@@ -47,14 +47,14 @@ U_NAMESPACE_BEGIN ...@@ -47,14 +47,14 @@ U_NAMESPACE_BEGIN
struct SingleSubstitutionSubtable : GlyphSubstitutionSubtable struct SingleSubstitutionSubtable : GlyphSubstitutionSubtable
{ {
le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; le_uint32 process(const LEReferenceTo<SingleSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
}; };
struct SingleSubstitutionFormat1Subtable : SingleSubstitutionSubtable struct SingleSubstitutionFormat1Subtable : SingleSubstitutionSubtable
{ {
le_int16 deltaGlyphID; le_int16 deltaGlyphID;
le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; le_uint32 process(const LEReferenceTo<SingleSubstitutionFormat1Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
}; };
struct SingleSubstitutionFormat2Subtable : SingleSubstitutionSubtable struct SingleSubstitutionFormat2Subtable : SingleSubstitutionSubtable
...@@ -62,8 +62,9 @@ struct SingleSubstitutionFormat2Subtable : SingleSubstitutionSubtable ...@@ -62,8 +62,9 @@ struct SingleSubstitutionFormat2Subtable : SingleSubstitutionSubtable
le_uint16 glyphCount; le_uint16 glyphCount;
TTGlyphID substituteArray[ANY_NUMBER]; TTGlyphID substituteArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; le_uint32 process(const LEReferenceTo<SingleSubstitutionFormat2Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
}; };
LE_VAR_ARRAY(SingleSubstitutionFormat2Subtable, substituteArray)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -46,26 +46,25 @@ SingleTableProcessor::SingleTableProcessor() ...@@ -46,26 +46,25 @@ SingleTableProcessor::SingleTableProcessor()
{ {
} }
SingleTableProcessor::SingleTableProcessor(const MorphSubtableHeader *moprhSubtableHeader) SingleTableProcessor::SingleTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor(moprhSubtableHeader) : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) moprhSubtableHeader; LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
singleTableLookupTable = LEReferenceTo<SingleTableLookupTable>(morphSubtableHeader, success, (const SingleTableLookupTable*)&header->table);
singleTableLookupTable = (const SingleTableLookupTable *) &header->table;
} }
SingleTableProcessor::~SingleTableProcessor() SingleTableProcessor::~SingleTableProcessor()
{ {
} }
void SingleTableProcessor::process(LEGlyphStorage &glyphStorage) void SingleTableProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
const LookupSingle *entries = singleTableLookupTable->entries; const LookupSingle *entries = singleTableLookupTable->entries;
le_int32 glyph; le_int32 glyph;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(entries, glyphStorage[glyph]); const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(singleTableLookupTable, entries, glyphStorage[glyph], success);
if (lookupSingle != NULL) { if (lookupSingle != NULL) {
glyphStorage[glyph] = SWAPW(lookupSingle->value); glyphStorage[glyph] = SWAPW(lookupSingle->value);
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SingleTableProcessor : public NonContextualGlyphSubstitutionProcessor class SingleTableProcessor : public NonContextualGlyphSubstitutionProcessor
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SingleTableProcessor(const MorphSubtableHeader *morphSubtableHeader); SingleTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~SingleTableProcessor(); virtual ~SingleTableProcessor();
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
SingleTableProcessor(); SingleTableProcessor();
protected: protected:
const SingleTableLookupTable *singleTableLookupTable; LEReferenceTo<SingleTableLookupTable> singleTableLookupTable;
}; };
......
...@@ -46,26 +46,27 @@ SingleTableProcessor2::SingleTableProcessor2() ...@@ -46,26 +46,27 @@ SingleTableProcessor2::SingleTableProcessor2()
{ {
} }
SingleTableProcessor2::SingleTableProcessor2(const MorphSubtableHeader2 *moprhSubtableHeader) SingleTableProcessor2::SingleTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor2(moprhSubtableHeader) : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) moprhSubtableHeader; const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
singleTableLookupTable = (const SingleTableLookupTable *) &header->table; singleTableLookupTable = LEReferenceTo<SingleTableLookupTable>(morphSubtableHeader, success, &header->table);
} }
SingleTableProcessor2::~SingleTableProcessor2() SingleTableProcessor2::~SingleTableProcessor2()
{ {
} }
void SingleTableProcessor2::process(LEGlyphStorage &glyphStorage) void SingleTableProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
if(LE_FAILURE(success)) return;
const LookupSingle *entries = singleTableLookupTable->entries; const LookupSingle *entries = singleTableLookupTable->entries;
le_int32 glyph; le_int32 glyph;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(entries, glyphStorage[glyph]); const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(singleTableLookupTable, entries, glyphStorage[glyph], success);
if (lookupSingle != NULL) { if (lookupSingle != NULL) {
glyphStorage[glyph] = SWAPW(lookupSingle->value); glyphStorage[glyph] = SWAPW(lookupSingle->value);
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class SingleTableProcessor2 : public NonContextualGlyphSubstitutionProcessor2 class SingleTableProcessor2 : public NonContextualGlyphSubstitutionProcessor2
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
SingleTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); SingleTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~SingleTableProcessor2(); virtual ~SingleTableProcessor2();
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
SingleTableProcessor2(); SingleTableProcessor2();
protected: protected:
const SingleTableLookupTable *singleTableLookupTable; LEReferenceTo<SingleTableLookupTable> singleTableLookupTable;
}; };
......
...@@ -44,17 +44,18 @@ StateTableProcessor::StateTableProcessor() ...@@ -44,17 +44,18 @@ StateTableProcessor::StateTableProcessor()
{ {
} }
StateTableProcessor::StateTableProcessor(const MorphSubtableHeader *morphSubtableHeader) StateTableProcessor::StateTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: SubtableProcessor(morphSubtableHeader) : SubtableProcessor(morphSubtableHeader, success), stateTableHeader(morphSubtableHeader, success),
stHeader(stateTableHeader, success, (const StateTableHeader*)&stateTableHeader->stHeader)
{ {
stateTableHeader = (const MorphStateTableHeader *) morphSubtableHeader; if(LE_FAILURE(success)) return;
stateSize = SWAPW(stateTableHeader->stHeader.stateSize); stateSize = SWAPW(stateTableHeader->stHeader.stateSize);
classTableOffset = SWAPW(stateTableHeader->stHeader.classTableOffset); classTableOffset = SWAPW(stateTableHeader->stHeader.classTableOffset);
stateArrayOffset = SWAPW(stateTableHeader->stHeader.stateArrayOffset); stateArrayOffset = SWAPW(stateTableHeader->stHeader.stateArrayOffset);
entryTableOffset = SWAPW(stateTableHeader->stHeader.entryTableOffset); entryTableOffset = SWAPW(stateTableHeader->stHeader.entryTableOffset);
classTable = (const ClassTable *) ((char *) &stateTableHeader->stHeader + classTableOffset); classTable = LEReferenceTo<ClassTable>(stateTableHeader, success, ((char *) &stateTableHeader->stHeader + classTableOffset));
if(LE_FAILURE(success)) return;
firstGlyph = SWAPW(classTable->firstGlyph); firstGlyph = SWAPW(classTable->firstGlyph);
lastGlyph = firstGlyph + SWAPW(classTable->nGlyphs); lastGlyph = firstGlyph + SWAPW(classTable->nGlyphs);
} }
...@@ -63,9 +64,9 @@ StateTableProcessor::~StateTableProcessor() ...@@ -63,9 +64,9 @@ StateTableProcessor::~StateTableProcessor()
{ {
} }
void StateTableProcessor::process(LEGlyphStorage &glyphStorage) void StateTableProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
if (LE_FAILURE(success)) return;
LE_STATE_PATIENCE_INIT(); LE_STATE_PATIENCE_INIT();
// Start at state 0 // Start at state 0
...@@ -94,8 +95,8 @@ void StateTableProcessor::process(LEGlyphStorage &glyphStorage) ...@@ -94,8 +95,8 @@ void StateTableProcessor::process(LEGlyphStorage &glyphStorage)
} }
} }
const EntryTableIndex *stateArray = (const EntryTableIndex *) ((char *) &stateTableHeader->stHeader + currentState); LEReferenceToArrayOf<EntryTableIndex> stateArray(stHeader, success, currentState, LE_UNBOUNDED_ARRAY);
EntryTableIndex entryTableIndex = stateArray[(le_uint8)classCode]; EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success);
LE_STATE_PATIENCE_CURR(le_int32, currGlyph); LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
LE_STATE_PATIENCE_INCR(currGlyph); LE_STATE_PATIENCE_INCR(currGlyph);
......
...@@ -49,7 +49,7 @@ class LEGlyphStorage; ...@@ -49,7 +49,7 @@ class LEGlyphStorage;
class StateTableProcessor : public SubtableProcessor class StateTableProcessor : public SubtableProcessor
{ {
public: public:
void process(LEGlyphStorage &glyphStorage); void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
virtual void beginStateTable() = 0; virtual void beginStateTable() = 0;
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
virtual void endStateTable() = 0; virtual void endStateTable() = 0;
protected: protected:
StateTableProcessor(const MorphSubtableHeader *morphSubtableHeader); StateTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~StateTableProcessor(); virtual ~StateTableProcessor();
StateTableProcessor(); StateTableProcessor();
...@@ -68,11 +68,12 @@ protected: ...@@ -68,11 +68,12 @@ protected:
ByteOffset stateArrayOffset; ByteOffset stateArrayOffset;
ByteOffset entryTableOffset; ByteOffset entryTableOffset;
const ClassTable *classTable; LEReferenceTo<ClassTable> classTable;
TTGlyphID firstGlyph; TTGlyphID firstGlyph;
TTGlyphID lastGlyph; TTGlyphID lastGlyph;
const MorphStateTableHeader *stateTableHeader; LEReferenceTo<MorphStateTableHeader> stateTableHeader;
LEReferenceTo<StateTableHeader> stHeader; // for convenience
private: private:
StateTableProcessor(const StateTableProcessor &other); // forbid copying of this class StateTableProcessor(const StateTableProcessor &other); // forbid copying of this class
......
...@@ -45,27 +45,33 @@ StateTableProcessor2::StateTableProcessor2() ...@@ -45,27 +45,33 @@ StateTableProcessor2::StateTableProcessor2()
{ {
} }
StateTableProcessor2::StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) StateTableProcessor2::StateTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: SubtableProcessor2(morphSubtableHeader) : SubtableProcessor2(morphSubtableHeader, success), stateTableHeader(morphSubtableHeader, success),
stHeader(stateTableHeader, success, (const StateTableHeader2*)&stateTableHeader->stHeader),
nClasses(0), classTableOffset(0), stateArrayOffset(0), entryTableOffset(0), classTable(), format(0),
stateArray()
{ {
stateTableHeader = (const MorphStateTableHeader2 *) morphSubtableHeader; if (LE_FAILURE(success)) {
nClasses = SWAPL(stateTableHeader->stHeader.nClasses); return;
classTableOffset = SWAPL(stateTableHeader->stHeader.classTableOffset); }
stateArrayOffset = SWAPL(stateTableHeader->stHeader.stateArrayOffset); nClasses = SWAPL(stHeader->nClasses);
entryTableOffset = SWAPL(stateTableHeader->stHeader.entryTableOffset); classTableOffset = SWAPL(stHeader->classTableOffset);
stateArrayOffset = SWAPL(stHeader->stateArrayOffset);
classTable = (LookupTable *) ((char *) &stateTableHeader->stHeader + classTableOffset); entryTableOffset = SWAPL(stHeader->entryTableOffset);
format = SWAPW(classTable->format);
classTable = LEReferenceTo<LookupTable>(stHeader, success, classTableOffset);
stateArray = (const EntryTableIndex2 *) ((char *) &stateTableHeader->stHeader + stateArrayOffset); format = SWAPW(classTable->format);
stateArray = LEReferenceToArrayOf<EntryTableIndex2>(stHeader, success, stateArrayOffset, LE_UNBOUNDED_ARRAY);
} }
StateTableProcessor2::~StateTableProcessor2() StateTableProcessor2::~StateTableProcessor2()
{ {
} }
void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) void StateTableProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
if (LE_FAILURE(success)) return;
// Start at state 0 // Start at state 0
// XXX: How do we know when to start at state 1? // XXX: How do we know when to start at state 1?
le_uint16 currentState = 0; le_uint16 currentState = 0;
...@@ -85,9 +91,11 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -85,9 +91,11 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
switch (format) { switch (format) {
case ltfSimpleArray: { case ltfSimpleArray: {
#ifdef TEST_FORMAT #ifdef TEST_FORMAT
SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) classTable; LEReferenceTo<SimpleArrayLookupTable> lookupTable0(classTable, success);
if(LE_FAILURE(success)) break;
while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
if(LE_STATE_PATIENCE_DECR()) { if (LE_FAILURE(success)) break;
if (LE_STATE_PATIENCE_DECR()) {
LE_DEBUG_BAD_FONT("patience exceeded - state table not moving") LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
break; // patience exceeded. break; // patience exceeded.
} }
...@@ -105,7 +113,7 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -105,7 +113,7 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
classCode = SWAPW(lookupTable0->valueArray[gid]); classCode = SWAPW(lookupTable0->valueArray[gid]);
} }
} }
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success));
LE_STATE_PATIENCE_CURR(le_int32, currGlyph); LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset
LE_STATE_PATIENCE_INCR(currGlyph); LE_STATE_PATIENCE_INCR(currGlyph);
...@@ -114,10 +122,12 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -114,10 +122,12 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
break; break;
} }
case ltfSegmentSingle: { case ltfSegmentSingle: {
SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) classTable; LEReferenceTo<SegmentSingleLookupTable> lookupTable2(classTable, success);
if(LE_FAILURE(success)) break;
while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
if(LE_STATE_PATIENCE_DECR()) { if (LE_FAILURE(success)) break;
LE_DEBUG_BAD_FONT("patience exceeded - state table not moving") if (LE_STATE_PATIENCE_DECR()) {
LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
break; // patience exceeded. break; // patience exceeded.
} }
LookupValue classCode = classCodeOOB; LookupValue classCode = classCodeOOB;
...@@ -131,15 +141,16 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -131,15 +141,16 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
if (glyphCode == 0xFFFF) { if (glyphCode == 0xFFFF) {
classCode = classCodeDEL; classCode = classCodeDEL;
} else { } else {
const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid); const LookupSegment *segment =
if (segment != NULL) { lookupTable2->lookupSegment(lookupTable2, lookupTable2->segments, gid, success);
if (segment != NULL && LE_SUCCESS(success)) {
classCode = SWAPW(segment->value); classCode = SWAPW(segment->value);
} }
} }
} }
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses,success));
LE_STATE_PATIENCE_CURR(le_int32, currGlyph); LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
LE_STATE_PATIENCE_INCR(currGlyph); LE_STATE_PATIENCE_INCR(currGlyph);
} }
break; break;
...@@ -149,9 +160,10 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -149,9 +160,10 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
break; break;
} }
case ltfSingleTable: { case ltfSingleTable: {
SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) classTable; LEReferenceTo<SingleTableLookupTable> lookupTable6(classTable, success);
while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
if(LE_STATE_PATIENCE_DECR()) { if (LE_FAILURE(success)) break;
if (LE_STATE_PATIENCE_DECR()) {
LE_DEBUG_BAD_FONT("patience exceeded - state table not moving") LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
break; // patience exceeded. break; // patience exceeded.
} }
...@@ -170,21 +182,22 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -170,21 +182,22 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
if (glyphCode == 0xFFFF) { if (glyphCode == 0xFFFF) {
classCode = classCodeDEL; classCode = classCodeDEL;
} else { } else {
const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid); const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6, lookupTable6->entries, gid, success);
if (segment != NULL) { if (segment != NULL) {
classCode = SWAPW(segment->value); classCode = SWAPW(segment->value);
} }
} }
} }
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success));
LE_STATE_PATIENCE_CURR(le_int32, currGlyph); LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
LE_STATE_PATIENCE_INCR(currGlyph); LE_STATE_PATIENCE_INCR(currGlyph);
} }
break; break;
} }
case ltfTrimmedArray: { case ltfTrimmedArray: {
TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) classTable; LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(classTable, success);
if (LE_FAILURE(success)) break;
TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount); TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount);
...@@ -206,9 +219,9 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -206,9 +219,9 @@ void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]); classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
} }
} }
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]); EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success));
LE_STATE_PATIENCE_CURR(le_int32, currGlyph); LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
LE_STATE_PATIENCE_INCR(currGlyph); LE_STATE_PATIENCE_INCR(currGlyph);
} }
break; break;
......
...@@ -50,16 +50,16 @@ class LEGlyphStorage; ...@@ -50,16 +50,16 @@ class LEGlyphStorage;
class StateTableProcessor2 : public SubtableProcessor2 class StateTableProcessor2 : public SubtableProcessor2
{ {
public: public:
void process(LEGlyphStorage &glyphStorage); void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
virtual void beginStateTable() = 0; virtual void beginStateTable() = 0;
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index) = 0; virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success) = 0;
virtual void endStateTable() = 0; virtual void endStateTable() = 0;
protected: protected:
StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); StateTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~StateTableProcessor2(); virtual ~StateTableProcessor2();
StateTableProcessor2(); StateTableProcessor2();
...@@ -71,9 +71,10 @@ protected: ...@@ -71,9 +71,10 @@ protected:
le_uint32 stateArrayOffset; le_uint32 stateArrayOffset;
le_uint32 entryTableOffset; le_uint32 entryTableOffset;
const LookupTable *classTable; LEReferenceTo<LookupTable> classTable;
const EntryTableIndex2 *stateArray; LEReferenceToArrayOf<EntryTableIndex2> stateArray;
const MorphStateTableHeader2 *stateTableHeader; LEReferenceTo<MorphStateTableHeader2> stateTableHeader;
LEReferenceTo<StateTableHeader2> stHeader; // for convenience
private: private:
StateTableProcessor2(const StateTableProcessor2 &other); // forbid copying of this class StateTableProcessor2(const StateTableProcessor2 &other); // forbid copying of this class
......
...@@ -111,6 +111,7 @@ struct ClassTable ...@@ -111,6 +111,7 @@ struct ClassTable
le_uint16 nGlyphs; le_uint16 nGlyphs;
ClassCode classArray[ANY_NUMBER]; ClassCode classArray[ANY_NUMBER];
}; };
LE_VAR_ARRAY(ClassTable, classArray)
enum StateNumber enum StateNumber
{ {
......
...@@ -40,10 +40,10 @@ SubtableProcessor::SubtableProcessor() ...@@ -40,10 +40,10 @@ SubtableProcessor::SubtableProcessor()
{ {
} }
SubtableProcessor::SubtableProcessor(const MorphSubtableHeader *morphSubtableHeader) SubtableProcessor::SubtableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: length(0), coverage(0), subtableFeatures(0L), subtableHeader(morphSubtableHeader)
{ {
subtableHeader = morphSubtableHeader; if(LE_FAILURE(success)) return;
length = SWAPW(subtableHeader->length); length = SWAPW(subtableHeader->length);
coverage = SWAPW(subtableHeader->coverage); coverage = SWAPW(subtableHeader->coverage);
subtableFeatures = SWAPL(subtableHeader->subtableFeatures); subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
......
...@@ -46,11 +46,11 @@ class LEGlyphStorage; ...@@ -46,11 +46,11 @@ class LEGlyphStorage;
class SubtableProcessor : public UMemory { class SubtableProcessor : public UMemory {
public: public:
virtual void process(LEGlyphStorage &glyphStorage) = 0; virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
virtual ~SubtableProcessor(); virtual ~SubtableProcessor();
protected: protected:
SubtableProcessor(const MorphSubtableHeader *morphSubtableHeader); SubtableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
SubtableProcessor(); SubtableProcessor();
...@@ -58,7 +58,7 @@ protected: ...@@ -58,7 +58,7 @@ protected:
SubtableCoverage coverage; SubtableCoverage coverage;
FeatureFlags subtableFeatures; FeatureFlags subtableFeatures;
const MorphSubtableHeader *subtableHeader; const LEReferenceTo<MorphSubtableHeader> subtableHeader;
private: private:
......
...@@ -40,13 +40,14 @@ SubtableProcessor2::SubtableProcessor2() ...@@ -40,13 +40,14 @@ SubtableProcessor2::SubtableProcessor2()
{ {
} }
SubtableProcessor2::SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) SubtableProcessor2::SubtableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: subtableHeader(morphSubtableHeader, success), length(0), coverage(0), subtableFeatures(0L)
{ {
subtableHeader = morphSubtableHeader; if(LE_FAILURE(success)) return;
length = SWAPL(subtableHeader->length); length = SWAPL(subtableHeader->length);
coverage = SWAPL(subtableHeader->coverage); coverage = SWAPL(subtableHeader->coverage);
subtableFeatures = SWAPL(subtableHeader->subtableFeatures); subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
} }
SubtableProcessor2::~SubtableProcessor2() SubtableProcessor2::~SubtableProcessor2()
......
...@@ -46,11 +46,11 @@ class LEGlyphStorage; ...@@ -46,11 +46,11 @@ class LEGlyphStorage;
class SubtableProcessor2 : public UMemory { class SubtableProcessor2 : public UMemory {
public: public:
virtual void process(LEGlyphStorage &glyphStorage) = 0; virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
virtual ~SubtableProcessor2(); virtual ~SubtableProcessor2();
protected: protected:
SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); SubtableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
SubtableProcessor2(); SubtableProcessor2();
...@@ -58,7 +58,7 @@ protected: ...@@ -58,7 +58,7 @@ protected:
SubtableCoverage2 coverage; SubtableCoverage2 coverage;
FeatureFlags subtableFeatures; FeatureFlags subtableFeatures;
const MorphSubtableHeader2 *subtableHeader; const LEReferenceTo<MorphSubtableHeader2> subtableHeader;
private: private:
......
...@@ -134,11 +134,10 @@ void ThaiLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 of ...@@ -134,11 +134,10 @@ void ThaiLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 of
return; return;
} }
if (fTypoFlags & 0x1) { /* kerning enabled */ if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(kernTable, success);
KernTable kt(fFontInstance, getFontTable(kernTableTag)); kt.process(glyphStorage, success);
kt.process(glyphStorage);
} }
// default is no adjustments // default is no adjustments
......
...@@ -49,7 +49,7 @@ U_NAMESPACE_BEGIN ...@@ -49,7 +49,7 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TibetanOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TibetanOpenTypeLayoutEngine)
TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(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) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = TibetanReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = TibetanReordering::getFeatureMap(fFeatureMapCount);
......
...@@ -83,7 +83,7 @@ public: ...@@ -83,7 +83,7 @@ public:
* @internal * @internal
*/ */
TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, TibetanOpenTypeLayoutEngine(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 * This constructor is used when the font requires a "canned" GSUB table which can't be known
......
...@@ -46,22 +46,28 @@ TrimmedArrayProcessor::TrimmedArrayProcessor() ...@@ -46,22 +46,28 @@ TrimmedArrayProcessor::TrimmedArrayProcessor()
{ {
} }
TrimmedArrayProcessor::TrimmedArrayProcessor(const MorphSubtableHeader *morphSubtableHeader) TrimmedArrayProcessor::TrimmedArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success), firstGlyph(0), lastGlyph(0)
{ {
const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
trimmedArrayLookupTable = (const TrimmedArrayLookupTable *) &header->table; if(LE_FAILURE(success)) return;
firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount); trimmedArrayLookupTable = LEReferenceTo<TrimmedArrayLookupTable>(morphSubtableHeader, success, (const TrimmedArrayLookupTable*)&header->table);
if(LE_FAILURE(success)) return;
firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount);
} }
TrimmedArrayProcessor::~TrimmedArrayProcessor() TrimmedArrayProcessor::~TrimmedArrayProcessor()
{ {
} }
void TrimmedArrayProcessor::process(LEGlyphStorage &glyphStorage) void TrimmedArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
if(LE_FAILURE(success)) return;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
le_int32 glyph; le_int32 glyph;
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class TrimmedArrayProcessor : public NonContextualGlyphSubstitutionProcessor class TrimmedArrayProcessor : public NonContextualGlyphSubstitutionProcessor
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
TrimmedArrayProcessor(const MorphSubtableHeader *morphSubtableHeader); TrimmedArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~TrimmedArrayProcessor(); virtual ~TrimmedArrayProcessor();
...@@ -76,7 +76,7 @@ private: ...@@ -76,7 +76,7 @@ private:
protected: protected:
TTGlyphID firstGlyph; TTGlyphID firstGlyph;
TTGlyphID lastGlyph; TTGlyphID lastGlyph;
const TrimmedArrayLookupTable *trimmedArrayLookupTable; LEReferenceTo<TrimmedArrayLookupTable> trimmedArrayLookupTable;
}; };
......
...@@ -46,22 +46,24 @@ TrimmedArrayProcessor2::TrimmedArrayProcessor2() ...@@ -46,22 +46,24 @@ TrimmedArrayProcessor2::TrimmedArrayProcessor2()
{ {
} }
TrimmedArrayProcessor2::TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) TrimmedArrayProcessor2::TrimmedArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader) : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
{ {
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader; const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
trimmedArrayLookupTable = (const TrimmedArrayLookupTable *) &header->table; trimmedArrayLookupTable = LEReferenceTo<TrimmedArrayLookupTable>(morphSubtableHeader, success, &header->table);
firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph); firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount); lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount);
valueArray = LEReferenceToArrayOf<LookupValue>(morphSubtableHeader, success, &trimmedArrayLookupTable->valueArray[0], LE_UNBOUNDED_ARRAY);
} }
TrimmedArrayProcessor2::~TrimmedArrayProcessor2() TrimmedArrayProcessor2::~TrimmedArrayProcessor2()
{ {
} }
void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage) void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
if(LE_FAILURE(success)) return;
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
le_int32 glyph; le_int32 glyph;
...@@ -70,7 +72,7 @@ void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage) ...@@ -70,7 +72,7 @@ void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage)
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph); TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph);
if ((ttGlyph > firstGlyph) && (ttGlyph < lastGlyph)) { if ((ttGlyph > firstGlyph) && (ttGlyph < lastGlyph)) {
TTGlyphID newGlyph = SWAPW(trimmedArrayLookupTable->valueArray[ttGlyph - firstGlyph]); TTGlyphID newGlyph = SWAPW(valueArray(ttGlyph - firstGlyph, success));
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
......
...@@ -50,9 +50,9 @@ class LEGlyphStorage; ...@@ -50,9 +50,9 @@ class LEGlyphStorage;
class TrimmedArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2 class TrimmedArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
{ {
public: public:
virtual void process(LEGlyphStorage &glyphStorage); virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader); TrimmedArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~TrimmedArrayProcessor2(); virtual ~TrimmedArrayProcessor2();
...@@ -76,8 +76,8 @@ private: ...@@ -76,8 +76,8 @@ private:
protected: protected:
TTGlyphID firstGlyph; TTGlyphID firstGlyph;
TTGlyphID lastGlyph; TTGlyphID lastGlyph;
const TrimmedArrayLookupTable *trimmedArrayLookupTable; LEReferenceTo<TrimmedArrayLookupTable> trimmedArrayLookupTable;
LEReferenceToArrayOf<LookupValue> valueArray;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -64,6 +64,7 @@ private: ...@@ -64,6 +64,7 @@ private:
static le_int16 getFieldCount(ValueFormat valueFormat); static le_int16 getFieldCount(ValueFormat valueFormat);
static le_int16 getFieldIndex(ValueFormat valueFormat, ValueRecordField field); static le_int16 getFieldIndex(ValueFormat valueFormat, ValueRecordField field);
}; };
LE_VAR_ARRAY(ValueRecord, values)
enum ValueRecordFields enum ValueRecordFields
{ {
......
...@@ -320,22 +320,20 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription ...@@ -320,22 +320,20 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription
JNIEXPORT TTLayoutTableCache* newLayoutTableCache() { JNIEXPORT TTLayoutTableCache* newLayoutTableCache() {
TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache)); TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache));
if (ltc) { if (ltc) {
ltc->gsub_len = -1; int i;
ltc->gpos_len = -1; for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
ltc->gdef_len = -1; ltc->entries[i].len = -1;
ltc->mort_len = -1; }
ltc->kern_len = -1;
} }
return ltc; return ltc;
} }
JNIEXPORT void freeLayoutTableCache(TTLayoutTableCache* ltc) { JNIEXPORT void freeLayoutTableCache(TTLayoutTableCache* ltc) {
if (ltc) { if (ltc) {
if (ltc->gsub) free(ltc->gsub); int i;
if (ltc->gpos) free(ltc->gpos); for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
if (ltc->gdef) free(ltc->gdef); if(ltc->entries[i].ptr) free (ltc->entries[i].ptr);
if (ltc->mort) free(ltc->mort); }
if (ltc->kern) free(ltc->kern);
if (ltc->kernPairs) free(ltc->kernPairs); if (ltc->kernPairs) free(ltc->kernPairs);
free(ltc); free(ltc);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册