src/share/native/sun/font/layout/ContextualSubstSubtables.cpp
Print this page
rev 663 : 6501644: sync LayoutEngine *code* structure to match ICU
Reviewed-by: prr, omajid
rev 664 : 6886358: layout code update
Reviewed-by: igor, prr, omajid
rev 665 : 8001031: Better font processing.
Reviewed-by: vadim, prr, mschoene, omajid
@@ -22,11 +22,10 @@
* questions.
*
*/
/*
- *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
*
*/
#include "LETypes.h"
@@ -37,10 +36,12 @@
#include "GlyphIterator.h"
#include "LookupProcessor.h"
#include "CoverageTables.h"
#include "LESwaps.h"
+U_NAMESPACE_BEGIN
+
/*
NOTE: This could be optimized somewhat by keeping track
of the previous sequenceIndex in the loop and doing next()
or prev() of the delta between that and the current
sequenceIndex instead of always resetting to the front.
@@ -49,22 +50,27 @@
const LookupProcessor *lookupProcessor,
const SubstitutionLookupRecord *substLookupRecordArray,
le_uint16 substCount,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
- le_int32 position)
+ le_int32 position,
+ LEErrorCode& success)
{
+ if (LE_FAILURE(success)) {
+ return;
+ }
+
GlyphIterator tempIterator(*glyphIterator);
- for (le_int16 subst = 0; subst < substCount; subst += 1) {
+ for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) {
le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex);
le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex);
tempIterator.setCurrStreamPosition(position);
tempIterator.next(sequenceIndex);
- lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance);
+ lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance, success);
}
}
le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, le_uint16 glyphCount,
GlyphIterator *glyphIterator, le_bool backtrack)
@@ -162,49 +168,58 @@
}
return TRUE;
}
-le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance) const
+le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode& success) const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
switch(SWAPW(subtableFormat))
{
case 0:
return 0;
case 1:
{
const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this;
-
- return subtable->process(lookupProcessor, glyphIterator, fontInstance);
+ return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
}
case 2:
{
const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this;
-
- return subtable->process(lookupProcessor, glyphIterator, fontInstance);
+ return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
}
case 3:
{
const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this;
-
- return subtable->process(lookupProcessor, glyphIterator, fontInstance);
+ return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
}
default:
return 0;
}
}
-le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance) const
+le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode& success) const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
- le_int32 coverageIndex = getGlyphCoverage(glyph);
+ le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
le_uint16 srSetCount = SWAPW(subRuleSetCount);
if (coverageIndex < srSetCount) {
@@ -224,11 +239,11 @@
if (matchGlyphIDs(subRuleTable->inputGlyphArray, matchCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount];
- applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position);
+ applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return matchCount + 1;
}
glyphIterator->setCurrStreamPosition(position);
@@ -239,15 +254,21 @@
}
return 0;
}
-le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance) const
+le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode& success) const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
- le_int32 coverageIndex = getGlyphCoverage(glyph);
+ le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
const ClassDefinitionTable *classDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset));
le_uint16 scSetCount = SWAPW(subClassSetCount);
@@ -270,11 +291,11 @@
if (matchGlyphClasses(subClassRuleTable->classArray, matchCount, glyphIterator, classDefinitionTable)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount];
- applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position);
+ applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return matchCount + 1;
}
glyphIterator->setCurrStreamPosition(position);
@@ -285,13 +306,19 @@
}
return 0;
}
-le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance)const
+le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode& success)const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
le_uint16 gCount = SWAPW(glyphCount);
le_uint16 subCount = SWAPW(substCount);
le_int32 position = glyphIterator->getCurrStreamPosition();
// Back up the glyph iterator so that we
@@ -302,47 +329,50 @@
if (ContextualSubstitutionBase::matchGlyphCoverages(coverageTableOffsetArray, gCount, glyphIterator, (const char *) this)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount];
- ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position);
+ ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success);
return gCount + 1;
}
glyphIterator->setCurrStreamPosition(position);
return 0;
}
-le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance) const
+le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode& success) const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
switch(SWAPW(subtableFormat))
{
case 0:
return 0;
case 1:
{
const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this;
-
- return subtable->process(lookupProcessor, glyphIterator, fontInstance);
+ return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
}
case 2:
{
const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this;
-
- return subtable->process(lookupProcessor, glyphIterator, fontInstance);
+ return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
}
case 3:
{
const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this;
-
- return subtable->process(lookupProcessor, glyphIterator, fontInstance);
+ return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
}
default:
return 0;
}
@@ -352,15 +382,21 @@
// the Visual Studio .NET 2003 compiler on the calls to the
// GlyphIterator constructor. It somehow can't decide if
// emptyFeatureList matches an le_uint32 or an le_uint16...
static const FeatureMask emptyFeatureList = 0x00000000UL;
-le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance) const
+le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode& success) const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
- le_int32 coverageIndex = getGlyphCoverage(glyph);
+ le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
le_uint16 srSetCount = SWAPW(chainSubRuleSetCount);
if (coverageIndex < srSetCount) {
@@ -402,11 +438,11 @@
if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1];
- applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position);
+ applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return inputGlyphCount + 1;
}
glyphIterator->setCurrStreamPosition(position);
@@ -417,15 +453,21 @@
}
return 0;
}
-le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance) const
+le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode& success) const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
- le_int32 coverageIndex = getGlyphCoverage(glyph);
+ le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
if (coverageIndex >= 0) {
const ClassDefinitionTable *backtrackClassDefinitionTable =
(const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset));
const ClassDefinitionTable *inputClassDefinitionTable =
@@ -476,11 +518,11 @@
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1];
- applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position);
+ applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return inputGlyphCount + 1;
}
glyphIterator->setCurrStreamPosition(position);
@@ -491,13 +533,19 @@
}
return 0;
}
-le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
- const LEFontInstance *fontInstance) const
+le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
+ GlyphIterator *glyphIterator,
+ const LEFontInstance *fontInstance,
+ LEErrorCode & success) const
{
+ if (LE_FAILURE(success)) {
+ return 0;
+ }
+
le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]);
const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1];
const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]);
const Offset *lookaheadCoverageTableOffsetArray = &inputCoverageTableOffsetArray[inputGlyphCount + 1];
@@ -531,14 +579,16 @@
if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray,
inputGlyphCount, glyphIterator, (const char *) this)) {
const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1];
- ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position);
+ ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return inputGlyphCount;
}
glyphIterator->setCurrStreamPosition(position);
return 0;
}
+
+U_NAMESPACE_END