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