提交 aa8269cb 编写于 作者: P prr

8024530: Enhance font process resilience

Reviewed-by: mschoene, bae, srl, prr
上级 4ec93e19
...@@ -55,7 +55,7 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu ...@@ -55,7 +55,7 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu
(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), success)) {
glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0])); glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
} }
......
...@@ -37,55 +37,54 @@ ...@@ -37,55 +37,54 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
void AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, void AnchorTable::getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const LEPoint &anchor, LEErrorCode &success) const
{ {
switch(SWAPW(anchorFormat)) { switch(SWAPW(anchorFormat)) {
case 1: case 1:
{ {
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this; LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
f1->getAnchor(fontInstance, anchor);
break; break;
} }
case 2: case 2:
{ {
const Format2AnchorTable *f2 = (const Format2AnchorTable *) this; LEReferenceTo<Format2AnchorTable> f2(base, success);
f2->getAnchor(f2, glyphID, fontInstance, anchor, success);
f2->getAnchor(glyphID, fontInstance, anchor);
break; break;
} }
case 3: case 3:
{ {
const Format3AnchorTable *f3 = (const Format3AnchorTable *) this; LEReferenceTo<Format3AnchorTable> f3(base, success);
f3->getAnchor(f3, fontInstance, anchor, success);
f3->getAnchor(fontInstance, anchor);
break; break;
} }
default: default:
{
// unknown format: just use x, y coordinate, like format 1... // unknown format: just use x, y coordinate, like format 1...
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this; LEReferenceTo<Format1AnchorTable> f1(base, success);
f1->getAnchor(f1, fontInstance, anchor, success);
f1->getAnchor(fontInstance, anchor);
break; break;
} }
}
} }
void Format1AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const void Format1AnchorTable::getAnchor(const LEReferenceTo<Format1AnchorTable>& base, const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const
{ {
le_int16 x = SWAPW(xCoordinate); le_int16 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate); le_int16 y = SWAPW(yCoordinate);
LEPoint pixels; LEPoint pixels;
fontInstance->transformFunits(x, y, pixels); fontInstance->transformFunits(x, y, pixels);
fontInstance->pixelsToUnits(pixels, anchor); fontInstance->pixelsToUnits(pixels, anchor);
} }
void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const void Format2AnchorTable::getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor
, LEErrorCode &success) const
{ {
LEPoint point; LEPoint point;
...@@ -100,7 +99,8 @@ void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *font ...@@ -100,7 +99,8 @@ void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *font
fontInstance->pixelsToUnits(point, anchor); fontInstance->pixelsToUnits(point, anchor);
} }
void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const void Format3AnchorTable::getAnchor(const LEReferenceTo<Format3AnchorTable> &base, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{ {
le_int16 x = SWAPW(xCoordinate); le_int16 x = SWAPW(xCoordinate);
le_int16 y = SWAPW(yCoordinate); le_int16 y = SWAPW(yCoordinate);
...@@ -111,15 +111,15 @@ void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint & ...@@ -111,15 +111,15 @@ void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &
fontInstance->transformFunits(x, y, pixels); fontInstance->transformFunits(x, y, pixels);
if (dtxOffset != 0) { if (dtxOffset != 0) {
const DeviceTable *dtx = (const DeviceTable *) ((char *) this + dtxOffset); LEReferenceTo<DeviceTable> dt(base, success, dtxOffset);
le_int16 adjx = dtx->getAdjustment((le_int16) fontInstance->getXPixelsPerEm()); le_int16 adjx = dt->getAdjustment(dt, (le_int16) fontInstance->getXPixelsPerEm(), success);
pixels.fX += adjx; pixels.fX += adjx;
} }
if (dtyOffset != 0) { if (dtyOffset != 0) {
const DeviceTable *dty = (const DeviceTable *) ((char *) this + dtyOffset); LEReferenceTo<DeviceTable> dt(base, success, dtyOffset);
le_int16 adjy = dty->getAdjustment((le_int16) fontInstance->getYPixelsPerEm()); le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success);
pixels.fY += adjy; pixels.fY += adjy;
} }
......
...@@ -49,20 +49,23 @@ struct AnchorTable ...@@ -49,20 +49,23 @@ struct AnchorTable
le_int16 xCoordinate; le_int16 xCoordinate;
le_int16 yCoordinate; le_int16 yCoordinate;
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, void getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor) const; LEPoint &anchor, LEErrorCode &success) const;
}; };
struct Format1AnchorTable : AnchorTable struct Format1AnchorTable : AnchorTable
{ {
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const; void getAnchor(const LEReferenceTo<Format1AnchorTable>& base,
const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const;
}; };
struct Format2AnchorTable : AnchorTable struct Format2AnchorTable : AnchorTable
{ {
le_uint16 anchorPoint; le_uint16 anchorPoint;
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const; void getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
LEGlyphID glyphID, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
}; };
struct Format3AnchorTable : AnchorTable struct Format3AnchorTable : AnchorTable
...@@ -70,7 +73,9 @@ struct Format3AnchorTable : AnchorTable ...@@ -70,7 +73,9 @@ struct Format3AnchorTable : AnchorTable
Offset xDeviceTableOffset; Offset xDeviceTableOffset;
Offset yDeviceTableOffset; Offset yDeviceTableOffset;
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const; void getAnchor(const LEReferenceTo<Format3AnchorTable>& base,
const LEFontInstance *fontInstance, LEPoint &anchor,
LEErrorCode &success) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const le_bool CharSubstitutionFilter::accept(LEGlyphID glyph, LEErrorCode &/*success*/) const
{ {
return fFontInstance->canDisplay((LEUnicode) glyph); return fFontInstance->canDisplay((LEUnicode) glyph);
} }
...@@ -147,7 +147,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l ...@@ -147,7 +147,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
GDEFMarkFilter filter(fGDEFTable, success); GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success); adjustMarkGlyphs(glyphStorage, &filter, success);
} else { } else {
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData,
CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen);
GDEFMarkFilter filter(gdefTable, success); GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
...@@ -157,9 +159,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l ...@@ -157,9 +159,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
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.setTo(LETableReference::kStaticData, (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable, CanonShaping::glyphSubstitutionTableLen);
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; fGDEFTable.setTo(LETableReference::kStaticData, (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
/* OpenTypeLayoutEngine will allocate a substitution filter */ /* OpenTypeLayoutEngine will allocate a substitution filter */
} }
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine() UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
......
...@@ -59,7 +59,8 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] = ...@@ -59,7 +59,8 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c) ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
{ {
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable, const LEReferenceTo<ClassDefinitionTable> joiningTypes(LETableReference::kStaticData,
(const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
ArabicShaping::shapingTypeTableLen); ArabicShaping::shapingTypeTableLen);
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success); le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
......
...@@ -60,7 +60,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le ...@@ -60,7 +60,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
LEUnicode *outChars, LEGlyphStorage &glyphStorage) LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{ {
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success); 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);
......
...@@ -43,6 +43,8 @@ class LEFontInstance; ...@@ -43,6 +43,8 @@ class LEFontInstance;
* This filter is used by character-based GSUB processors. It * This filter is used by character-based GSUB processors. It
* accepts only those characters which the given font can display. * accepts only those characters which the given font can display.
* *
* Note: Implementation is in ArabicLayoutEngine.cpp
*
* @internal * @internal
*/ */
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
...@@ -97,7 +99,7 @@ public: ...@@ -97,7 +99,7 @@ public:
* *
* @internal * @internal
*/ */
le_bool accept(LEGlyphID glyph) const; le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -49,6 +49,7 @@ struct ClassDefinitionTable ...@@ -49,6 +49,7 @@ struct ClassDefinitionTable
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const; le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const; le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
#if LE_ENABLE_RAW
le_int32 getGlyphClass(LEGlyphID glyphID) const { le_int32 getGlyphClass(LEGlyphID glyphID) const {
LETableReference base((const le_uint8*)this); LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR; LEErrorCode ignored = LE_NO_ERROR;
...@@ -60,6 +61,7 @@ struct ClassDefinitionTable ...@@ -60,6 +61,7 @@ struct ClassDefinitionTable
LEErrorCode ignored = LE_NO_ERROR; LEErrorCode ignored = LE_NO_ERROR;
return hasGlyphClass(base,glyphClass,ignored); return hasGlyphClass(base,glyphClass,ignored);
} }
#endif
}; };
struct ClassDefFormat1Table : ClassDefinitionTable struct ClassDefFormat1Table : ClassDefinitionTable
......
...@@ -56,20 +56,32 @@ struct SubstitutionLookupRecord ...@@ -56,20 +56,32 @@ struct SubstitutionLookupRecord
struct ContextualSubstitutionBase : GlyphSubstitutionSubtable struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
{ {
static le_bool matchGlyphIDs( static le_bool matchGlyphIDs(
const TTGlyphID *glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator, const LEReferenceToArrayOf<TTGlyphID> &glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
le_bool backtrack = FALSE); le_bool backtrack = FALSE);
static le_bool matchGlyphClasses( static le_bool matchGlyphClasses(
const le_uint16 *classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator, const LEReferenceToArrayOf<le_uint16> &classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
const ClassDefinitionTable *classDefinitionTable, le_bool backtrack = FALSE); const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable, LEErrorCode &success, le_bool backtrack = FALSE);
static le_bool matchGlyphCoverages( static le_bool matchGlyphCoverages(
const Offset *coverageTableOffsetArray, le_uint16 glyphCount, const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack = FALSE); GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE);
/**
* little shim to wrap the Offset array in range checking
* @private
*/
static le_bool matchGlyphCoverages(
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE) {
LEReferenceToArrayOf<Offset> ref(offsetBase, success, coverageTableOffsetArray, glyphCount);
if( LE_FAILURE(success) ) { return FALSE; }
return matchGlyphCoverages(ref, glyphCount, glyphIterator, offsetBase, success, backtrack);
}
static void applySubstitutionLookups( static void applySubstitutionLookups(
const LookupProcessor *lookupProcessor, const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray, const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
le_uint16 substCount, le_uint16 substCount,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
...@@ -79,7 +91,8 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable ...@@ -79,7 +91,8 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase struct ContextualSubstitutionSubtable : ContextualSubstitutionBase
{ {
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
...@@ -87,7 +100,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable ...@@ -87,7 +100,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint16 subRuleSetCount; le_uint16 subRuleSetCount;
Offset subRuleSetTableOffsetArray[ANY_NUMBER]; Offset subRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray) LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
...@@ -116,7 +130,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable ...@@ -116,7 +130,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint16 subClassSetCount; le_uint16 subClassSetCount;
Offset subClassSetTableOffsetArray[ANY_NUMBER]; Offset subClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray) LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
...@@ -152,13 +166,15 @@ struct ContextualSubstitutionFormat3Subtable ...@@ -152,13 +166,15 @@ struct ContextualSubstitutionFormat3Subtable
Offset coverageTableOffsetArray[ANY_NUMBER]; Offset coverageTableOffsetArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray) LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
{ {
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
...@@ -166,7 +182,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit ...@@ -166,7 +182,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint16 chainSubRuleSetCount; le_uint16 chainSubRuleSetCount;
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER]; Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray) LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
...@@ -201,7 +218,8 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit ...@@ -201,7 +218,8 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint16 chainSubClassSetCount; le_uint16 chainSubClassSetCount;
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER]; Offset chainSubClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray) LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
...@@ -243,7 +261,8 @@ struct ChainingContextualSubstitutionFormat3Subtable ...@@ -243,7 +261,8 @@ struct ChainingContextualSubstitutionFormat3Subtable
//le_uint16 substCount; //le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray) LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
......
...@@ -37,8 +37,10 @@ ...@@ -37,8 +37,10 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const le_int32 CoverageTable::getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
if(LE_FAILURE(success)) return -1;
switch(SWAPW(coverageFormat)) switch(SWAPW(coverageFormat))
{ {
case 0: case 0:
...@@ -46,16 +48,16 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -46,16 +48,16 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
case 1: case 1:
{ {
const CoverageFormat1Table *f1Table = (const CoverageFormat1Table *) this; LEReferenceTo<CoverageFormat1Table> f1Table(base, success);
return f1Table->getGlyphCoverage(glyphID); return f1Table->getGlyphCoverage(f1Table, glyphID, success);
} }
case 2: case 2:
{ {
const CoverageFormat2Table *f2Table = (const CoverageFormat2Table *) this; LEReferenceTo<CoverageFormat2Table> f2Table(base, success);
return f2Table->getGlyphCoverage(glyphID); return f2Table->getGlyphCoverage(f2Table, glyphID, success);
} }
default: default:
...@@ -63,8 +65,10 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -63,8 +65,10 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
} }
} }
le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const le_int32 CoverageFormat1Table::getGlyphCoverage(LEReferenceTo<CoverageFormat1Table> &base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
if(LE_FAILURE(success)) return -1;
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
le_uint16 count = SWAPW(glyphCount); le_uint16 count = SWAPW(glyphCount);
le_uint8 bit = OpenTypeUtilities::highBit(count); le_uint8 bit = OpenTypeUtilities::highBit(count);
...@@ -73,37 +77,45 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -73,37 +77,45 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
le_uint16 probe = power; le_uint16 probe = power;
le_uint16 index = 0; le_uint16 index = 0;
if (count == 0) { if (count == 0) {
return -1; return -1;
} }
LEReferenceToArrayOf<TTGlyphID>(base, success, glyphArray, count);
if(LE_FAILURE(success)) return -1; // range checks array
if (SWAPW(glyphArray[extra]) <= ttGlyphID) { if (SWAPW(glyphArray[extra]) <= ttGlyphID) {
index = extra; index = extra;
} }
while (probe > (1 << 0)) { while (probe > (1 << 0)) {
probe >>= 1; probe >>= 1;
if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) { if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) {
index += probe; index += probe;
} }
} }
if (SWAPW(glyphArray[index]) == ttGlyphID) { if (SWAPW(glyphArray[index]) == ttGlyphID) {
return index; return index;
} }
return -1; return -1;
} }
le_int32 CoverageFormat2Table::getGlyphCoverage(LEGlyphID glyphID) const le_int32 CoverageFormat2Table::getGlyphCoverage(LEReferenceTo<CoverageFormat2Table> &base, LEGlyphID glyphID, LEErrorCode &success) const
{ {
if(LE_FAILURE(success)) return -1;
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
le_uint16 count = SWAPW(rangeCount); le_uint16 count = SWAPW(rangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> rangeRecordArrayRef(base, success, rangeRecordArray, count);
le_int32 rangeIndex = le_int32 rangeIndex =
OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArray, count); OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArrayRef, success);
if (rangeIndex < 0) { if (rangeIndex < 0 || LE_FAILURE(success)) { // could fail if array out of bounds
return -1; return -1;
} }
......
...@@ -46,7 +46,7 @@ struct CoverageTable ...@@ -46,7 +46,7 @@ struct CoverageTable
{ {
le_uint16 coverageFormat; le_uint16 coverageFormat;
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
}; };
struct CoverageFormat1Table : CoverageTable struct CoverageFormat1Table : CoverageTable
...@@ -54,7 +54,7 @@ struct CoverageFormat1Table : CoverageTable ...@@ -54,7 +54,7 @@ struct CoverageFormat1Table : CoverageTable
le_uint16 glyphCount; le_uint16 glyphCount;
TTGlyphID glyphArray[ANY_NUMBER]; TTGlyphID glyphArray[ANY_NUMBER];
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(LEReferenceTo<CoverageFormat1Table> &base, LEGlyphID glyphID, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(CoverageFormat1Table, glyphArray) LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
...@@ -64,7 +64,7 @@ struct CoverageFormat2Table : CoverageTable ...@@ -64,7 +64,7 @@ struct CoverageFormat2Table : CoverageTable
le_uint16 rangeCount; le_uint16 rangeCount;
GlyphRangeRecord rangeRecordArray[ANY_NUMBER]; GlyphRangeRecord rangeRecordArray[ANY_NUMBER];
le_int32 getGlyphCoverage(LEGlyphID glyphID) const; le_int32 getGlyphCoverage(LEReferenceTo<CoverageFormat2Table> &base, LEGlyphID glyphID, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray) LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
......
...@@ -51,23 +51,27 @@ le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachme ...@@ -51,23 +51,27 @@ le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachme
} }
LEPoint entryAnchor, exitAnchor; LEPoint entryAnchor, exitAnchor;
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor); Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
if (entryOffset != 0) { if (entryOffset != 0) {
const AnchorTable *entryAnchorTable = (const AnchorTable *) ((char *) this + entryOffset); LEReferenceTo<AnchorTable> entryAnchorTable(base, success, entryOffset);
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor); if( LE_SUCCESS(success) ) {
glyphIterator->setCursiveEntryPoint(entryAnchor); entryAnchorTable->getAnchor(entryAnchorTable, glyphID, fontInstance, entryAnchor, success);
glyphIterator->setCursiveEntryPoint(entryAnchor);
}
} else { } else {
//glyphIterator->clearCursiveEntryPoint(); //glyphIterator->clearCursiveEntryPoint();
} }
if (exitOffset != 0) { if (exitOffset != 0) {
const AnchorTable *exitAnchorTable = (const AnchorTable *) ((char *) this + exitOffset); LEReferenceTo<AnchorTable> exitAnchorTable(base, success, exitOffset);
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor); if( LE_SUCCESS(success) ) {
glyphIterator->setCursiveExitPoint(exitAnchor); exitAnchorTable->getAnchor(exitAnchorTable, glyphID, fontInstance, exitAnchor, success);
glyphIterator->setCursiveExitPoint(exitAnchor);
}
} else { } else {
//glyphIterator->clearCursiveExitPoint(); //glyphIterator->clearCursiveExitPoint();
} }
......
...@@ -43,7 +43,7 @@ const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8}; ...@@ -43,7 +43,7 @@ const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8};
#define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits) #define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits)
le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const le_int16 DeviceTable::getAdjustment(const LEReferenceTo<DeviceTable>&base, le_uint16 ppem, LEErrorCode &success) const
{ {
le_uint16 start = SWAPW(startSize); le_uint16 start = SWAPW(startSize);
le_uint16 format = SWAPW(deltaFormat) - 1; le_uint16 format = SWAPW(deltaFormat) - 1;
...@@ -53,6 +53,13 @@ le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const ...@@ -53,6 +53,13 @@ le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
le_uint16 sizeIndex = ppem - start; le_uint16 sizeIndex = ppem - start;
le_uint16 bits = fieldBits[format]; le_uint16 bits = fieldBits[format];
le_uint16 count = 16 / bits; le_uint16 count = 16 / bits;
LEReferenceToArrayOf<le_uint16> deltaValuesRef(base, success, deltaValues, (sizeIndex / count));
if(LE_FAILURE(success)) {
return result;
}
le_uint16 word = SWAPW(deltaValues[sizeIndex / count]); le_uint16 word = SWAPW(deltaValues[sizeIndex / count]);
le_uint16 fieldIndex = sizeIndex % count; le_uint16 fieldIndex = sizeIndex % count;
le_uint16 shift = 16 - (bits * (fieldIndex + 1)); le_uint16 shift = 16 - (bits * (fieldIndex + 1));
......
...@@ -50,7 +50,7 @@ struct DeviceTable ...@@ -50,7 +50,7 @@ struct DeviceTable
le_uint16 deltaFormat; le_uint16 deltaFormat;
le_uint16 deltaValues[ANY_NUMBER]; le_uint16 deltaValues[ANY_NUMBER];
le_int16 getAdjustment(le_uint16 ppem) const; le_int16 getAdjustment(const LEReferenceTo<DeviceTable> &base, le_uint16 ppem, LEErrorCode &success) const;
private: private:
static const le_uint16 fieldMasks[]; static const le_uint16 fieldMasks[];
......
...@@ -48,7 +48,6 @@ le_uint32 ExtensionSubtable::process(const LEReferenceTo<ExtensionSubtable> &thi ...@@ -48,7 +48,6 @@ le_uint32 ExtensionSubtable::process(const LEReferenceTo<ExtensionSubtable> &thi
const LookupProcessor *lookupProcessor, le_uint16 lookupType, const LookupProcessor *lookupProcessor, 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)) {
return 0; return 0;
} }
......
...@@ -52,8 +52,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable ...@@ -52,8 +52,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable
le_uint16 extensionLookupType; le_uint16 extensionLookupType;
le_uint32 extensionOffset; le_uint32 extensionOffset;
le_uint32 process(const LEReferenceTo<ExtensionSubtable> &extRef, le_uint32 process(const LEReferenceTo<ExtensionSubtable> &base, const LookupProcessor *lookupProcessor, le_uint16 lookupType,
const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
......
...@@ -49,11 +49,11 @@ GDEFMarkFilter::~GDEFMarkFilter() ...@@ -49,11 +49,11 @@ GDEFMarkFilter::~GDEFMarkFilter()
// nothing to do? // nothing to do?
} }
le_bool GDEFMarkFilter::accept(LEGlyphID glyph) const le_bool GDEFMarkFilter::accept(LEGlyphID glyph, LEErrorCode &success) const
{ {
le_int32 glyphClass = classDefTable->getGlyphClass(glyph); le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
return glyphClass == gcdMarkGlyph; return glyphClass == gcdMarkGlyph;
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -55,7 +55,7 @@ public: ...@@ -55,7 +55,7 @@ public:
GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success); GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~GDEFMarkFilter(); virtual ~GDEFMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const; virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -41,14 +41,13 @@ ...@@ -41,14 +41,13 @@
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 LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader) FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader, LEErrorCode &success)
: 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(), markAttachClassDefinitionTable() glyphClassDefinitionTable(), markAttachClassDefinitionTable()
{ {
LEErrorCode success = LE_NO_ERROR; // TODO
le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyphCount = glyphStorage.getGlyphCount();
if (theGlyphDefinitionTableHeader.isValid()) { if (theGlyphDefinitionTableHeader.isValid()) {
...@@ -388,7 +387,7 @@ void GlyphIterator::setCursiveGlyph() ...@@ -388,7 +387,7 @@ void GlyphIterator::setCursiveGlyph()
void GlyphIterator::filterResetCache(void) { void GlyphIterator::filterResetCache(void) {
filterCacheValid = FALSE; filterCacheValid = FALSE;
} }
le_bool GlyphIterator::filterGlyph(le_uint32 index) le_bool GlyphIterator::filterGlyph(le_uint32 index)
{ {
...@@ -399,53 +398,53 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) ...@@ -399,53 +398,53 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index)
le_bool &filterResult = filterCache.result; // NB: Making this a reference to accept the updated value, in case le_bool &filterResult = filterCache.result; // NB: Making this a reference to accept the updated value, in case
// we want more fancy cacheing in the future. // we want more fancy cacheing in the future.
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) { if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
filterResult = TRUE; filterResult = TRUE;
} else { } else {
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
le_int32 glyphClass = gcdNoGlyphClass; le_int32 glyphClass = gcdNoGlyphClass;
if (glyphClassDefinitionTable.isValid()) { if (glyphClassDefinitionTable.isValid()) {
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success); glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
} }
switch (glyphClass) { switch (glyphClass) {
case gcdNoGlyphClass: case gcdNoGlyphClass:
filterResult = FALSE; filterResult = FALSE;
break; break;
case gcdSimpleGlyph: case gcdSimpleGlyph:
filterResult = (lookupFlags & lfIgnoreBaseGlyphs) != 0; filterResult = (lookupFlags & lfIgnoreBaseGlyphs) != 0;
break; break;
case gcdLigatureGlyph: case gcdLigatureGlyph:
filterResult = (lookupFlags & lfIgnoreLigatures) != 0; filterResult = (lookupFlags & lfIgnoreLigatures) != 0;
break; break;
case gcdMarkGlyph: case gcdMarkGlyph:
if ((lookupFlags & lfIgnoreMarks) != 0) { if ((lookupFlags & lfIgnoreMarks) != 0) {
filterResult = TRUE; filterResult = TRUE;
} else { } else {
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift; le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) { if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
filterResult = (markAttachClassDefinitionTable filterResult = (markAttachClassDefinitionTable
-> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType); -> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType);
} else { } else {
filterResult = FALSE; filterResult = FALSE;
} }
} }
break; break;
case gcdComponentGlyph: case gcdComponentGlyph:
filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0); filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0);
break; break;
default: default:
filterResult = FALSE; filterResult = FALSE;
break; break;
} }
} }
filterCacheValid = TRUE; filterCacheValid = TRUE;
} }
return filterCache.result; return filterCache.result;
} }
......
...@@ -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 LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader); FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader, LEErrorCode &success);
GlyphIterator(GlyphIterator &that); GlyphIterator(GlyphIterator &that);
......
...@@ -95,6 +95,8 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo ...@@ -95,6 +95,8 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
le_uint32 delta = 0; le_uint32 delta = 0;
//_LETRACE("attempting lookupType #%d", lookupType);
switch(lookupType) switch(lookupType)
{ {
case 0: case 0:
...@@ -152,21 +154,21 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo ...@@ -152,21 +154,21 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
{ {
LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success); LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this , glyphIterator, fontInstance, success);
break; break;
} }
case gpstChainedContext: case gpstChainedContext:
{ {
LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break; break;
} }
case gpstExtension: case gpstExtension:
{ {
LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(subtable, this, lookupType, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, lookupType, glyphIterator, fontInstance, success);
break; break;
...@@ -176,6 +178,12 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo ...@@ -176,6 +178,12 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
break; break;
} }
#if LE_TRACE
if(delta != 0) {
_LETRACE("GlyphPositioningLookupProcessor applied #%d -> delta %d @ %d", lookupType, delta, glyphIterator->getCurrStreamPosition());
}
#endif
return delta; return delta;
} }
......
...@@ -123,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo ...@@ -123,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
{ {
const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break; break;
} }
...@@ -131,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo ...@@ -131,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
{ {
const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success); const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
delta = subtable->process(this, glyphIterator, fontInstance, success); delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
break; break;
} }
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include "LEGlyphStorage.h" #include "LEGlyphStorage.h"
#include "IndicReordering.h" #include "IndicReordering.h"
#include <stdio.h>
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
...@@ -53,14 +53,14 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI ...@@ -53,14 +53,14 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI
le_int32 typoFlags, le_bool version2, const LEReferenceTo<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 ) {
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount); fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
} else { } else {
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
} }
fFeatureOrder = TRUE; fFeatureOrder = TRUE;
fVersion2 = version2; fVersion2 = version2;
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode); fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
} }
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
...@@ -68,7 +68,7 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI ...@@ -68,7 +68,7 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI
{ {
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE; fFeatureOrder = TRUE;
fVersion2 = FALSE; fVersion2 = FALSE;
} }
IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine() IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
...@@ -90,6 +90,7 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_ ...@@ -90,6 +90,7 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
return 0; return 0;
} }
_LETRACE("IOTLE::gp, calling parent");
le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success); le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
...@@ -97,11 +98,15 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_ ...@@ -97,11 +98,15 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
} }
if (fVersion2) { if (fVersion2) {
IndicReordering::finalReordering(glyphStorage,retCount); _LETRACE("IOTLE::gp, v2 final,");
IndicReordering::applyPresentationForms(glyphStorage,retCount); IndicReordering::finalReordering(glyphStorage,retCount);
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success); _LETRACE("IOTLE::gp, v2 pres");
IndicReordering::applyPresentationForms(glyphStorage,retCount);
_LETRACE("IOTLE::gp, parent gsub");
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
} else { } else {
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success); _LETRACE("IOTLE::gp, adjust mpres");
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
} }
return retCount; return retCount;
} }
...@@ -116,6 +121,8 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], ...@@ -116,6 +121,8 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
return 0; return 0;
} }
_LETRACE("IOTLE: charProc");
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
success = LE_ILLEGAL_ARGUMENT_ERROR; success = LE_ILLEGAL_ARGUMENT_ERROR;
return 0; return 0;
...@@ -143,8 +150,10 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], ...@@ -143,8 +150,10 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
le_int32 outCharCount; le_int32 outCharCount;
if (fVersion2) { if (fVersion2) {
_LETRACE("v2process");
outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage); outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
} else { } else {
_LETRACE("reorder");
outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success); outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
} }
......
...@@ -254,8 +254,8 @@ public: ...@@ -254,8 +254,8 @@ public:
return fGlyphStorage.getAuxData(charIndex,success); return fGlyphStorage.getAuxData(charIndex,success);
} }
void decomposeReorderMatras ( const IndicClassTable *classTable, le_int32 beginSyllable, le_int32 nextSyllable, le_int32 inv_count ) { void decomposeReorderMatras ( const IndicClassTable *classTable, le_int32 beginSyllable, le_int32 nextSyllable, le_int32 inv_count ) {
le_int32 i; le_int32 i;
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
for ( i = beginSyllable ; i < nextSyllable ; i++ ) { for ( i = beginSyllable ; i < nextSyllable ; i++ ) {
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include <stdio.h> #include <stdio.h>
#define DEBUG 0 #define DEBUG_KERN_TABLE 0
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
...@@ -99,14 +99,14 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success) ...@@ -99,14 +99,14 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
: pairsSwapped(NULL), fTable(base) : pairsSwapped(NULL), fTable(base)
{ {
if(LE_FAILURE(success) || (fTable.isEmpty())) { if(LE_FAILURE(success) || (fTable.isEmpty())) {
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stderr, "no kern data\n"); fprintf(stderr, "no kern data\n");
#endif #endif
return; return;
} }
LEReferenceTo<KernTableHeader> header(fTable, success); LEReferenceTo<KernTableHeader> header(fTable, success);
#if DEBUG #if DEBUG_KERN_TABLE
// 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*)header.getAlias())[i]&0xff); fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
...@@ -171,13 +171,13 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success) ...@@ -171,13 +171,13 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift); 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)); fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
#endif #endif
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairsSwapped); fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairsSwapped);
fprintf(stderr, fprintf(stderr,
" searchRange(pairs): %d entrySelector: %d rangeShift(pairs): %d\n", " searchRange(pairs): %d entrySelector: %d rangeShift(pairs): %d\n",
searchRange, entrySelector, rangeShift); searchRange, entrySelector, rangeShift);
{ if (LE_SUCCESS(success)) {
// dump part of the pair list // dump part of the pair list
char ids[256]; char ids[256];
for (int i = 256; --i >= 0;) { for (int i = 256; --i >= 0;) {
...@@ -242,7 +242,7 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success) ...@@ -242,7 +242,7 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
p = tp; p = tp;
} }
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stderr, "binary search for %0.8x\n", key); fprintf(stderr, "binary search for %0.8x\n", key);
#endif #endif
...@@ -251,13 +251,13 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success) ...@@ -251,13 +251,13 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
probe >>= 1; probe >>= 1;
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_KERN_TABLE
fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey); fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
#endif #endif
if (tkey <= key) { if (tkey <= key) {
if (tkey == key) { if (tkey == key) {
le_int16 value = SWAPW(tp->value); le_int16 value = SWAPW(tp->value);
#if DEBUG #if DEBUG_KERN_TABLE
fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n", fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n",
storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value)); storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
fflush(stdout); fflush(stdout);
......
...@@ -181,6 +181,10 @@ public: ...@@ -181,6 +181,10 @@ public:
* *
* Subclasses which represent composite fonts should always return <code>NULL</code>. * Subclasses which represent composite fonts should always return <code>NULL</code>.
* *
* Note that implementing this function does not allow for range checking.
* Subclasses that desire the safety of range checking must implement the
* variation which has a length parameter.
*
* @param tableTag - the four byte table tag. (e.g. 'cmap') * @param tableTag - the four byte table tag. (e.g. 'cmap')
* *
* @return the address of the table in memory, or <code>NULL</code> * @return the address of the table in memory, or <code>NULL</code>
...@@ -200,6 +204,8 @@ public: ...@@ -200,6 +204,8 @@ public:
* Subclasses which represent composite fonts should always return <code>NULL</code>. * Subclasses which represent composite fonts should always return <code>NULL</code>.
* *
* This version sets a length, for range checking. * This version sets a length, for range checking.
* Note that range checking can only be accomplished if this function is
* implemented in subclasses.
* *
* @param tableTag - the four byte table tag. (e.g. 'cmap') * @param tableTag - the four byte table tag. (e.g. 'cmap')
* @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown. * @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown.
...@@ -572,5 +578,3 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat) ...@@ -572,5 +578,3 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat)
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -62,7 +62,7 @@ public: ...@@ -62,7 +62,7 @@ public:
* *
* @internal * @internal
*/ */
virtual le_bool accept(LEGlyphID glyph) const = 0; virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const = 0;
}; };
#endif /* U_HIDE_INTERNAL_API */ #endif /* U_HIDE_INTERNAL_API */
......
...@@ -458,7 +458,7 @@ void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorC ...@@ -458,7 +458,7 @@ void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorC
success = LE_INDEX_OUT_OF_BOUNDS_ERROR; success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
return; return;
} }
_LETRACE("set%-4d\t(%.2f, %.2f)", glyphIndex, x, y);
fPositions[glyphIndex * 2] = x; fPositions[glyphIndex * 2] = x;
fPositions[glyphIndex * 2 + 1] = y; fPositions[glyphIndex * 2 + 1] = y;
} }
...@@ -688,10 +688,9 @@ le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGl ...@@ -688,10 +688,9 @@ le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGl
// the source glyph we're pointing at // the source glyph we're pointing at
// just got replaced by the insertion // just got replaced by the insertion
fSrcIndex -= 1; fSrcIndex -= 1;
return FALSE; return FALSE;
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -568,4 +568,3 @@ inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const ...@@ -568,4 +568,3 @@ inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* YOU REALLY KNOW WHAT YOU'RE DOING. * YOU REALLY KNOW WHAT YOU'RE DOING.
* *
* Generated on: 10/26/2010 02:53:33 PM PDT * Generated on: 11/01/2011 04:08:09 PM PDT
*/ */
#ifndef __LESCRIPTS_H #ifndef __LESCRIPTS_H
...@@ -262,7 +262,16 @@ enum ScriptCodes { ...@@ -262,7 +262,16 @@ enum ScriptCodes {
khojScriptCode = 157, khojScriptCode = 157,
tirhScriptCode = 158, tirhScriptCode = 158,
scriptCodeCount = 159 /**
* @stable ICU 52
*/
aghbScriptCode = 159,
mahjScriptCode = 160,
/**
* @stable ICU 2.2
*/
scriptCodeCount
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -132,6 +132,9 @@ enum LEErrorCode { ...@@ -132,6 +132,9 @@ enum LEErrorCode {
#define uprv_memcpy memcpy #define uprv_memcpy memcpy
#define uprv_realloc realloc #define uprv_realloc realloc
#define U_EXPORT2
#define U_CAPI extern "C"
#if !defined(U_IS_BIG_ENDIAN) #if !defined(U_IS_BIG_ENDIAN)
#ifdef _LITTLE_ENDIAN #ifdef _LITTLE_ENDIAN
#define U_IS_BIG_ENDIAN 0 #define U_IS_BIG_ENDIAN 0
......
...@@ -37,34 +37,47 @@ ...@@ -37,34 +37,47 @@
#include "LETypes.h" #include "LETypes.h"
#include "LEFontInstance.h" #include "LEFontInstance.h"
/**
* \def LE_ENABLE_RAW
* If this is 1, enables old non-safe raw access
*/
#ifndef LE_ENABLE_RAW
#define LE_ENABLE_RAW 0
#endif
#define kQuestionmarkTableTag 0x3F3F3F3FUL #define kQuestionmarkTableTag 0x3F3F3F3FUL /* ???? */
#define kTildeTableTag 0x7e7e7e7eUL #define kStaticTableTag 0x30303030UL /* 0000 */
#define kTildeTableTag 0x7e7e7e7eUL /* ~~~~ */
#ifdef __cplusplus #ifdef __cplusplus
// internal - interface for range checking // internal - interface for range checking
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
#if LE_ASSERT_BAD_FONT #if LE_ASSERT_BAD_FONT
#ifndef LE_TRACE_TR
#define LE_TRACE_TR 0
#endif
class LETableReference; // fwd class LETableReference; // fwd
/** /**
* defined in OpenTypeUtilities.cpp * defined in OpenTypeUtilities.cpp
* @internal * @internal
*/ */
extern void _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len); U_CAPI void U_EXPORT2 _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_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); #define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
#if 0 #if LE_TRACE_TR
#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0); #define _TRTRACE(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
#else #else
#define LE_TRACE_TR(x) #define _TRTRACE(x)
#endif #endif
#else #else
#define LE_DEBUG_TR(x) #define LE_DEBUG_TR(x)
#define LE_DEBUG_TR3(x,y,z) #define LE_DEBUG_TR3(x,y,z)
#define LE_TRACE_TR(x) #define _TRTRACE(x)
#endif #endif
/** /**
...@@ -72,6 +85,13 @@ extern void _debug_LETableReference(const char *f, int l, const char *msg, const ...@@ -72,6 +85,13 @@ extern void _debug_LETableReference(const char *f, int l, const char *msg, const
*/ */
class LETableReference { class LETableReference {
public: public:
/**
* Dummy enum asserting that a value is actually static data
* and does not need to be range checked
*/
enum EStaticData { kStaticData = 0 };
/** /**
* @internal * @internal
* Construct from a specific tag * Construct from a specific tag
...@@ -79,28 +99,42 @@ public: ...@@ -79,28 +99,42 @@ public:
LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) : LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) { fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
loadTable(success); loadTable(success);
LE_TRACE_TR("INFO: new table load") _TRTRACE("INFO: new table load")
} }
LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) { LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) {
if(LE_FAILURE(success)) { if(LE_FAILURE(success)) {
clear(); clear();
} }
LE_TRACE_TR("INFO: new clone") _TRTRACE("INFO: new clone")
} }
#if LE_ENABLE_RAW
/**
* Construct without a parent LETR.
*/
LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) : LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) { fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
LE_TRACE_TR("INFO: new raw") _TRTRACE("INFO: new raw")
}
#endif
/**
* Construct without a parent LETR.
*/
LETableReference(EStaticData /* NOTUSED */, const le_uint8* data, size_t length) :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
_TRTRACE("INFO: new EStaticData")
} }
LETableReference() : LETableReference() :
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) { fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
LE_TRACE_TR("INFO: new empty") _TRTRACE("INFO: new empty")
} }
~LETableReference() { ~LETableReference() {
fTag=kTildeTableTag; fTag= (LETag)kTildeTableTag;
LE_TRACE_TR("INFO: new dtor") _TRTRACE("INFO: new dtor")
} }
/** /**
...@@ -126,7 +160,7 @@ public: ...@@ -126,7 +160,7 @@ public:
fLength = (fParent->fLength) - offset; // decrement length as base address is incremented fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
} }
if(fLength != LE_UINTPTR_MAX) { // if we have bounds: if(fLength != LE_UINTPTR_MAX) { // if we have bounds:
if(offset+fLength > fParent->fLength) { if((offset+fLength < offset) || (offset+fLength > fParent->fLength)) {
LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength); LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength);
err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
clear(); clear();
...@@ -136,11 +170,13 @@ public: ...@@ -136,11 +170,13 @@ public:
} else { } else {
clear(); clear();
} }
LE_TRACE_TR("INFO: new subset") _TRTRACE("INFO: new subset")
} }
const void* getAlias() const { return (const void*)fStart; } const void* getAlias() const { return (const void*)fStart; }
const void* getAliasTODO() const { LE_DEBUG_TR("getAliasTODO()"); return (const void*)fStart; } #ifndef LE_ENABLE_RAW
const void* getAliasRAW() const { LE_DEBUG_TR("getAliasRAW()"); return (const void*)fStart; }
#endif
le_bool isEmpty() const { return fStart==NULL || fLength==0; } le_bool isEmpty() const { return fStart==NULL || fLength==0; }
le_bool isValid() const { return !isEmpty(); } le_bool isValid() const { return !isEmpty(); }
le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; } le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
...@@ -233,7 +269,18 @@ protected: ...@@ -233,7 +269,18 @@ protected:
void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) { void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
fFont = NULL; fFont = NULL;
fTag = kQuestionmarkTableTag; fTag = (LETag)kQuestionmarkTableTag;
fParent = NULL;
fStart = (const le_uint8*)data;
fLength = length;
}
/**
* set this object pointing to static data
*/
void setTo(EStaticData /*notused*/, const void *data, size_t length) {
fFont = NULL;
fTag = (LETag)kStaticTableTag;
fParent = NULL; fParent = NULL;
fStart = (const le_uint8*)data; fStart = (const le_uint8*)data;
fLength = length; fLength = length;
...@@ -276,6 +323,90 @@ size_t LETableVarSizer<T>::getSize() { ...@@ -276,6 +323,90 @@ size_t LETableVarSizer<T>::getSize() {
* Open a new entry based on an existing table * Open a new entry based on an existing table
*/ */
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.
*/
inline 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
*/
inline 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();
}
inline 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();
}
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
: LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
: LETableReference(font, tableTag, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
#if LE_ENABLE_RAW
inline LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
inline LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
#endif
inline LEReferenceTo(EStaticData staticData, const le_uint8 *data, size_t length) : LETableReference(staticData, data, length) {}
inline LEReferenceTo(EStaticData staticData, const T *data, size_t length) : LETableReference(staticData, (const le_uint8*)data, length) {}
inline LEReferenceTo() : LETableReference() {}
#if LE_ENABLE_RAW
inline LEReferenceTo<T>& operator=(const T* other) {
setRaw(other);
return *this;
}
#endif
LEReferenceTo<T>& setTo(LETableReference::EStaticData staticData, const T* other, size_t length) {
LETableReference::setTo(staticData, other, length);
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 *operator*() const { return getAlias(); }
const T *getAlias() const { return (const T*)fStart; }
#if LE_ENABLE_RAW
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
#endif
};
/** /**
* \def LE_UNBOUNDED_ARRAY * \def LE_UNBOUNDED_ARRAY
* define an array with no *known* bound. Will trim to available size. * define an array with no *known* bound. Will trim to available size.
...@@ -288,12 +419,12 @@ class LEReferenceToArrayOf : public LETableReference { ...@@ -288,12 +419,12 @@ class LEReferenceToArrayOf : public LETableReference {
public: public:
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count) LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
: LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) { : LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO by offset") _TRTRACE("INFO: new RTAO by offset")
if(LE_SUCCESS(success)) { if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
} }
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
} }
if(LE_FAILURE(success)) { if(LE_FAILURE(success)) {
fCount=0; fCount=0;
...@@ -303,23 +434,23 @@ public: ...@@ -303,23 +434,23 @@ public:
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count) LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
: LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) { : LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO") _TRTRACE("INFO: new RTAO")
if(LE_SUCCESS(success)) { if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
} }
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
} }
if(LE_FAILURE(success)) clear(); if(LE_FAILURE(success)) clear();
} }
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count) 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) { : LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
LE_TRACE_TR("INFO: new RTAO") _TRTRACE("INFO: new RTAO")
if(LE_SUCCESS(success)) { if(LE_SUCCESS(success)) {
if(count == LE_UNBOUNDED_ARRAY) { // not a known length if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
} }
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
} }
if(LE_FAILURE(success)) clear(); if(LE_FAILURE(success)) clear();
} }
...@@ -328,18 +459,40 @@ LE_TRACE_TR("INFO: new RTAO") ...@@ -328,18 +459,40 @@ LE_TRACE_TR("INFO: new RTAO")
le_uint32 getCount() const { return fCount; } le_uint32 getCount() const { return fCount; }
using LETableReference::getAlias; const T *getAlias() const { return (const T*)fStart; }
const T *getAlias(le_uint32 i, LEErrorCode &success) const { const T *getAlias(le_uint32 i, LEErrorCode &success) const {
return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success))); return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success)));
} }
const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; } #ifndef LE_ENABLE_RAW
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
#endif
const T& getObject(le_uint32 i, LEErrorCode &success) const { const T& getObject(le_uint32 i, LEErrorCode &success) const {
return *getAlias(i,success); return *getAlias(i,success);
} }
/**
* by-value array accessor for integral types.
*/
const T operator[](le_uint32 i) const {
LEErrorCode success = LE_NO_ERROR;
const T *ret = getAlias(i, success);
if(LE_FAILURE(success) || ret==NULL) {
#if LE_ASSERT_BAD_FONT
LE_DEBUG_TR3("Range error, out of bounds? (%p) #%d", NULL, i);
#endif
return T(0); // will not work for all types.
}
return *ret;
}
const LEReferenceTo<T> getReference(le_uint32 i, LEErrorCode &success) const {
if(LE_FAILURE(success)) return LEReferenceTo<T>();
return LEReferenceTo<T>(*this, success, getAlias(i,success));
}
const T& operator()(le_uint32 i, LEErrorCode &success) const { const T& operator()(le_uint32 i, LEErrorCode &success) const {
return *getAlias(i,success); return *getAlias(i,success);
} }
...@@ -348,6 +501,7 @@ LE_TRACE_TR("INFO: new RTAO") ...@@ -348,6 +501,7 @@ LE_TRACE_TR("INFO: new RTAO")
if(LE_SUCCESS(success)&&i<getCount()) { if(LE_SUCCESS(success)&&i<getCount()) {
return LETableVarSizer<T>::getSize()*i; return LETableVarSizer<T>::getSize()*i;
} else { } else {
LE_DEBUG_TR3("getOffsetFor failed (%p) index=%d",NULL, i);
success = LE_INDEX_OUT_OF_BOUNDS_ERROR; success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
} }
return 0; return 0;
...@@ -359,7 +513,7 @@ LE_TRACE_TR("INFO: new RTAO") ...@@ -359,7 +513,7 @@ LE_TRACE_TR("INFO: new RTAO")
} }
LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) { LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
LE_TRACE_TR("INFO: null RTAO") _TRTRACE("INFO: null RTAO")
} }
private: private:
...@@ -367,73 +521,11 @@ private: ...@@ -367,73 +521,11 @@ private:
}; };
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.
*/
inline 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
*/
inline 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();
}
inline 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();
}
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
: LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
: LETableReference(font, tableTag, success) {
verifyLength(0, LETableVarSizer<T>::getSize(), success);
if(LE_FAILURE(success)) clear();
}
inline LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
inline LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
inline LEReferenceTo() : LETableReference(NULL) {}
inline 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; }
};
#ifdef _TRTRACE
#undef _TRTRACE
#endif
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -337,6 +337,20 @@ struct LEPoint ...@@ -337,6 +337,20 @@ struct LEPoint
typedef struct LEPoint LEPoint; typedef struct LEPoint LEPoint;
#endif #endif
/**
* \def LE_TRACE
* @internal
*/
#ifndef LE_TRACE
# define LE_TRACE 0
#endif
#if LE_TRACE
# include <stdio.h>
# define _LETRACE printf("\n%s:%d: LE: ", __FILE__, __LINE__),printf
#else
# define _LETRACE 0&&
#endif
#ifndef U_HIDE_INTERNAL_API #ifndef U_HIDE_INTERNAL_API
...@@ -553,7 +567,7 @@ enum LEFeatureTags { ...@@ -553,7 +567,7 @@ enum LEFeatureTags {
LE_CALT_FEATURE_TAG = 0x63616C74UL, /**< 'calt' */ LE_CALT_FEATURE_TAG = 0x63616C74UL, /**< 'calt' */
LE_CASE_FEATURE_TAG = 0x63617365UL, /**< 'case' */ LE_CASE_FEATURE_TAG = 0x63617365UL, /**< 'case' */
LE_CCMP_FEATURE_TAG = 0x63636D70UL, /**< 'ccmp' */ LE_CCMP_FEATURE_TAG = 0x63636D70UL, /**< 'ccmp' */
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */ LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
LE_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */ LE_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */
LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */ LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */
LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */ LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */
...@@ -701,6 +715,12 @@ enum LEFeatureENUMs { ...@@ -701,6 +715,12 @@ enum LEFeatureENUMs {
LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM
}; };
/**
* Flags for typographic features.
* @internal
* @{
*/
#define LE_Kerning_FEATURE_FLAG (1 << LE_Kerning_FEATURE_ENUM) #define LE_Kerning_FEATURE_FLAG (1 << LE_Kerning_FEATURE_ENUM)
#define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM) #define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM)
#define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM) #define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM)
...@@ -727,6 +747,9 @@ enum LEFeatureENUMs { ...@@ -727,6 +747,9 @@ enum LEFeatureENUMs {
#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM) #define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM)
#define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM) #define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM)
/**
* @}
*/
#define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */ #define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */
...@@ -768,7 +791,7 @@ typedef enum LEErrorCode LEErrorCode; ...@@ -768,7 +791,7 @@ typedef enum LEErrorCode LEErrorCode;
* *
* @stable ICU 2.4 * @stable ICU 2.4
*/ */
#ifndef LE_FAILURE #ifndef LE_SUCCESS
#define LE_SUCCESS(code) (U_SUCCESS((UErrorCode)code)) #define LE_SUCCESS(code) (U_SUCCESS((UErrorCode)code))
#endif #endif
...@@ -781,4 +804,4 @@ typedef enum LEErrorCode LEErrorCode; ...@@ -781,4 +804,4 @@ typedef enum LEErrorCode LEErrorCode;
#define LE_FAILURE(code) (U_FAILURE((UErrorCode)code)) #define LE_FAILURE(code) (U_FAILURE((UErrorCode)code))
#endif #endif
#endif /* __LETYPES_H */ #endif
...@@ -156,7 +156,7 @@ public: ...@@ -156,7 +156,7 @@ public:
CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success); CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
virtual ~CanonMarkFilter(); virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const; virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
}; };
CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success) CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
...@@ -169,9 +169,8 @@ CanonMarkFilter::~CanonMarkFilter() ...@@ -169,9 +169,8 @@ CanonMarkFilter::~CanonMarkFilter()
// nothing to do? // nothing to do?
} }
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const le_bool CanonMarkFilter::accept(LEGlyphID glyph, LEErrorCode &success) const
{ {
LEErrorCode success = LE_NO_ERROR;
le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success); le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
if(LE_FAILURE(success)) return false; if(LE_FAILURE(success)) return false;
return glyphClass != 0; return glyphClass != 0;
...@@ -207,7 +206,7 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, ...@@ -207,7 +206,7 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
fGlyphStorage = new LEGlyphStorage(); fGlyphStorage = new LEGlyphStorage();
if (fGlyphStorage == NULL) { if (fGlyphStorage == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
} }
} }
le_int32 LayoutEngine::getGlyphCount() const le_int32 LayoutEngine::getGlyphCount() const
...@@ -263,7 +262,9 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -263,7 +262,9 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
return count; return count;
} }
LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable); LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable(LETableReference::kStaticData,
(GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable,
CanonShaping::glyphSubstitutionTableLen);
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;
...@@ -300,7 +301,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -300,7 +301,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
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);
...@@ -323,7 +324,8 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -323,7 +324,8 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
LE_DELETE_ARRAY(reordered); LE_DELETE_ARRAY(reordered);
} }
outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success); const LEReferenceTo<GlyphDefinitionTableHeader> noGDEF; // empty gdef header
outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, noGDEF, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
delete substitutionFilter; delete substitutionFilter;
...@@ -403,10 +405,13 @@ void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y ...@@ -403,10 +405,13 @@ void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y
LEPoint advance; LEPoint advance;
glyphStorage.setPosition(i, x, y, success); glyphStorage.setPosition(i, x, y, success);
_LETRACE("g#%-4d (%.2f, %.2f)", i, x, y);
fFontInstance->getGlyphAdvance(glyphStorage[i], advance); fFontInstance->getGlyphAdvance(glyphStorage[i], advance);
x += advance.fX; x += advance.fX;
y += advance.fY; y += advance.fY;
} }
glyphStorage.setPosition(glyphCount, x, y, success); glyphStorage.setPosition(glyphCount, x, y, success);
...@@ -424,7 +429,7 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset ...@@ -424,7 +429,7 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset
return; return;
} }
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
CanonShaping::glyphDefinitionTableLen); CanonShaping::glyphDefinitionTableLen);
CanonMarkFilter filter(gdefTable, success); CanonMarkFilter filter(gdefTable, success);
...@@ -464,9 +469,10 @@ void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter ...@@ -464,9 +469,10 @@ void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter
glyphStorage.getGlyphPosition(p + 1, next, ignore, success); glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
xAdvance = next - prev; xAdvance = next - prev;
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
glyphStorage.adjustPosition(p, xAdjust, 0, success); glyphStorage.adjustPosition(p, xAdjust, 0, success);
if (markFilter->accept(glyphStorage[p])) { if (markFilter->accept(glyphStorage[p], success)) {
xAdjust -= xAdvance; xAdjust -= xAdvance;
} }
...@@ -506,9 +512,13 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, ...@@ -506,9 +512,13 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
glyphStorage.getGlyphPosition(p + 1, next, ignore, success); glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
xAdvance = next - prev; xAdvance = next - prev;
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
glyphStorage.adjustPosition(p, xAdjust, 0, success); glyphStorage.adjustPosition(p, xAdjust, 0, success);
if (markFilter->accept(chars[c])) { if (markFilter->accept(chars[c], success)) {
xAdjust -= xAdvance; xAdjust -= xAdvance;
} }
...@@ -662,8 +672,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -662,8 +672,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
break; break;
} }
} else { } else {
MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag); LEReferenceTo<MorphTableHeader2> morxTable(fontInstance, morxTableTag, success);
if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) { if (LE_SUCCESS(success) &&
morxTable.isValid() &&
SWAPL(morxTable->version)==0x00020000) {
result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success); result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
} else { } else {
LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success); LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
...@@ -686,21 +698,20 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -686,21 +698,20 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
break; break;
} }
case arabScriptCode: case arabScriptCode:
//case hebrScriptCode: result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); break;
break;
//case hebrScriptCode: //case hebrScriptCode:
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); // return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
case thaiScriptCode: case thaiScriptCode:
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break; break;
case hangScriptCode: case hangScriptCode:
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break; break;
default: default:
result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
...@@ -711,9 +722,9 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -711,9 +722,9 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
} }
if (result && LE_FAILURE(success)) { if (result && LE_FAILURE(success)) {
delete result; delete result;
result = NULL; result = NULL;
} }
if (result == NULL) { if (result == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
......
...@@ -156,8 +156,8 @@ protected: ...@@ -156,8 +156,8 @@ protected:
* @param fontInstance - the font for the text * @param fontInstance - the font for the text
* @param scriptCode - the script for the text * @param scriptCode - the script for the text
* @param languageCode - the language for the text * @param languageCode - the language for the text
* @param typoFlags - the typographic control flags for the text. Set bit 1 if kerning * @param typoFlags - the typographic control flags for the text (a bitfield). Use kTypoFlagKern
* is desired, set bit 2 if ligature formation is desired. Others are reserved. * if kerning is desired, kTypoFlagLiga if ligature formation is desired. Others are reserved.
* @param success - set to an error code if the operation fails * @param success - set to an error code if the operation fails
* *
* @see LEFontInstance * @see LEFontInstance
......
...@@ -105,7 +105,7 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp ...@@ -105,7 +105,7 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY); LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
if(LE_FAILURE(success)) { if(LE_FAILURE(success)) {
currGlyph+= dir; currGlyph+= dir;
return nextStateIndex; // get out! bad font return nextStateIndex; // get out! bad font
} }
do { do {
......
...@@ -49,14 +49,20 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -49,14 +49,20 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl
return 0; return 0;
} }
if (coverageIndex >= 0) { LEReferenceToArrayOf<Offset> ligSetTableOffsetArrayRef(base, success, ligSetTableOffsetArray, SWAPW(ligSetCount));
if (coverageIndex >= 0 && LE_SUCCESS(success) && (le_uint32)coverageIndex < ligSetTableOffsetArrayRef.getCount()) {
Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]); Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
const LigatureSetTable *ligSetTable = (const LigatureSetTable *) ((char *) this + ligSetTableOffset); LEReferenceTo<LigatureSetTable> ligSetTable(base, success, ligSetTableOffset);
if( LE_FAILURE(success) ) { return 0; }
le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount); le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount);
for (le_uint16 lig = 0; lig < ligCount; lig += 1) { LEReferenceTo<Offset> ligatureTableOffsetArray(base, success, ligSetTable->ligatureTableOffsetArray, ligCount);
for (le_uint16 lig = 0; LE_SUCCESS(success) && lig < ligCount; lig += 1) {
Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]); Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]);
const LigatureTable *ligTable = (const LigatureTable *) ((char *)ligSetTable + ligTableOffset); LEReferenceTo<LigatureTable> ligTable(ligSetTable, success, ligTableOffset);
if(LE_FAILURE(success)) { return 0; }
le_uint16 compCount = SWAPW(ligTable->compCount) - 1; le_uint16 compCount = SWAPW(ligTable->compCount) - 1;
le_int32 startPosition = glyphIterator->getCurrStreamPosition(); le_int32 startPosition = glyphIterator->getCurrStreamPosition();
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph); TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
...@@ -72,7 +78,7 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -72,7 +78,7 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl
} }
} }
if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph)))) { if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph), success))) {
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF; TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF;
......
...@@ -60,9 +60,11 @@ le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lo ...@@ -60,9 +60,11 @@ le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lo
LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success); LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success); delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
if (delta > 0 && LE_FAILURE(success)) {
if (delta > 0 || LE_FAILURE(success)) { #if LE_TRACE
return 1; _LETRACE("Posn #%d, type %X, applied subtable #%d/%d - %s\n", startPosition, lookupType, subtable, subtableCount, u_errorName((UErrorCode)success));
#endif
return 1;
} }
glyphIterator->setCurrStreamPosition(startPosition); glyphIterator->setCurrStreamPosition(startPosition);
...@@ -86,7 +88,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -86,7 +88,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
} }
GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments, GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
rightToLeft, 0, 0, glyphDefinitionTableHeader); rightToLeft, 0, 0, glyphDefinitionTableHeader, success);
le_int32 newGlyphCount = glyphCount; le_int32 newGlyphCount = glyphCount;
for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) { for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
...@@ -94,6 +96,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -94,6 +96,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
FeatureMask selectMask = lookupSelectArray[lookup]; FeatureMask selectMask = lookupSelectArray[lookup];
if (selectMask != 0) { if (selectMask != 0) {
_LETRACE("Processing order#%d/%d", order, lookupOrderCount);
const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success); const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
if (!lookupTable.isValid() ||LE_FAILURE(success) ) { if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
continue; continue;
...@@ -103,8 +106,11 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj ...@@ -103,8 +106,11 @@ 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); // TODO applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
#if LE_TRACE
_LETRACE("Failure for lookup 0x%x - %s\n", lookup, u_errorName((UErrorCode)success));
#endif
return 0; return 0;
} }
} }
......
...@@ -65,7 +65,7 @@ le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &b ...@@ -65,7 +65,7 @@ le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &b
if(LE_FAILURE(success)) return 0; if(LE_FAILURE(success)) return 0;
return coverageTable->getGlyphCoverage(glyphID); return coverageTable->getGlyphCoverage(coverageTable, glyphID, success);
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -38,20 +38,28 @@ ...@@ -38,20 +38,28 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_int32 MarkArray::getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance, le_int32 MarkArray::getMarkClass(const LETableReference &base, LEGlyphID glyphID,
LEPoint &anchor) const le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const
{ {
le_int32 markClass = -1; le_int32 markClass = -1;
if (coverageIndex >= 0) { if ( coverageIndex >= 0 && LE_SUCCESS(success) ) {
le_uint16 mCount = SWAPW(markCount); le_uint16 mCount = SWAPW(markCount);
if (coverageIndex < mCount) { if (coverageIndex < mCount) {
LEReferenceToArrayOf<MarkRecord> markRecordArrayRef(base, success, markRecordArray, mCount);
if(LE_FAILURE(success)) {
return markClass;
}
const MarkRecord *markRecord = &markRecordArray[coverageIndex]; const MarkRecord *markRecord = &markRecordArray[coverageIndex];
Offset anchorTableOffset = SWAPW(markRecord->markAnchorTableOffset); Offset anchorTableOffset = SWAPW(markRecord->markAnchorTableOffset);
const AnchorTable *anchorTable = (AnchorTable *) ((char *) this + anchorTableOffset); LEReferenceTo<AnchorTable> anchorTable(base, success, anchorTableOffset);
if(LE_FAILURE(success)) {
return markClass;
}
anchorTable->getAnchor(glyphID, fontInstance, anchor); anchorTable->getAnchor(anchorTable, glyphID, fontInstance, anchor, success);
markClass = SWAPW(markRecord->markClass); markClass = SWAPW(markRecord->markClass);
} }
......
...@@ -54,8 +54,9 @@ struct MarkArray ...@@ -54,8 +54,9 @@ struct MarkArray
le_uint16 markCount; le_uint16 markCount;
MarkRecord markRecordArray[ANY_NUMBER]; MarkRecord markRecordArray[ANY_NUMBER];
le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance, le_int32 getMarkClass(const LETableReference &base, LEGlyphID glyphID,
LEPoint &anchor) const; le_int32 coverageIndex, const LEFontInstance *fontInstance,
LEPoint &anchor, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(MarkArray, markRecordArray) LE_VAR_ARRAY(MarkArray, markRecordArray)
......
...@@ -66,11 +66,11 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -66,11 +66,11 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
} }
LEPoint markAnchor; LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); LEReferenceTo<MarkArray> markArray(base, success, (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount); le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) { if (markClass < 0 || markClass >= mcCount || LE_FAILURE(success)) {
// markGlyph isn't in the mark array or its // markGlyph isn't in the mark array or its
// mark class is too big. The table is mal-formed! // mark class is too big. The table is mal-formed!
return 0; return 0;
...@@ -80,7 +80,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -80,7 +80,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
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(base, (LEGlyphID) baseGlyph, success); le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success);
const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)); LEReferenceTo<BaseArray> baseArray(base, success, (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0;
le_uint16 baseCount = SWAPW(baseArray->baseRecordCount); le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);
if (baseCoverage < 0 || baseCoverage >= baseCount) { if (baseCoverage < 0 || baseCoverage >= baseCount) {
...@@ -89,19 +90,23 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -89,19 +90,23 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
// table is mal-formed... // table is mal-formed...
return 0; return 0;
} }
LEReferenceTo<BaseRecord> baseRecord(base, success, &baseArray->baseRecordArray[baseCoverage * mcCount]);
if( LE_FAILURE(success) ) { return 0; }
LEReferenceToArrayOf<Offset> baseAnchorTableOffsetArray(base, success, &(baseRecord->baseAnchorTableOffsetArray[0]), markClass+1);
const BaseRecord *baseRecord = &baseArray->baseRecordArray[baseCoverage * mcCount]; if( LE_FAILURE(success) ) { return 0; }
Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]); Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) baseArray + anchorTableOffset); if (anchorTableOffset <= 0) {
LEPoint baseAnchor, markAdvance, pixels;
if (anchorTableOffset == 0) {
// this means the table is mal-formed... // this means the table is mal-formed...
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition()); glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
return 0; return 0;
} }
anchorTable->getAnchor(baseGlyph, fontInstance, baseAnchor); LEReferenceTo<AnchorTable> anchorTable(baseArray, success, anchorTableOffset);
LEPoint baseAnchor, markAdvance, pixels;
anchorTable->getAnchor(anchorTable, baseGlyph, fontInstance, baseAnchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels); fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance); fontInstance->pixelsToUnits(pixels, markAdvance);
...@@ -109,6 +114,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -109,6 +114,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
float anchorDiffX = baseAnchor.fX - markAnchor.fX; float anchorDiffX = baseAnchor.fX - markAnchor.fX;
float anchorDiffY = baseAnchor.fY - markAnchor.fY; float anchorDiffY = baseAnchor.fY - markAnchor.fY;
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X", anchorDiffX, anchorDiffY, markGlyph);
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition()); glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
if (glyphIterator->isRightToLeft()) { if (glyphIterator->isRightToLeft()) {
...@@ -132,7 +139,6 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl ...@@ -132,7 +139,6 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
gi.next(); gi.next();
} }
// end of JK patch // end of JK patch
fontInstance->pixelsToUnits(pixels, baseAdvance); fontInstance->pixelsToUnits(pixels, baseAdvance);
glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY); glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY);
......
...@@ -65,8 +65,11 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -65,8 +65,11 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
} }
LEPoint markAnchor; LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); if( LE_FAILURE(success) ) {
return 0;
}
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount); le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) { if (markClass < 0 || markClass >= mcCount) {
...@@ -79,7 +82,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -79,7 +82,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
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(base, (LEGlyphID) ligatureGlyph, success); le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success);
const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset)); LEReferenceTo<LigatureArray> ligatureArray(base, success, SWAPW(baseArrayOffset));
le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount); le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);
if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) { if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) {
...@@ -91,7 +94,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -91,7 +94,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
le_int32 markPosition = glyphIterator->getCurrStreamPosition(); le_int32 markPosition = glyphIterator->getCurrStreamPosition();
Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]); Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]);
const LigatureAttachTable *ligatureAttachTable = (const LigatureAttachTable *) ((char *) ligatureArray + ligatureAttachOffset); LEReferenceTo<LigatureAttachTable> ligatureAttachTable(ligatureArray, success, ligatureAttachOffset);
le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount); le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount);
le_int32 component = ligatureIterator.getMarkComponent(markPosition); le_int32 component = ligatureIterator.getMarkComponent(markPosition);
...@@ -100,12 +103,14 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base ...@@ -100,12 +103,14 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
component = componentCount - 1; component = componentCount - 1;
} }
const ComponentRecord *componentRecord = &ligatureAttachTable->componentRecordArray[component * mcCount]; LEReferenceTo<ComponentRecord> componentRecord(base, success, &ligatureAttachTable->componentRecordArray[component * mcCount]);
LEReferenceToArrayOf<Offset> ligatureAnchorTableOffsetArray(base, success, &(componentRecord->ligatureAnchorTableOffsetArray[0]), markClass+1);
if( LE_FAILURE(success) ) { return 0; }
Offset anchorTableOffset = SWAPW(componentRecord->ligatureAnchorTableOffsetArray[markClass]); Offset anchorTableOffset = SWAPW(componentRecord->ligatureAnchorTableOffsetArray[markClass]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) ligatureAttachTable + anchorTableOffset); LEReferenceTo<AnchorTable> anchorTable(ligatureAttachTable, success, anchorTableOffset);
LEPoint ligatureAnchor, markAdvance, pixels; LEPoint ligatureAnchor, markAdvance, pixels;
anchorTable->getAnchor(ligatureGlyph, fontInstance, ligatureAnchor); anchorTable->getAnchor(anchorTable, ligatureGlyph, fontInstance, ligatureAnchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels); fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance); fontInstance->pixelsToUnits(pixels, markAdvance);
......
...@@ -66,8 +66,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -66,8 +66,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
} }
LEPoint markAnchor; LEPoint markAnchor;
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)); LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor); if(LE_FAILURE(success)) {
return 0;
}
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
le_uint16 mcCount = SWAPW(classCount); le_uint16 mcCount = SWAPW(classCount);
if (markClass < 0 || markClass >= mcCount) { if (markClass < 0 || markClass >= mcCount) {
...@@ -79,7 +82,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -79,7 +82,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
GlyphIterator mark2Iterator(*glyphIterator); GlyphIterator mark2Iterator(*glyphIterator);
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator); LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success); le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success);
const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)); LEReferenceTo<Mark2Array> mark2Array(base, success, (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)));
if(LE_FAILURE(success)) return 0;
le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount); le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
if (mark2Coverage < 0 || mark2Coverage >= mark2Count) { if (mark2Coverage < 0 || mark2Coverage >= mark2Count) {
...@@ -89,9 +93,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -89,9 +93,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
return 0; return 0;
} }
const Mark2Record *mark2Record = &mark2Array->mark2RecordArray[mark2Coverage * mcCount]; LEReferenceTo<Mark2Record> mark2Record(base, success, &mark2Array->mark2RecordArray[mark2Coverage * mcCount]);
if(LE_FAILURE(success)) return 0;
Offset anchorTableOffset = SWAPW(mark2Record->mark2AnchorTableOffsetArray[markClass]); Offset anchorTableOffset = SWAPW(mark2Record->mark2AnchorTableOffsetArray[markClass]);
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) mark2Array + anchorTableOffset); LEReferenceTo<AnchorTable> anchorTable(mark2Array, success, anchorTableOffset);
if(LE_FAILURE(success)) return 0;
LEPoint mark2Anchor, markAdvance, pixels; LEPoint mark2Anchor, markAdvance, pixels;
if (anchorTableOffset == 0) { if (anchorTableOffset == 0) {
...@@ -99,7 +105,7 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -99,7 +105,7 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
return 0; return 0;
} }
anchorTable->getAnchor(mark2Glyph, fontInstance, mark2Anchor); anchorTable->getAnchor(anchorTable, mark2Glyph, fontInstance, mark2Anchor, success);
fontInstance->getGlyphAdvance(markGlyph, pixels); fontInstance->getGlyphAdvance(markGlyph, pixels);
fontInstance->pixelsToUnits(pixels, markAdvance); fontInstance->pixelsToUnits(pixels, markAdvance);
...@@ -107,6 +113,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl ...@@ -107,6 +113,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
float anchorDiffX = mark2Anchor.fX - markAnchor.fX; float anchorDiffX = mark2Anchor.fX - markAnchor.fX;
float anchorDiffY = mark2Anchor.fY - markAnchor.fY; float anchorDiffY = mark2Anchor.fY - markAnchor.fY;
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X mark2 0x%X", anchorDiffX, anchorDiffY, markGlyph, mark2Glyph);
glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition()); glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition());
if (glyphIterator->isRightToLeft()) { if (glyphIterator->isRightToLeft()) {
......
...@@ -54,9 +54,10 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -54,9 +54,10 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
// FIXME: is this always the right thing to do? // FIXME: is this always the right thing to do?
// FIXME: should this only be done for a non-zero // FIXME: should this only be done for a non-zero
// glyphCount? // glyphCount?
if (filter != NULL && filter->accept(glyph)) { if (filter != NULL && filter->accept(glyph, success)) {
return 0; return 0;
} }
if(LE_FAILURE(success)) return 0;
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
le_uint16 seqCount = SWAPW(sequenceCount); le_uint16 seqCount = SWAPW(sequenceCount);
...@@ -67,7 +68,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -67,7 +68,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
if (coverageIndex >= 0 && coverageIndex < seqCount) { if (coverageIndex >= 0 && coverageIndex < seqCount) {
Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]); Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset); LEReferenceTo<SequenceTable> sequenceTable(base, success, sequenceTableOffset);
le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount); le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount);
if (glyphCount == 0) { if (glyphCount == 0) {
...@@ -76,7 +77,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -76,7 +77,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
} else if (glyphCount == 1) { } else if (glyphCount == 1) {
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]); TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) { if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
return 0; return 0;
} }
...@@ -89,7 +90,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl ...@@ -89,7 +90,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
for (le_int32 i = 0; i < glyphCount; i += 1) { for (le_int32 i = 0; i < glyphCount; i += 1) {
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]); TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
if (! filter->accept(substitute)) { if (! filter->accept(substitute, success)) {
return 0; return 0;
} }
} }
......
...@@ -470,6 +470,7 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o ...@@ -470,6 +470,7 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o
void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
LEGlyphStorage &glyphStorage, LEErrorCode &success) LEGlyphStorage &glyphStorage, LEErrorCode &success)
{ {
_LETRACE("OTLE::adjustGPOS");
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
return; return;
} }
...@@ -510,14 +511,17 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 ...@@ -510,14 +511,17 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
if (!fGPOSTable.isEmpty()) { if (!fGPOSTable.isEmpty()) {
if (fScriptTagV2 != nullScriptTag && if (fScriptTagV2 != nullScriptTag &&
fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) { fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) {
_LETRACE("OTLE::process [0]");
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} else { } else {
_LETRACE("OTLE::process [1]");
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag,
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
} }
} else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ } else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
_LETRACE("OTLE::kerning");
LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
KernTable kt(kernTable, success); KernTable kt(kernTable, success);
kt.process(glyphStorage, success); kt.process(glyphStorage, success);
...@@ -546,6 +550,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 ...@@ -546,6 +550,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
xPlacement = fFontInstance->xUnitsToPoints(xPlacement); xPlacement = fFontInstance->xUnitsToPoints(xPlacement);
yPlacement = fFontInstance->yUnitsToPoints(yPlacement); yPlacement = fFontInstance->yUnitsToPoints(yPlacement);
_LETRACE("OTLE GPOS: #%d, (%.2f,%.2f)", i, xPlacement, yPlacement);
glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success); glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success);
xAdjust += fFontInstance->xUnitsToPoints(xAdvance); xAdjust += fFontInstance->xUnitsToPoints(xAdvance);
......
...@@ -46,15 +46,14 @@ class OpenTypeUtilities /* not : public UObject because all methods are static * ...@@ -46,15 +46,14 @@ 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 LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success); static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success);
/** #if LE_ENABLE_RAW
* @deprecated TODO remove
*/
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) { static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) {
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
LETableReference recordRef0((const le_uint8*)records); LETableReference recordRef0((const le_uint8*)records);
LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount); LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount);
return getGlyphRangeIndex(glyphID, recordRef, success); return getGlyphRangeIndex(glyphID, recordRef, success);
} }
#endif
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &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);
......
...@@ -76,19 +76,17 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi ...@@ -76,19 +76,17 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
{ {
LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success); le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
if (LE_FAILURE(success)) {
return 0;
}
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
if (coverageIndex >= 0 && glyphIterator->next()) { LEReferenceToArrayOf<Offset> pairSetTableOffsetArrayRef(base, success, pairSetTableOffsetArray, SWAPW(pairSetCount));
if (LE_SUCCESS(success) && coverageIndex >= 0 && glyphIterator->next() && (le_uint32)coverageIndex < pairSetTableOffsetArrayRef.getCount()) {
Offset pairSetTableOffset = SWAPW(pairSetTableOffsetArray[coverageIndex]); Offset pairSetTableOffset = SWAPW(pairSetTableOffsetArray[coverageIndex]);
LEReferenceTo<PairSetTable> pairSetTable(base, success, ((char *) this + pairSetTableOffset)); LEReferenceTo<PairSetTable> pairSetTable(base, success, pairSetTableOffset);
if (LE_FAILURE(success)) { if( LE_FAILURE(success) ) return 0;
return 0;
}
le_uint16 pairValueCount = SWAPW(pairSetTable->pairValueCount); le_uint16 pairValueCount = SWAPW(pairSetTable->pairValueCount);
LEReferenceTo<PairValueRecord> pairValueRecordArray(pairSetTable, success, pairSetTable->pairValueRecordArray);
if( LE_FAILURE(success) ) return 0;
le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1)); le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1));
le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2)); le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
le_int16 recordSize = sizeof(PairValueRecord) - sizeof(ValueRecord) + valueRecord1Size + valueRecord2Size; le_int16 recordSize = sizeof(PairValueRecord) - sizeof(ValueRecord) + valueRecord1Size + valueRecord2Size;
...@@ -96,21 +94,22 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi ...@@ -96,21 +94,22 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
LEReferenceTo<PairValueRecord> pairValueRecord; LEReferenceTo<PairValueRecord> pairValueRecord;
if (pairValueCount != 0) { if (pairValueCount != 0) {
pairValueRecord = findPairValueRecord(base, (TTGlyphID) LE_GET_GLYPH(secondGlyph), pairSetTable->pairValueRecordArray, pairValueCount, recordSize, success); pairValueRecord = findPairValueRecord((TTGlyphID) LE_GET_GLYPH(secondGlyph), pairValueRecordArray, pairValueCount, recordSize, success);
} }
if (pairValueRecord.isEmpty()) { if (pairValueRecord.isEmpty() || LE_FAILURE(success)) {
return 0; return 0;
} }
if (valueFormat1 != 0) { if (valueFormat1 != 0) {
pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance); pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
} }
if (valueFormat2 != 0) { if (valueFormat2 != 0) {
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size); LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size));
if(LE_SUCCESS(success)) {
valueRecord2->adjustPosition(SWAPW(valueFormat2), (char *) this, *glyphIterator, fontInstance); valueRecord2->adjustPosition(SWAPW(valueFormat2), base, *glyphIterator, fontInstance, success);
}
} }
// back up glyphIterator so second glyph can be // back up glyphIterator so second glyph can be
...@@ -135,26 +134,28 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi ...@@ -135,26 +134,28 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
if (coverageIndex >= 0 && glyphIterator->next()) { if (coverageIndex >= 0 && glyphIterator->next()) {
LEGlyphID secondGlyph = glyphIterator->getCurrGlyphID(); LEGlyphID secondGlyph = glyphIterator->getCurrGlyphID();
const ClassDefinitionTable *classDef1 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef1Offset)); const LEReferenceTo<ClassDefinitionTable> classDef1(base, success, SWAPW(classDef1Offset));
const ClassDefinitionTable *classDef2 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef2Offset)); const LEReferenceTo<ClassDefinitionTable> classDef2(base, success, SWAPW(classDef2Offset));
le_int32 class1 = classDef1->getGlyphClass(firstGlyph); le_int32 class1 = classDef1->getGlyphClass(classDef1, firstGlyph, success);
le_int32 class2 = classDef2->getGlyphClass(secondGlyph); le_int32 class2 = classDef2->getGlyphClass(classDef2, secondGlyph, success);
le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1)); le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1));
le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2)); le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
le_int16 class2RecordSize = valueRecord1Size + valueRecord2Size; le_int16 class2RecordSize = valueRecord1Size + valueRecord2Size;
le_int16 class1RecordSize = class2RecordSize * SWAPW(class2Count); le_int16 class1RecordSize = class2RecordSize * SWAPW(class2Count);
const Class1Record *class1Record = (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1)); const LEReferenceTo<Class1Record> class1Record(base, success, (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1)));
const Class2Record *class2Record = (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2)); const LEReferenceTo<Class2Record> class2Record(base, success, (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2)));
if( LE_SUCCESS(success) ) {
if (valueFormat1 != 0) { if (valueFormat1 != 0) {
class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance); class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
} }
if (valueFormat2 != 0) {
if (valueFormat2 != 0) { const LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &class2Record->valueRecord1) + valueRecord1Size);
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &class2Record->valueRecord1 + valueRecord1Size); LEReferenceTo<PairPositioningFormat2Subtable> thisRef(base, success, this);
if(LE_SUCCESS(success)) {
valueRecord2->adjustPosition(SWAPW(valueFormat2), (const char *) this, *glyphIterator, fontInstance); valueRecord2->adjustPosition(SWAPW(valueFormat2), thisRef, *glyphIterator, fontInstance, success);
}
}
} }
// back up glyphIterator so second glyph can be // back up glyphIterator so second glyph can be
...@@ -166,23 +167,24 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi ...@@ -166,23 +167,24 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
return 0; return 0;
} }
LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const LEReferenceTo<PairValueRecord>
PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID, LEReferenceTo<PairValueRecord>& records,
le_uint16 recordCount,
le_uint16 recordSize, LEErrorCode &success) const
{ {
#if 1 #if 1
// The OpenType spec. says that the ValueRecord table is // The OpenType spec. says that the ValueRecord table is
// sorted by secondGlyph. Unfortunately, there are fonts // sorted by secondGlyph. Unfortunately, there are fonts
// around that have an unsorted ValueRecord table. // around that have an unsorted ValueRecord table.
LEReferenceTo<PairValueRecord> record(base, success, records); LEReferenceTo<PairValueRecord> record(records);
record.verifyLength(0, recordSize, success);
for(le_int32 r = 0; r < recordCount; r += 1) { for(le_int32 r = 0; r < recordCount; r += 1) {
if (LE_FAILURE(success)) return (const PairValueRecord*)NULL; if(LE_FAILURE(success)) return LEReferenceTo<PairValueRecord>();
if (SWAPW(record->secondGlyph) == glyphID) { if (SWAPW(record->secondGlyph) == glyphID) {
return record; return record;
} }
record = LEReferenceTo<PairValueRecord>(base, success, ((const char*)record.getAlias())+ recordSize); record.addOffset(recordSize, success);
record.verifyLength(0, recordSize, success);
} }
#else #else
#error dead code - not updated. #error dead code - not updated.
...@@ -211,7 +213,7 @@ LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueReco ...@@ -211,7 +213,7 @@ LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueReco
} }
#endif #endif
return (const PairValueRecord*)NULL; return LEReferenceTo<PairValueRecord>();
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -77,9 +77,8 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable ...@@ -77,9 +77,8 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable
le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
private: private:
LEReferenceTo<PairValueRecord> findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records, LEReferenceTo<PairValueRecord> findPairValueRecord(TTGlyphID glyphID, LEReferenceTo<PairValueRecord> &records,
le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const; le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const;
}; };
LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray) LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray)
......
...@@ -106,7 +106,8 @@ LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &b ...@@ -106,7 +106,8 @@ LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &b
} }
} else { } else {
LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count); LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count);
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success);
} }
if (scriptTableOffset != 0) { if (scriptTableOffset != 0) {
......
...@@ -126,13 +126,13 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { ...@@ -126,13 +126,13 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
linaScriptTag, /* 'lina' (LINA) */ linaScriptTag, /* 'lina' (LINA) */
mandScriptTag, /* 'mand' (MANDAIC) */ mandScriptTag, /* 'mand' (MANDAIC) */
mayaScriptTag, /* 'maya' (MAYA) */ mayaScriptTag, /* 'maya' (MAYA) */
meroScriptTag, /* 'mero' (MERO) */ meroScriptTag, /* 'mero' (MEROITIC_HIEROGLYPHS) */
nkooScriptTag, /* 'nko ' (NKO) */ nkooScriptTag, /* 'nko ' (NKO) */
orkhScriptTag, /* 'orkh' (OLD_TURKIC) */ orkhScriptTag, /* 'orkh' (OLD_TURKIC) */
permScriptTag, /* 'perm' (PERM) */ permScriptTag, /* 'perm' (PERM) */
phagScriptTag, /* 'phag' (PHAGS_PA) */ phagScriptTag, /* 'phag' (PHAGS_PA) */
phnxScriptTag, /* 'phnx' (PHOENICIAN) */ phnxScriptTag, /* 'phnx' (PHOENICIAN) */
plrdScriptTag, /* 'plrd' (PLRD) */ plrdScriptTag, /* 'plrd' (MIAO/POLLARD) */
roroScriptTag, /* 'roro' (RORO) */ roroScriptTag, /* 'roro' (RORO) */
saraScriptTag, /* 'sara' (SARA) */ saraScriptTag, /* 'sara' (SARA) */
syreScriptTag, /* 'syre' (SYRE) */ syreScriptTag, /* 'syre' (SYRE) */
...@@ -158,7 +158,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { ...@@ -158,7 +158,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
mteiScriptTag, /* 'mtei' (MEETEI_MAYEK) */ mteiScriptTag, /* 'mtei' (MEETEI_MAYEK) */
armiScriptTag, /* 'armi' (IMPERIAL_ARAMAIC) */ armiScriptTag, /* 'armi' (IMPERIAL_ARAMAIC) */
avstScriptTag, /* 'avst' (AVESTAN) */ avstScriptTag, /* 'avst' (AVESTAN) */
cakmScriptTag, /* 'cakm' (CAKM) */ cakmScriptTag, /* 'cakm' (CHAKMA) */
koreScriptTag, /* 'kore' (KORE) */ koreScriptTag, /* 'kore' (KORE) */
kthiScriptTag, /* 'kthi' (KAITHI) */ kthiScriptTag, /* 'kthi' (KAITHI) */
maniScriptTag, /* 'mani' (MANI) */ maniScriptTag, /* 'mani' (MANI) */
...@@ -181,7 +181,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { ...@@ -181,7 +181,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
kpelScriptTag, /* 'kpel' (KPEL) */ kpelScriptTag, /* 'kpel' (KPEL) */
lomaScriptTag, /* 'loma' (LOMA) */ lomaScriptTag, /* 'loma' (LOMA) */
mendScriptTag, /* 'mend' (MEND) */ mendScriptTag, /* 'mend' (MEND) */
mercScriptTag, /* 'merc' (MERC) */ mercScriptTag, /* 'merc' (MEROITIC_CURSIVE) */
narbScriptTag, /* 'narb' (NARB) */ narbScriptTag, /* 'narb' (NARB) */
nbatScriptTag, /* 'nbat' (NBAT) */ nbatScriptTag, /* 'nbat' (NBAT) */
palmScriptTag, /* 'palm' (PALM) */ palmScriptTag, /* 'palm' (PALM) */
......
...@@ -140,13 +140,13 @@ const LETag lepcScriptTag = 0x6C657063; /* 'lepc' (LEPCHA) */ ...@@ -140,13 +140,13 @@ const LETag lepcScriptTag = 0x6C657063; /* 'lepc' (LEPCHA) */
const LETag linaScriptTag = 0x6C696E61; /* 'lina' (LINA) */ const LETag linaScriptTag = 0x6C696E61; /* 'lina' (LINA) */
const LETag mandScriptTag = 0x6D616E64; /* 'mand' (MANDAIC) */ const LETag mandScriptTag = 0x6D616E64; /* 'mand' (MANDAIC) */
const LETag mayaScriptTag = 0x6D617961; /* 'maya' (MAYA) */ const LETag mayaScriptTag = 0x6D617961; /* 'maya' (MAYA) */
const LETag meroScriptTag = 0x6D65726F; /* 'mero' (MERO) */ const LETag meroScriptTag = 0x6D65726F; /* 'mero' (MEROITIC_HIEROGLYPHS) */
const LETag nkooScriptTag = 0x6E6B6F20; /* 'nko ' (NKO) */ const LETag nkooScriptTag = 0x6E6B6F20; /* 'nko ' (NKO) */
const LETag orkhScriptTag = 0x6F726B68; /* 'orkh' (OLD_TURKIC) */ const LETag orkhScriptTag = 0x6F726B68; /* 'orkh' (OLD_TURKIC) */
const LETag permScriptTag = 0x7065726D; /* 'perm' (PERM) */ const LETag permScriptTag = 0x7065726D; /* 'perm' (PERM) */
const LETag phagScriptTag = 0x70686167; /* 'phag' (PHAGS_PA) */ const LETag phagScriptTag = 0x70686167; /* 'phag' (PHAGS_PA) */
const LETag phnxScriptTag = 0x70686E78; /* 'phnx' (PHOENICIAN) */ const LETag phnxScriptTag = 0x70686E78; /* 'phnx' (PHOENICIAN) */
const LETag plrdScriptTag = 0x706C7264; /* 'plrd' (PLRD) */ const LETag plrdScriptTag = 0x706C7264; /* 'plrd' (MIAO) */
const LETag roroScriptTag = 0x726F726F; /* 'roro' (RORO) */ const LETag roroScriptTag = 0x726F726F; /* 'roro' (RORO) */
const LETag saraScriptTag = 0x73617261; /* 'sara' (SARA) */ const LETag saraScriptTag = 0x73617261; /* 'sara' (SARA) */
const LETag syreScriptTag = 0x73797265; /* 'syre' (SYRE) */ const LETag syreScriptTag = 0x73797265; /* 'syre' (SYRE) */
...@@ -172,7 +172,7 @@ const LETag moonScriptTag = 0x6D6F6F6E; /* 'moon' (MOON) */ ...@@ -172,7 +172,7 @@ const LETag moonScriptTag = 0x6D6F6F6E; /* 'moon' (MOON) */
const LETag mteiScriptTag = 0x6D746569; /* 'mtei' (MEETEI_MAYEK) */ const LETag mteiScriptTag = 0x6D746569; /* 'mtei' (MEETEI_MAYEK) */
const LETag armiScriptTag = 0x61726D69; /* 'armi' (IMPERIAL_ARAMAIC) */ const LETag armiScriptTag = 0x61726D69; /* 'armi' (IMPERIAL_ARAMAIC) */
const LETag avstScriptTag = 0x61767374; /* 'avst' (AVESTAN) */ const LETag avstScriptTag = 0x61767374; /* 'avst' (AVESTAN) */
const LETag cakmScriptTag = 0x63616B6D; /* 'cakm' (CAKM) */ const LETag cakmScriptTag = 0x63616B6D; /* 'cakm' (CHAKMA) */
const LETag koreScriptTag = 0x6B6F7265; /* 'kore' (KORE) */ const LETag koreScriptTag = 0x6B6F7265; /* 'kore' (KORE) */
const LETag kthiScriptTag = 0x6B746869; /* 'kthi' (KAITHI) */ const LETag kthiScriptTag = 0x6B746869; /* 'kthi' (KAITHI) */
const LETag maniScriptTag = 0x6D616E69; /* 'mani' (MANI) */ const LETag maniScriptTag = 0x6D616E69; /* 'mani' (MANI) */
...@@ -195,7 +195,7 @@ const LETag granScriptTag = 0x6772616E; /* 'gran' (GRAN) */ ...@@ -195,7 +195,7 @@ const LETag granScriptTag = 0x6772616E; /* 'gran' (GRAN) */
const LETag kpelScriptTag = 0x6B70656C; /* 'kpel' (KPEL) */ const LETag kpelScriptTag = 0x6B70656C; /* 'kpel' (KPEL) */
const LETag lomaScriptTag = 0x6C6F6D61; /* 'loma' (LOMA) */ const LETag lomaScriptTag = 0x6C6F6D61; /* 'loma' (LOMA) */
const LETag mendScriptTag = 0x6D656E64; /* 'mend' (MEND) */ const LETag mendScriptTag = 0x6D656E64; /* 'mend' (MEND) */
const LETag mercScriptTag = 0x6D657263; /* 'merc' (MERC) */ const LETag mercScriptTag = 0x6D657263; /* 'merc' (MEROITIC_CURSIVE) */
const LETag narbScriptTag = 0x6E617262; /* 'narb' (NARB) */ const LETag narbScriptTag = 0x6E617262; /* 'narb' (NARB) */
const LETag nbatScriptTag = 0x6E626174; /* 'nbat' (NBAT) */ const LETag nbatScriptTag = 0x6E626174; /* 'nbat' (NBAT) */
const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */ const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */
......
...@@ -65,17 +65,18 @@ void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode & ...@@ -65,17 +65,18 @@ void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &
for (glyph = 0; glyph < glyphCount; glyph += 1) { for (glyph = 0; glyph < glyphCount; glyph += 1) {
LEGlyphID thisGlyph = glyphStorage[glyph]; LEGlyphID thisGlyph = glyphStorage[glyph];
// lookupSegment already range checked by lookupSegment() function.
const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success); const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success);
if (lookupSegment != NULL) { if (lookupSegment != NULL&& LE_SUCCESS(success)) {
TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph); TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
TTGlyphID lastGlyph = SWAPW(lookupSegment->lastGlyph);
le_int16 offset = SWAPW(lookupSegment->value); le_int16 offset = SWAPW(lookupSegment->value);
TTGlyphID thisGlyphId= LE_GET_GLYPH(thisGlyph);
if (offset != 0) { LEReferenceToArrayOf<TTGlyphID> glyphArray(subtableHeader, success, offset, lastGlyph - firstGlyph + 1);
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader.getAliasTODO() + offset); if (offset != 0 && thisGlyphId <= lastGlyph && thisGlyphId >= firstGlyph && LE_SUCCESS(success) ) {
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]); TTGlyphID newGlyph = SWAPW(glyphArray[thisGlyphId]);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
} }
} }
......
...@@ -75,7 +75,7 @@ le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePo ...@@ -75,7 +75,7 @@ le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePo
} }
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
valueRecord.adjustPosition(SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance); valueRecord.adjustPosition(SWAPW(valueFormat), base, *glyphIterator, fontInstance, success);
return 1; return 1;
} }
...@@ -92,7 +92,7 @@ le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePo ...@@ -92,7 +92,7 @@ le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePo
} }
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance); valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), base, *glyphIterator, fontInstance, success);
return 1; return 1;
} }
......
...@@ -76,7 +76,7 @@ le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleS ...@@ -76,7 +76,7 @@ le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleS
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID); TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) { if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
glyphIterator->setCurrGlyphID(substitute); glyphIterator->setCurrGlyphID(substitute);
} }
...@@ -97,7 +97,7 @@ le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleS ...@@ -97,7 +97,7 @@ le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleS
if (coverageIndex >= 0) { if (coverageIndex >= 0) {
TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]); TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) { if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
glyphIterator->setCurrGlyphID(substitute); glyphIterator->setCurrGlyphID(substitute);
} }
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
*/ */
#ifndef __TIBETANREORDERING_H #ifndef __TIBETANREORDERING_H
#define __TIBETANORDERING_H #define __TIBETANREORDERING_H
/** /**
* \file * \file
......
...@@ -59,8 +59,8 @@ le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, Val ...@@ -59,8 +59,8 @@ le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, Val
return SWAPW(value); return SWAPW(value);
} }
void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void ValueRecord::adjustPosition(ValueFormat valueFormat, const LETableReference& base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const const LEFontInstance *fontInstance, LEErrorCode &success) const
{ {
float xPlacementAdjustment = 0; float xPlacementAdjustment = 0;
float yPlacementAdjustment = 0; float yPlacementAdjustment = 0;
...@@ -118,8 +118,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -118,8 +118,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice); Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj); xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -129,8 +129,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -129,8 +129,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice); Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj); yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
...@@ -140,8 +140,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -140,8 +140,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice); Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj); xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -151,10 +151,10 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -151,10 +151,10 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice); Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj); yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
} }
} }
...@@ -163,8 +163,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp ...@@ -163,8 +163,8 @@ void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, Glyp
xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment); xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
} }
void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const LETableReference& base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const const LEFontInstance *fontInstance, LEErrorCode &success) const
{ {
float xPlacementAdjustment = 0; float xPlacementAdjustment = 0;
float yPlacementAdjustment = 0; float yPlacementAdjustment = 0;
...@@ -222,8 +222,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -222,8 +222,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj); xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -233,8 +233,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -233,8 +233,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj); yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
...@@ -244,8 +244,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -244,8 +244,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 xAdj = dt->getAdjustment(xppem); le_int16 xAdj = dt->getAdjustment(dt, xppem, success);
xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj); xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
} }
...@@ -255,8 +255,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const ...@@ -255,8 +255,8 @@ void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const
Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice); Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice);
if (dtOffset != 0) { if (dtOffset != 0) {
const DeviceTable *dt = (const DeviceTable *) (base + dtOffset); LEReferenceTo<DeviceTable> dt(base, success, dtOffset);
le_int16 yAdj = dt->getAdjustment(yppem); le_int16 yAdj = dt->getAdjustment(dt, yppem, success);
yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj); yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
} }
......
...@@ -53,10 +53,10 @@ struct ValueRecord ...@@ -53,10 +53,10 @@ struct ValueRecord
le_int16 getFieldValue(ValueFormat valueFormat, ValueRecordField field) const; le_int16 getFieldValue(ValueFormat valueFormat, ValueRecordField field) const;
le_int16 getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const; le_int16 getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const;
void adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void adjustPosition(ValueFormat valueFormat, const LETableReference &base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const; const LEFontInstance *fontInstance, LEErrorCode &success) const;
void adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator, void adjustPosition(le_int16 index, ValueFormat valueFormat, const LETableReference &base, GlyphIterator &glyphIterator,
const LEFontInstance *fontInstance) const; const LEFontInstance *fontInstance, LEErrorCode &success) const;
static le_int16 getSize(ValueFormat valueFormat); static le_int16 getSize(ValueFormat valueFormat);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册