提交 0fd0c1f7 编写于 作者: S srl

6886358: layout code update

Reviewed-by: igor, prr
上级 321e8299
......@@ -68,8 +68,7 @@ FILES_cpp_shared = \
GlyphPositioningTables.cpp \
GlyphSubstLookupProc.cpp \
GlyphSubstitutionTables.cpp \
HebrewLigatureData.cpp \
HebrewShaping.cpp \
HangulLayoutEngine.cpp \
IndicClassTables.cpp \
IndicReordering.cpp \
KernTable.cpp \
......@@ -95,6 +94,8 @@ FILES_cpp_shared = \
SubstitutionLookups.cpp \
ThaiShaping.cpp \
ThaiStateTables.cpp \
TibetanLayoutEngine.cpp \
TibetanReordering.cpp \
ValueRecords.cpp \
ArabicLayoutEngine.cpp \
ArabicShaping.cpp \
......
......@@ -276,6 +276,18 @@ public final class FontUtilities {
// 0E00 - 0E7F if Thai, assume shaping for vowel, tone marks
return true;
}
else if (code < 0x0f00) {
return false;
}
else if (code <= 0x0fff) { // U+0F00 - U+0FFF Tibetan
return true;
}
else if (code < 0x1100) {
return false;
}
else if (code < 0x11ff) { // U+1100 - U+11FF Old Hangul
return true;
}
else if (code < 0x1780) {
return false;
}
......
......@@ -59,16 +59,16 @@ le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable)
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
}
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
......@@ -151,8 +151,8 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
}
}
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
......
......@@ -66,6 +66,7 @@ public:
* @param scriptCode - the script
* @param langaugeCode - the language
* @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
*
* @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine
......@@ -74,7 +75,7 @@ public:
* @internal
*/
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable);
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known
......@@ -83,6 +84,7 @@ public:
* @param fontInstance - the font
* @param scriptCode - the script
* @param langaugeCode - the language
* @param success - set to an error code if the operation fails
*
* @see OpenTypeLayoutEngine
* @see ScriptAndLanguageTags.h for script and language codes
......@@ -90,7 +92,7 @@ public:
* @internal
*/
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags);
le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
......@@ -184,6 +186,7 @@ public:
* @param fontInstance - the font
* @param scriptCode - the script
* @param languageCode - the language
* @param success - set to an error code if the operation fails
*
* @see LEFontInstance
* @see ScriptAndLanguageTags.h for script and language codes
......@@ -191,7 +194,7 @@ public:
* @internal
*/
UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags);
le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
......
......@@ -104,6 +104,7 @@ ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
#define markFeatureMask 0x00040000UL
#define mkmkFeatureMask 0x00020000UL
#define NO_FEATURES 0
#define ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask)
#define SHAPE_MASK 0xF0000000UL
......@@ -198,7 +199,11 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
LEUnicode c = chars[in];
ShapeType t = getShapeType(c);
if (t == ST_NOSHAPE_NONE) {
glyphStorage.setAuxData(out, NO_FEATURES, success);
} else {
glyphStorage.setAuxData(out, ISOL_FEATURES, success);
}
if ((t & MASK_TRANSPARENT) != 0) {
continue;
......
......@@ -38,7 +38,7 @@ U_NAMESPACE_BEGIN
class LEGlyphStorage;
class CanonShaping /* not : public UObject because all members are static */
class U_LAYOUT_API CanonShaping /* not : public UObject because all members are static */
{
public:
static const le_uint8 glyphSubstitutionTable[];
......
......@@ -93,7 +93,7 @@ le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const
TTGlyphID firstGlyph = SWAPW(startGlyph);
TTGlyphID lastGlyph = firstGlyph + SWAPW(glyphCount);
if (ttGlyphID > firstGlyph && ttGlyphID < lastGlyph) {
if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
return SWAPW(classValueArray[ttGlyphID - firstGlyph]);
}
......
......@@ -52,18 +52,23 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
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);
}
}
......@@ -165,9 +170,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
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:
......@@ -176,22 +187,19 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
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:
......@@ -199,9 +207,15 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
}
}
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);
......@@ -227,7 +241,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
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;
}
......@@ -242,9 +256,15 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
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);
......@@ -273,7 +293,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
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;
}
......@@ -288,9 +308,15 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
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();
......@@ -305,7 +331,7 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
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;
}
......@@ -315,9 +341,15 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
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:
......@@ -326,22 +358,19 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
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:
......@@ -355,9 +384,15 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
// 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);
......@@ -405,7 +440,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
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;
}
......@@ -420,9 +455,15 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
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);
......@@ -479,7 +520,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
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;
}
......@@ -494,9 +535,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
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];
......@@ -534,7 +581,7 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
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;
}
......
......@@ -72,12 +72,13 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
le_uint16 substCount,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
le_int32 position);
le_int32 position,
LEErrorCode& success);
};
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase
{
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
......@@ -85,7 +86,7 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint16 subRuleSetCount;
Offset subRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct SubRuleSetTable
......@@ -110,7 +111,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint16 subClassSetCount;
Offset subClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct SubClassSetTable
......@@ -140,12 +141,12 @@ struct ContextualSubstitutionFormat3Subtable
Offset coverageTableOffsetArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
{
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
......@@ -153,7 +154,7 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint16 chainSubRuleSetCount;
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ChainSubRuleSetTable
......@@ -184,7 +185,7 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint16 chainSubClassSetCount;
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
struct ChainSubClassSetTable
......@@ -222,7 +223,7 @@ struct ChainingContextualSubstitutionFormat3Subtable
//le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
U_NAMESPACE_END
......
......@@ -73,6 +73,10 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
le_uint16 probe = power;
le_uint16 index = 0;
if (count == 0) {
return -1;
}
if (SWAPW(glyphArray[extra]) <= ttGlyphID) {
index = extra;
}
......
......@@ -59,6 +59,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor);
glyphIterator->setCursiveEntryPoint(entryAnchor);
} else {
//glyphIterator->clearCursiveEntryPoint();
}
if (exitOffset != 0) {
......@@ -66,6 +68,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor);
glyphIterator->setCursiveExitPoint(exitAnchor);
} else {
//glyphIterator->clearCursiveExitPoint();
}
return 1;
......
......@@ -41,13 +41,15 @@ const le_uint16 DeviceTable::fieldMasks[] = {0x0003, 0x000F, 0x00FF};
const le_uint16 DeviceTable::fieldSignBits[] = {0x0002, 0x0008, 0x0080};
const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8};
#define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits)
le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
{
le_uint16 start = SWAPW(startSize);
le_uint16 format = SWAPW(deltaFormat) - 1;
le_int16 result = 0;
if (ppem >= start && ppem <= SWAPW(endSize)) {
if (ppem >= start && ppem <= SWAPW(endSize) && format < FORMAT_COUNT) {
le_uint16 sizeIndex = ppem - start;
le_uint16 bits = fieldBits[format];
le_uint16 count = 16 / bits;
......
......@@ -40,18 +40,24 @@
U_NAMESPACE_BEGIN
// read a 32-bit value that might only be 16-bit-aligned in memory
#define READ_LONG(code) (le_uint32)((SWAPW(*(le_uint16*)&code) << 16) + SWAPW(*(((le_uint16*)&code) + 1)))
// FIXME: should look at the format too... maybe have a sub-class for it?
le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
}
le_uint16 elt = SWAPW(extensionLookupType);
if (elt != lookupType) {
le_uint32 extOffset = SWAPL(extensionOffset);
le_uint32 extOffset = READ_LONG(extensionOffset);
LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset);
return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance);
return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
}
return 0;
......
......@@ -53,7 +53,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable
le_uint32 extensionOffset;
le_uint32 process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
};
U_NAMESPACE_END
......
......@@ -33,7 +33,7 @@
#include "LETypes.h"
#include "OpenTypeUtilities.h"
#include "OpenTypeTables.h"
#include "Features.h"
#include "ICUFeatures.h"
#include "LESwaps.h"
U_NAMESPACE_BEGIN
......
......@@ -41,8 +41,8 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine)
GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable)
: LayoutEngine(fontInstance, scriptCode, languageCode, 0), fMorphTable(morphTable)
GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable)
{
// nothing else to do?
}
......
......@@ -67,13 +67,14 @@ public:
* @param scriptCode - the script
* @param langaugeCode - the language
* @param morphTable - the 'mort' table
* @param success - set to an error code if the operation fails
*
* @see LayoutEngine::layoutEngineFactory
* @see ScriptAndLangaugeTags.h for script and language codes
*
* @internal
*/
GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable);
GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
......
......@@ -44,7 +44,7 @@ GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjus
FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
: direction(1), position(-1), nextLimit(-1), prevLimit(-1),
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask),
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
{
......@@ -78,6 +78,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that)
destIndex = that.destIndex;
lookupFlags = that.lookupFlags;
featureMask = that.featureMask;
glyphGroup = that.glyphGroup;
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
}
......@@ -95,6 +96,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask)
destIndex = that.destIndex;
lookupFlags = that.lookupFlags;
featureMask = newFeatureMask;
glyphGroup = 0;
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
}
......@@ -112,6 +114,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
destIndex = that.destIndex;
lookupFlags = newLookupFlags;
featureMask = that.featureMask;
glyphGroup = that.glyphGroup;
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
}
......@@ -125,12 +128,13 @@ void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask)
{
position = prevLimit;
featureMask = newFeatureMask;
glyphGroup = 0;
lookupFlags = newLookupFlags;
}
LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count)
LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success)
{
return glyphStorage.insertGlyphs(position, count);
return glyphStorage.insertGlyphs(position, count, success);
}
le_int32 GlyphIterator::applyInsertions()
......@@ -299,6 +303,36 @@ void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float
glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
}
void GlyphIterator::clearCursiveEntryPoint()
{
if (direction < 0) {
if (position <= nextLimit || position >= prevLimit) {
return;
}
} else {
if (position <= prevLimit || position >= nextLimit) {
return;
}
}
glyphPositionAdjustments->clearEntryPoint(position);
}
void GlyphIterator::clearCursiveExitPoint()
{
if (direction < 0) {
if (position <= nextLimit || position >= prevLimit) {
return;
}
} else {
if (position <= prevLimit || position >= nextLimit) {
return;
}
}
glyphPositionAdjustments->clearExitPoint(position);
}
void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
{
if (direction < 0) {
......@@ -391,7 +425,7 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const
}
}
le_bool GlyphIterator::hasFeatureTag() const
le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const
{
if (featureMask == 0) {
return TRUE;
......@@ -400,14 +434,18 @@ le_bool GlyphIterator::hasFeatureTag() const
LEErrorCode success = LE_NO_ERROR;
FeatureMask fm = glyphStorage.getAuxData(position, success);
return (fm & featureMask) != 0;
return ((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup);
}
le_bool GlyphIterator::findFeatureTag()
{
//glyphGroup = 0;
while (nextInternal()) {
if (hasFeatureTag()) {
prevInternal();
if (hasFeatureTag(FALSE)) {
LEErrorCode success = LE_NO_ERROR;
glyphGroup = (glyphStorage.getAuxData(position, success) & LE_GLYPH_GROUP_MASK);
return TRUE;
}
}
......@@ -435,7 +473,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta)
le_bool GlyphIterator::next(le_uint32 delta)
{
return nextInternal(delta) && hasFeatureTag();
return nextInternal(delta) && hasFeatureTag(TRUE);
}
le_bool GlyphIterator::prevInternal(le_uint32 delta)
......@@ -457,7 +495,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta)
le_bool GlyphIterator::prev(le_uint32 delta)
{
return prevInternal(delta) && hasFeatureTag();
return prevInternal(delta) && hasFeatureTag(TRUE);
}
le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
......
......@@ -88,16 +88,18 @@ public:
void setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
float xAdvanceAdjust, float yAdvanceAdjust);
void clearCursiveEntryPoint();
void clearCursiveExitPoint();
void setCursiveEntryPoint(LEPoint &entryPoint);
void setCursiveExitPoint(LEPoint &exitPoint);
void setCursiveGlyph();
LEGlyphID *insertGlyphs(le_int32 count);
LEGlyphID *insertGlyphs(le_int32 count, LEErrorCode& success);
le_int32 applyInsertions();
private:
le_bool filterGlyph(le_uint32 index) const;
le_bool hasFeatureTag() const;
le_bool hasFeatureTag(le_bool matchGroup) const;
le_bool nextInternal(le_uint32 delta = 1);
le_bool prevInternal(le_uint32 delta = 1);
......@@ -113,6 +115,7 @@ private:
le_int32 destIndex;
le_uint16 lookupFlags;
FeatureMask featureMask;
le_int32 glyphGroup;
const GlyphClassDefinitionTable *glyphClassDefinitionTable;
const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable;
......
......@@ -71,6 +71,20 @@ const LEPoint *GlyphPositionAdjustments::getExitPoint(le_int32 index, LEPoint &e
return fEntryExitPoints[index].getExitPoint(exitPoint);
}
void GlyphPositionAdjustments::clearEntryPoint(le_int32 index)
{
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
fEntryExitPoints[index].clearEntryPoint();
}
void GlyphPositionAdjustments::clearExitPoint(le_int32 index)
{
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
fEntryExitPoints[index].clearExitPoint();
}
void GlyphPositionAdjustments::setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
{
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
......@@ -152,7 +166,12 @@ void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage &glyphStor
lastExitGlyphID = glyphID;
} else {
if (baselineIsLogicalEnd(i) && firstExitPoint >= 0 && lastExitPoint >= 0) {
le_int32 limit = lastExitPoint + dir;
le_int32 limit = lastExitPoint /*+ dir*/;
LEPoint dummyAnchor;
if (getEntryPoint(i, dummyAnchor) != NULL) {
limit += dir;
}
for (le_int32 j = firstExitPoint; j != limit; j += dir) {
if (isCursiveGlyph(j)) {
......
......@@ -97,6 +97,8 @@ private:
LEPoint *getEntryPoint(LEPoint &entryPoint) const;
LEPoint *getExitPoint(LEPoint &exitPoint) const;
inline void clearEntryPoint();
inline void clearExitPoint();
inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);
......@@ -151,6 +153,8 @@ public:
inline void adjustXAdvance(le_int32 index, float xAdjustment);
inline void adjustYAdvance(le_int32 index, float yAdjustment);
void clearEntryPoint(le_int32 index);
void clearExitPoint(le_int32 index);
void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);
......@@ -266,6 +270,16 @@ inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd()
return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
}
inline void GlyphPositionAdjustments::EntryExitPoint::clearEntryPoint()
{
fFlags &= ~EEF_HAS_ENTRY_POINT;
}
inline void GlyphPositionAdjustments::EntryExitPoint::clearExitPoint()
{
fFlags &= ~EEF_HAS_EXIT_POINT;
}
inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
{
if (baselineIsLogicalEnd) {
......
......@@ -43,12 +43,19 @@ U_NAMESPACE_BEGIN
void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
{
GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder);
if (LE_FAILURE(success)) {
return;
}
processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance);
GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
if (LE_FAILURE(success)) {
return;
}
processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance, success);
glyphPositionAdjustments->applyCursiveAdjustments(glyphStorage, rightToLeft, fontInstance);
}
......
......@@ -53,7 +53,7 @@ struct GlyphPositioningTableHeader : public GlyphLookupTableHeader
{
void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
};
......
......@@ -31,7 +31,7 @@
#include "LETypes.h"
#include "LEFontInstance.h"
#include "OpenTypeTables.h"
#include "Features.h"
#include "ICUFeatures.h"
#include "Lookups.h"
#include "ScriptAndLanguage.h"
#include "GlyphDefinitionTables.h"
......@@ -58,13 +58,24 @@ typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubt
GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
const GlyphPositioningTableHeader *glyphPositioningTableHeader,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder)
LETag scriptTag,
LETag languageTag,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success)
: LookupProcessor(
(char *) glyphPositioningTableHeader,
SWAPW(glyphPositioningTableHeader->scriptListOffset),
SWAPW(glyphPositioningTableHeader->featureListOffset),
SWAPW(glyphPositioningTableHeader->lookupListOffset),
scriptTag, languageTag, featureMap, featureMapCount, featureOrder)
scriptTag,
languageTag,
featureMap,
featureMapCount,
featureOrder,
success
)
{
// anything?
}
......@@ -75,8 +86,13 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor()
le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
}
le_uint32 delta = 0;
switch(lookupType)
......@@ -136,7 +152,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
{
const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
}
......@@ -144,7 +160,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
{
const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
}
......@@ -152,7 +168,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
{
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
delta = subtable->process(this, lookupType, glyphIterator, fontInstance);
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break;
}
......
......@@ -40,7 +40,7 @@
#include "LEFontInstance.h"
#include "OpenTypeTables.h"
#include "Lookups.h"
#include "Features.h"
#include "ICUFeatures.h"
#include "GlyphDefinitionTables.h"
#include "GlyphPositioningTables.h"
#include "GlyphIterator.h"
......@@ -52,12 +52,17 @@ class GlyphPositioningLookupProcessor : public LookupProcessor
{
public:
GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder);
LETag scriptTag,
LETag languageTag,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success);
virtual ~GlyphPositioningLookupProcessor();
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const;
const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected:
GlyphPositioningLookupProcessor();
......
......@@ -33,7 +33,7 @@
#include "LEGlyphFilter.h"
#include "LEFontInstance.h"
#include "OpenTypeTables.h"
#include "Features.h"
#include "ICUFeatures.h"
#include "Lookups.h"
#include "ScriptAndLanguage.h"
#include "GlyphDefinitionTables.h"
......@@ -52,13 +52,19 @@ U_NAMESPACE_BEGIN
GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder)
LETag scriptTag,
LETag languageTag,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success)
: LookupProcessor(
(char *) glyphSubstitutionTableHeader,
SWAPW(glyphSubstitutionTableHeader->scriptListOffset),
SWAPW(glyphSubstitutionTableHeader->featureListOffset),
SWAPW(glyphSubstitutionTableHeader->lookupListOffset),
scriptTag, languageTag, featureMap, featureMapCount, featureOrder), fFilter(filter)
scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success), fFilter(filter)
{
// anything?
}
......@@ -68,8 +74,12 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor()
}
le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
}
le_uint32 delta = 0;
switch(lookupType)
......@@ -89,7 +99,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{
const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable;
delta = subtable->process(glyphIterator, fFilter);
delta = subtable->process(glyphIterator, success, fFilter);
break;
}
......@@ -113,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{
const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
}
......@@ -121,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{
const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance);
delta = subtable->process(this, glyphIterator, fontInstance, success);
break;
}
......@@ -129,7 +139,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
delta = subtable->process(this, lookupType, glyphIterator, fontInstance);
delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break;
}
......
......@@ -41,7 +41,7 @@
#include "LEFontInstance.h"
#include "OpenTypeTables.h"
#include "Lookups.h"
#include "Features.h"
#include "ICUFeatures.h"
#include "GlyphDefinitionTables.h"
#include "GlyphSubstitutionTables.h"
#include "GlyphIterator.h"
......@@ -53,12 +53,18 @@ class GlyphSubstitutionLookupProcessor : public LookupProcessor
{
public:
GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder);
LETag scriptTag,
LETag languageTag,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success);
virtual ~GlyphSubstitutionLookupProcessor();
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const;
const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected:
GlyphSubstitutionLookupProcessor();
......
......@@ -42,13 +42,23 @@
U_NAMESPACE_BEGIN
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag,
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage,
le_bool rightToLeft,
LETag scriptTag,
LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode &success) const
{
GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder);
if (LE_FAILURE(success)) {
return 0;
}
return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL);
GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success);
}
U_NAMESPACE_END
......@@ -50,9 +50,16 @@ struct GlyphDefinitionTableHeader;
struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
{
le_int32 process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEGlyphFilter *filter,
const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
le_int32 process(LEGlyphStorage &glyphStorage,
le_bool rightToLeft,
LETag scriptTag,
LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode &success) const;
};
enum GlyphSubstitutionSubtableTypes
......
......@@ -26,7 +26,7 @@
/*
* HanLayoutEngine.cpp: OpenType processing for Han fonts.
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved.
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved.
*/
#include "LETypes.h"
......@@ -64,8 +64,8 @@ static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
#define features (loclFeatureMask)
HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable)
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = featureMap;
fFeatureMapCount = featureMapCount;
......
......@@ -27,7 +27,7 @@
/*
* HanLayoutEngine.h: OpenType processing for Han fonts.
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved.
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved.
*/
#ifndef __HANLAYOUTENGINE_H
......@@ -64,6 +64,7 @@ public:
* @param scriptCode - the script
* @param langaugeCode - the language
* @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
*
* @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine
......@@ -72,7 +73,7 @@ public:
* @internal
*/
HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable);
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTablem, LEErrorCode &success);
/**
......
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* HangulLayoutEngine.cpp: OpenType processing for Han fonts.
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved.
*/
#include "LETypes.h"
#include "LEScripts.h"
#include "LELanguages.h"
#include "LayoutEngine.h"
#include "OpenTypeLayoutEngine.h"
#include "HangulLayoutEngine.h"
#include "ScriptAndLanguageTags.h"
#include "LEGlyphStorage.h"
#include "OpenTypeTables.h"
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HangulOpenTypeLayoutEngine)
#define FEATURE_MAP(name) {name ## FeatureTag, name ## FeatureMask}
#define LJMO_FIRST 0x1100
#define LJMO_LAST 0x1159
#define LJMO_FILL 0x115F
#define LJMO_COUNT 19
#define VJMO_FIRST 0x1161
#define VJMO_LAST 0x11A2
#define VJMO_FILL 0x1160
#define VJMO_COUNT 21
#define TJMO_FIRST 0x11A7
#define TJMO_LAST 0x11F9
#define TJMO_COUNT 28
#define HSYL_FIRST 0xAC00
#define HSYL_COUNT 11172
#define HSYL_LVCNT (VJMO_COUNT * TJMO_COUNT)
// Character classes
enum
{
CC_L = 0,
CC_V,
CC_T,
CC_LV,
CC_LVT,
CC_X,
CC_COUNT
};
// Action flags
#define AF_L 1
#define AF_V 2
#define AF_T 4
// Actions
#define a_N 0
#define a_L (AF_L)
#define a_V (AF_V)
#define a_T (AF_T)
#define a_VT (AF_V | AF_T)
#define a_LV (AF_L | AF_V)
#define a_LVT (AF_L | AF_V | AF_T)
typedef struct
{
le_int32 newState;
le_int32 actionFlags;
} StateTransition;
static const StateTransition stateTable[][CC_COUNT] =
{
// L V T LV LVT X
{ {1, a_L}, {2, a_LV}, {3, a_LVT}, {2, a_LV}, {3, a_LVT}, {4, a_T}}, // 0 - start
{ {1, a_L}, {2, a_V}, {3, a_VT}, {2, a_LV}, {3, a_LVT}, {-1, a_V}}, // 1 - L+
{{-1, a_N}, {2, a_V}, {3, a_T}, {-1, a_N}, {-1, a_N}, {-1, a_N}}, // 2 - L+V+
{{-1, a_N}, {-1, a_N}, {3, a_T}, {-1, a_N}, {-1, a_N}, {-1, a_N}}, // 3 - L+V+T*
{{-1, a_N}, {-1, a_N}, {-1, a_N}, {-1, a_N}, {-1, a_N}, {4, a_T}} // 4 - X+
};
#define ccmpFeatureTag LE_CCMP_FEATURE_TAG
#define ljmoFeatureTag LE_LJMO_FEATURE_TAG
#define vjmoFeatureTag LE_VJMO_FEATURE_TAG
#define tjmoFeatureTag LE_TJMO_FEATURE_TAG
#define ccmpFeatureMask 0x80000000UL
#define ljmoFeatureMask 0x40000000UL
#define vjmoFeatureMask 0x20000000UL
#define tjmoFeatureMask 0x10000000UL
static const FeatureMap featureMap[] =
{
{ccmpFeatureTag, ccmpFeatureMask},
{ljmoFeatureTag, ljmoFeatureMask},
{vjmoFeatureTag, vjmoFeatureMask},
{tjmoFeatureTag, tjmoFeatureMask}
};
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
#define nullFeatures 0
#define ljmoFeatures (ccmpFeatureMask | ljmoFeatureMask)
#define vjmoFeatures (ccmpFeatureMask | vjmoFeatureMask | ljmoFeatureMask | tjmoFeatureMask)
#define tjmoFeatures (ccmpFeatureMask | tjmoFeatureMask | ljmoFeatureMask | vjmoFeatureMask)
static le_int32 compose(LEUnicode lead, LEUnicode vowel, LEUnicode trail, LEUnicode &syllable)
{
le_int32 lIndex = lead - LJMO_FIRST;
le_int32 vIndex = vowel - VJMO_FIRST;
le_int32 tIndex = trail - TJMO_FIRST;
le_int32 result = 3;
if ((lIndex < 0 || lIndex >= LJMO_COUNT ) || (vIndex < 0 || vIndex >= VJMO_COUNT)) {
return 0;
}
if (tIndex <= 0 || tIndex >= TJMO_COUNT) {
tIndex = 0;
result = 2;
}
syllable = (LEUnicode) ((lIndex * VJMO_COUNT + vIndex) * TJMO_COUNT + tIndex + HSYL_FIRST);
return result;
}
static le_int32 decompose(LEUnicode syllable, LEUnicode &lead, LEUnicode &vowel, LEUnicode &trail)
{
le_int32 sIndex = syllable - HSYL_FIRST;
if (sIndex < 0 || sIndex >= HSYL_COUNT) {
return 0;
}
lead = LJMO_FIRST + (sIndex / HSYL_LVCNT);
vowel = VJMO_FIRST + (sIndex % HSYL_LVCNT) / TJMO_COUNT;
trail = TJMO_FIRST + (sIndex % TJMO_COUNT);
if (trail == TJMO_FIRST) {
return 2;
}
return 3;
}
static le_int32 getCharClass(LEUnicode ch, LEUnicode &lead, LEUnicode &vowel, LEUnicode &trail)
{
lead = LJMO_FILL;
vowel = VJMO_FILL;
trail = TJMO_FIRST;
if (ch >= LJMO_FIRST && ch <= LJMO_LAST) {
lead = ch;
return CC_L;
}
if (ch >= VJMO_FIRST && ch <= VJMO_LAST) {
vowel = ch;
return CC_V;
}
if (ch > TJMO_FIRST && ch <= TJMO_LAST) {
trail = ch;
return CC_T;
}
le_int32 c = decompose(ch, lead, vowel, trail);
if (c == 2) {
return CC_LV;
}
if (c == 3) {
return CC_LVT;
}
trail = ch;
return CC_X;
}
HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success)
{
fFeatureMap = featureMap;
fFeatureMapCount = featureMapCount;
fFeatureOrder = TRUE;
}
HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, success)
{
fFeatureMap = featureMap;
fFeatureMapCount = featureMapCount;
fFeatureOrder = TRUE;
}
HangulOpenTypeLayoutEngine::~HangulOpenTypeLayoutEngine()
{
// nothing to do
}
le_int32 HangulOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return 0;
}
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
success = LE_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
le_int32 worstCase = count * 3;
outChars = LE_NEW_ARRAY(LEUnicode, worstCase);
if (outChars == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success);
glyphStorage.allocateAuxData(success);
if (LE_FAILURE(success)) {
LE_DELETE_ARRAY(outChars);
return 0;
}
le_int32 outCharCount = 0;
le_int32 limit = offset + count;
le_int32 i = offset;
while (i < limit) {
le_int32 state = 0;
le_int32 inStart = i;
le_int32 outStart = outCharCount;
while( i < limit) {
LEUnicode lead = 0;
LEUnicode vowel = 0;
LEUnicode trail = 0;
le_int32 chClass = getCharClass(chars[i], lead, vowel, trail);
const StateTransition transition = stateTable[state][chClass];
if (chClass == CC_X) {
/* Any character of type X will be stored as a trail jamo */
if ((transition.actionFlags & AF_T) != 0) {
outChars[outCharCount] = trail;
glyphStorage.setCharIndex(outCharCount, i-offset, success);
glyphStorage.setAuxData(outCharCount++, nullFeatures, success);
}
} else {
/* Any Hangul will be fully decomposed. Output the decomposed characters. */
if ((transition.actionFlags & AF_L) != 0) {
outChars[outCharCount] = lead;
glyphStorage.setCharIndex(outCharCount, i-offset, success);
glyphStorage.setAuxData(outCharCount++, ljmoFeatures, success);
}
if ((transition.actionFlags & AF_V) != 0) {
outChars[outCharCount] = vowel;
glyphStorage.setCharIndex(outCharCount, i-offset, success);
glyphStorage.setAuxData(outCharCount++, vjmoFeatures, success);
}
if ((transition.actionFlags & AF_T) != 0) {
outChars[outCharCount] = trail;
glyphStorage.setCharIndex(outCharCount, i-offset, success);
glyphStorage.setAuxData(outCharCount++, tjmoFeatures, success);
}
}
state = transition.newState;
/* Negative next state means stop. */
if (state < 0) {
break;
}
i += 1;
}
le_int32 inLength = i - inStart;
le_int32 outLength = outCharCount - outStart;
/*
* See if the syllable can be composed into a single character. There are 5
* possible cases:
*
* Input Decomposed to Compose to
* LV L, V LV
* LVT L, V, T LVT
* L, V L, V LV, DEL
* LV, T L, V, T LVT, DEL
* L, V, T L, V, T LVT, DEL, DEL
*/
if ((inLength >= 1 && inLength <= 3) && (outLength == 2 || outLength == 3)) {
LEUnicode syllable = 0x0000;
LEUnicode lead = outChars[outStart];
LEUnicode vowel = outChars[outStart + 1];
LEUnicode trail = outLength == 3? outChars[outStart + 2] : TJMO_FIRST;
/*
* If the composition consumes the whole decomposed syllable,
* we can use it.
*/
if (compose(lead, vowel, trail, syllable) == outLength) {
outCharCount = outStart;
outChars[outCharCount] = syllable;
glyphStorage.setCharIndex(outCharCount, inStart-offset, success);
glyphStorage.setAuxData(outCharCount++, nullFeatures, success);
/*
* Replace the rest of the input characters with DEL.
*/
for(le_int32 d = inStart + 1; d < i; d += 1) {
outChars[outCharCount] = 0xFFFF;
glyphStorage.setCharIndex(outCharCount, d - offset, success);
glyphStorage.setAuxData(outCharCount++, nullFeatures, success);
}
}
}
}
glyphStorage.adoptGlyphCount(outCharCount);
return outCharCount;
}
U_NAMESPACE_END
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
#ifndef __HANGULAYOUTENGINE_H
#define __HANGULAYOUTENGINE_H
#include "LETypes.h"
#include "LEFontInstance.h"
#include "LEGlyphFilter.h"
#include "LayoutEngine.h"
#include "OpenTypeLayoutEngine.h"
#include "GlyphSubstitutionTables.h"
#include "GlyphDefinitionTables.h"
#include "GlyphPositioningTables.h"
U_NAMESPACE_BEGIN
class MPreFixups;
class LEGlyphStorage;
/**
* This class implements OpenType layout for Old Hangul OpenType fonts, as
* specified by Microsoft in "Creating and Supporting OpenType Fonts for
* The Korean Hangul Script" (http://www.microsoft.com/typography/otfntdev/hangulot/default.htm)
*
* This class overrides the characterProcessing method to do Hangul character processing.
* (See the MS spec. for more details)
*
* @internal
*/
class HangulOpenTypeLayoutEngine : public OpenTypeLayoutEngine
{
public:
/**
* This is the main constructor. It constructs an instance of HangulOpenTypeLayoutEngine for
* a particular font, script and language. It takes the GSUB table as a parameter since
* LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an
* Hangul OpenType font.
*
* @param fontInstance - the font
* @param scriptCode - the script
* @param langaugeCode - the language
* @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
*
* @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine
* @see ScriptAndLangaugeTags.h for script and language codes
*
* @internal
*/
HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known
* until after this constructor has been invoked.
*
* @param fontInstance - the font
* @param scriptCode - the script
* @param langaugeCode - the language
* @param success - set to an error code if the operation fails
*
* @see OpenTypeLayoutEngine
* @see ScriptAndLangaugeTags.h for script and language codes
*
* @internal
*/
HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
*
* @internal
*/
virtual ~HangulOpenTypeLayoutEngine();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @stable ICU 2.8
*/
virtual UClassID getDynamicClassID() const;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @stable ICU 2.8
*/
static UClassID getStaticClassID();
protected:
/**
* This method does Hangul OpenType character processing. It assigns the OpenType feature
* tags to the characters, and may compose a character sequence into a modern Hangul syllable,
* or decompose a modern Hangul syllable if it forms part of an old Hangul syllable.
*
* Input parameters:
* @param chars - the input character context
* @param offset - the index of the first character to process
* @param count - the number of characters to process
* @param max - the number of characters in the input context
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
* @param glyphStorage - the glyph storage object. The glyph and character index arrays will be set.
* the auxillary data array will be set to the feature tags.
*
* Output parameters:
* @param success - set to an error code if the operation fails
*
* @return the output character count
*
* @internal
*/
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
};
U_NAMESPACE_END
#endif
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
*
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
*
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* YOU REALLY KNOW WHAT YOU'RE DOING.
*
*/
#include "LETypes.h"
#include "HebrewShaping.h"
const le_uint8 HebrewShaping::glyphSubstitutionTable[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x1E, 0x00, 0x2C, 0x00, 0x01, 0x68, 0x65, 0x62, 0x72,
0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x6C, 0x69, 0x67, 0x61, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04,
0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x01, 0x62, 0x00, 0x16, 0x00, 0x32,
0x00, 0x4C, 0x00, 0x5E, 0x00, 0x68, 0x00, 0x72, 0x00, 0x7C, 0x00, 0x8E, 0x00, 0x98, 0x00, 0xA2,
0x00, 0xAC, 0x00, 0xB6, 0x00, 0xC8, 0x00, 0xD2, 0x00, 0xDC, 0x00, 0xE6, 0x00, 0xF0, 0x00, 0xFA,
0x01, 0x0C, 0x01, 0x16, 0x01, 0x20, 0x01, 0x2A, 0x01, 0x58, 0x00, 0x03, 0x00, 0x08, 0x00, 0x0E,
0x00, 0x14, 0xFB, 0x2E, 0x00, 0x02, 0x05, 0xB7, 0xFB, 0x2F, 0x00, 0x02, 0x05, 0xB8, 0xFB, 0x30,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0C, 0xFB, 0x31, 0x00, 0x02, 0x05, 0xBC,
0xFB, 0x4C, 0x00, 0x02, 0x05, 0xBF, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x32, 0x00, 0x02, 0x05, 0xBC,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x33, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x34,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0C, 0xFB, 0x4B, 0x00, 0x02, 0x05, 0xB9,
0xFB, 0x35, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x36, 0x00, 0x02, 0x05, 0xBC,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x38, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x39,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x3A, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x02,
0x00, 0x06, 0x00, 0x0C, 0xFB, 0x3B, 0x00, 0x02, 0x05, 0xBC, 0xFB, 0x4D, 0x00, 0x02, 0x05, 0xBF,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x3C, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x3E,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x40, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01,
0x00, 0x04, 0xFB, 0x41, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x43, 0x00, 0x02,
0x05, 0xBC, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0C, 0xFB, 0x44, 0x00, 0x02, 0x05, 0xBC, 0xFB, 0x4E,
0x00, 0x02, 0x05, 0xBF, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x46, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01,
0x00, 0x04, 0xFB, 0x47, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x48, 0x00, 0x02,
0x05, 0xBC, 0x00, 0x05, 0x00, 0x0C, 0x00, 0x14, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x28, 0xFB, 0x2C,
0x00, 0x03, 0x05, 0xBC, 0x05, 0xC1, 0xFB, 0x2D, 0x00, 0x03, 0x05, 0xBC, 0x05, 0xC2, 0xFB, 0x49,
0x00, 0x02, 0x05, 0xBC, 0xFB, 0x2A, 0x00, 0x02, 0x05, 0xC1, 0xFB, 0x2B, 0x00, 0x02, 0x05, 0xC2,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x4A, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x16, 0x05, 0xD0,
0x05, 0xD1, 0x05, 0xD2, 0x05, 0xD3, 0x05, 0xD4, 0x05, 0xD5, 0x05, 0xD6, 0x05, 0xD8, 0x05, 0xD9,
0x05, 0xDA, 0x05, 0xDB, 0x05, 0xDC, 0x05, 0xDE, 0x05, 0xE0, 0x05, 0xE1, 0x05, 0xE3, 0x05, 0xE4,
0x05, 0xE6, 0x05, 0xE7, 0x05, 0xE8, 0x05, 0xE9, 0x05, 0xEA
};
const le_uint8 HebrewShaping::glyphDefinitionTable[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x15,
0x05, 0x91, 0x05, 0xA1, 0x00, 0x03, 0x05, 0xA3, 0x05, 0xB9, 0x00, 0x03, 0x05, 0xBB, 0x05, 0xBD,
0x00, 0x03, 0x05, 0xBE, 0x05, 0xBE, 0x00, 0x01, 0x05, 0xBF, 0x05, 0xBF, 0x00, 0x03, 0x05, 0xC0,
0x05, 0xC0, 0x00, 0x01, 0x05, 0xC1, 0x05, 0xC2, 0x00, 0x03, 0x05, 0xC3, 0x05, 0xC3, 0x00, 0x01,
0x05, 0xC4, 0x05, 0xC4, 0x00, 0x03, 0x05, 0xD0, 0x05, 0xEA, 0x00, 0x01, 0x05, 0xF0, 0x05, 0xF2,
0x00, 0x02, 0x05, 0xF3, 0x05, 0xF4, 0x00, 0x01, 0xFB, 0x1E, 0xFB, 0x1E, 0x00, 0x03, 0xFB, 0x1F,
0xFB, 0x1F, 0x00, 0x02, 0xFB, 0x20, 0xFB, 0x36, 0x00, 0x01, 0xFB, 0x38, 0xFB, 0x3C, 0x00, 0x01,
0xFB, 0x3E, 0xFB, 0x3E, 0x00, 0x01, 0xFB, 0x40, 0xFB, 0x41, 0x00, 0x01, 0xFB, 0x43, 0xFB, 0x44,
0x00, 0x01, 0xFB, 0x46, 0xFB, 0x4E, 0x00, 0x01, 0xFB, 0x4F, 0xFB, 0x4F, 0x00, 0x02
};
......@@ -25,28 +25,45 @@
/*
*
* (C) Copyright IBM Corp. 1998, 1999, 2000 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
#ifndef __HEBREWSHAPING_H
#define __HEBREWSHAPING_H
#ifndef __ICUFEATURES_H
#define __ICUFEATURES_H
/**
* \file
* \internal
*/
#include "LETypes.h"
#include "OpenTypeTables.h"
class HebrewShaping
U_NAMESPACE_BEGIN
struct FeatureRecord
{
ATag featureTag;
Offset featureTableOffset;
};
struct FeatureTable
{
Offset featureParamsOffset;
le_uint16 lookupCount;
le_uint16 lookupListIndexArray[ANY_NUMBER];
};
struct FeatureListTable
{
public:
static void shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
le_bool rightToLeft, const LETag **tags);
le_uint16 featureCount;
FeatureRecord featureRecordArray[ANY_NUMBER];
static const le_uint8 glyphSubstitutionTable[];
static const le_uint8 glyphDefinitionTable[];
const FeatureTable *getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const;
private:
// forbid instantiation
HebrewShaping();
const FeatureTable *getFeatureTable(LETag featureTag) const;
};
U_NAMESPACE_END
#endif
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -73,6 +73,7 @@ U_NAMESPACE_BEGIN
#define _m2 (CC_SPLIT_VOWEL_PIECE_2 | CF_LENGTH_MARK)
#define _m3 (CC_SPLIT_VOWEL_PIECE_3 | CF_LENGTH_MARK)
#define _vr (CC_VIRAMA)
#define _al (CC_AL_LAKUNA)
// split matras
#define _s1 (_dv | _x1)
......@@ -90,6 +91,7 @@ U_NAMESPACE_BEGIN
// special forms... (Bengali RA?)
#define _bb (_ct | CF_BELOW_BASE)
#define _pb (_ct | CF_POST_BASE)
#define _fb (_ct | CF_PRE_BASE)
#define _vt (_bb | CF_VATTU)
#define _rv (_vt | CF_REPH)
#define _rp (_pb | CF_REPH)
......@@ -119,7 +121,7 @@ static const IndicClassTable::CharClass bengCharClasses[] =
_dr, _db, _db, _db, _db, _xx, _xx, _l1, _dl, _xx, _xx, _s1, _s2, _vr, _xx, _xx, // 09C0 - 09CF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _cn, // 09D0 - 09DF
_iv, _iv, _dv, _dv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 09E0 - 09EF
_ct, _ct, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 09F0 - 09FA
_rv, _ct, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 09F0 - 09FA
};
static const IndicClassTable::CharClass punjCharClasses[] =
......@@ -142,9 +144,22 @@ static const IndicClassTable::CharClass gujrCharClasses[] =
_rv, _xx, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _nu, _xx, _dr, _dl, // 0AB0 - 0ABF
_dr, _db, _db, _db, _db, _da, _xx, _da, _da, _dr, _xx, _dr, _dr, _vr, _xx, _xx, // 0AC0 - 0ACF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0AD0 - 0ADF
_iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0AE0 - 0AEF
_iv, _iv, _db, _db, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0AE0 - 0AEF
};
#if 1
static const IndicClassTable::CharClass oryaCharClasses[] =
{
_xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, /* 0B00 - 0B0F */
_iv, _xx, _xx, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _ct, _bb, /* 0B10 - 0B1F */
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _pb, /* 0B20 - 0B2F */
_rb, _xx, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _nu, _xx, _dr, _da, /* 0B30 - 0B3F */
_dr, _db, _db, _db, _xx, _xx, _xx, _dl, _s1, _xx, _xx, _s2, _s3, _vr, _xx, _xx, /* 0B40 - 0B4F */
_xx, _xx, _xx, _xx, _xx, _xx, _da, _dr, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _pb, /* 0B50 - 0B5F */
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0B60 - 0B6F */
_xx, _bb /* 0B70 - 0B71 */
};
#else
static const IndicClassTable::CharClass oryaCharClasses[] =
{
_xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, // 0B00 - 0B0F
......@@ -156,13 +171,14 @@ static const IndicClassTable::CharClass oryaCharClasses[] =
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0B60 - 0B6F
_xx, _ct // 0B70 - 0B71
};
#endif
static const IndicClassTable::CharClass tamlCharClasses[] =
{
_xx, _xx, _ma, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _iv, _iv, // 0B80 - 0B8F
_xx, _xx, _ma, _xx, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _iv, _iv, // 0B80 - 0B8F
_iv, _xx, _iv, _iv, _iv, _ct, _xx, _xx, _xx, _ct, _ct, _xx, _ct, _xx, _ct, _ct, // 0B90 - 0B9F
_xx, _xx, _xx, _ct, _ct, _xx, _xx, _xx, _ct, _ct, _ct, _xx, _xx, _xx, _ct, _ct, // 0BA0 - 0BAF
_ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0BB0 - 0BBF
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0BB0 - 0BBF
_da, _dr, _dr, _xx, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0BC0 - 0BCF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BD0 - 0BDF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BE0 - 0BEF
......@@ -175,7 +191,7 @@ static const IndicClassTable::CharClass teluCharClasses[] =
_xx, _mp, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C00 - 0C0F
_iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C10 - 0C1F
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0C20 - 0C2F
_bb, _ct, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F
_bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F
_da, _dr, _dr, _dr, _dr, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F
_xx, _xx, _xx, _xx, _xx, _da, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0C50 - 0C5F
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0C60 - 0C6F
......@@ -189,7 +205,7 @@ static const IndicClassTable::CharClass teluCharClasses[] =
// http://brahmi.sourceforge.net/docs/KannadaComputing.html
static const IndicClassTable::CharClass kndaCharClasses[] =
{
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, // 0C80 - 0C8F
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C80 - 0C8F
_iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C90 - 0C9F
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0CA0 - 0CAF
_rb, _ct, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _dr, _da, // 0CB0 - 0CBF
......@@ -203,9 +219,9 @@ static const IndicClassTable::CharClass kndaCharClasses[] =
static const IndicClassTable::CharClass mlymCharClasses[] =
{
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0D00 - 0D0F
_iv, _xx, _iv, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _bb, // 0D10 - 0D1F
_ct, _ct, _ct, _bb, _ct, _bb, _bb, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _pb, // 0D20 - 0D2F
_pb, _cn, _bb, _ct, _ct, _pb, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0D30 - 0D3F
_iv, _xx, _iv, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0D10 - 0D1F
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _pb, // 0D20 - 0D2F
_fb, _fb, _bb, _ct, _ct, _pb, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0D30 - 0D3F
_dr, _dr, _dr, _dr, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0D40 - 0D4F
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0D50 - 0D5F
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0D60 - 0D6F
......@@ -217,7 +233,7 @@ static const IndicClassTable::CharClass sinhCharClasses[] =
_iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _ct, _ct, _ct, _ct, _ct, _ct, // 0D90 - 0D9F
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0DA0 - 0DAF
_ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _xx, _xx, // 0DB0 - 0DBF
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _vr, _xx, _xx, _xx, _xx, _dr, // 0DC0 - 0DCF
_ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _al, _xx, _xx, _xx, _xx, _dr, // 0DC0 - 0DCF
_dr, _dr, _da, _da, _db, _xx, _db, _xx, _dr, _dl, _s1, _dl, _s2, _s3, _s4, _dr, // 0DD0 - 0DDF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0DE0 - 0DEF
_xx, _xx, _dr, _dr, _xx // 0DF0 - 0DF4
......@@ -248,17 +264,18 @@ static const SplitMatra sinhSplitTable[] = {{0x0DD9, 0x0DCA}, {0x0DD9, 0x0DCF},
// FIXME: post 'GSUB' reordering of MATRA_PRE's for Malayalam and Tamil
// FIXME: reformed Malayalam needs to reorder VATTU to before base glyph...
// FIXME: not sure passing ZWJ/ZWNJ is best way to render Malayalam Cillu...
// FIXME: eyelash RA only for Devanagari??
#define DEVA_SCRIPT_FLAGS (SF_EYELASH_RA | SF_NO_POST_BASE_LIMIT)
#define BENG_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT)
#define PUNJ_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT)
#define GUJR_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT)
#define ORYA_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT)
#define TAML_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT)
#define TELU_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | 3)
#define KNDA_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | 3)
#define MLYM_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT)
#define SINH_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT)
#define DEVA_SCRIPT_FLAGS (SF_EYELASH_RA | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define BENG_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define PUNJ_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define GUJR_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define ORYA_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define TAML_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define TELU_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | SF_FILTER_ZERO_WIDTH | 3)
#define KNDA_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | SF_FILTER_ZERO_WIDTH | 3)
#define MLYM_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT /*| SF_FILTER_ZERO_WIDTH*/)
#define SINH_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT)
//
// Indic Class Tables
......@@ -286,7 +303,7 @@ static const IndicClassTable sinhClassTable = {0x0D80, 0x0DF4, 4, SINH_SCRIPT_FL
//
// IndicClassTable addresses
//
static const IndicClassTable * const indicClassTables[] = {
static const IndicClassTable * const indicClassTables[scriptCodeCount] = {
NULL, /* 'zyyy' (COMMON) */
NULL, /* 'qaai' (INHERITED) */
NULL, /* 'arab' (ARABIC) */
......@@ -348,7 +365,79 @@ static const IndicClassTable * const indicClassTables[] = {
NULL, /* 'sylo' (SYLOTI_NAGRI) */
NULL, /* 'talu' (NEW_TAI_LUE) */
NULL, /* 'tfng' (TIFINAGH) */
NULL /* 'xpeo' (OLD_PERSIAN) */
NULL, /* 'xpeo' (OLD_PERSIAN) */
NULL, /* 'bali' (BALINESE) */
NULL, /* 'batk' (BATK) */
NULL, /* 'blis' (BLIS) */
NULL, /* 'brah' (BRAH) */
NULL, /* 'cham' (CHAM) */
NULL, /* 'cirt' (CIRT) */
NULL, /* 'cyrs' (CYRS) */
NULL, /* 'egyd' (EGYD) */
NULL, /* 'egyh' (EGYH) */
NULL, /* 'egyp' (EGYP) */
NULL, /* 'geok' (GEOK) */
NULL, /* 'hans' (HANS) */
NULL, /* 'hant' (HANT) */
NULL, /* 'hmng' (HMNG) */
NULL, /* 'hung' (HUNG) */
NULL, /* 'inds' (INDS) */
NULL, /* 'java' (JAVA) */
NULL, /* 'kali' (KALI) */
NULL, /* 'latf' (LATF) */
NULL, /* 'latg' (LATG) */
NULL, /* 'lepc' (LEPC) */
NULL, /* 'lina' (LINA) */
NULL, /* 'mand' (MAND) */
NULL, /* 'maya' (MAYA) */
NULL, /* 'mero' (MERO) */
NULL, /* 'nko ' (NKO) */
NULL, /* 'orkh' (ORKH) */
NULL, /* 'perm' (PERM) */
NULL, /* 'phag' (PHAGS_PA) */
NULL, /* 'phnx' (PHOENICIAN) */
NULL, /* 'plrd' (PLRD) */
NULL, /* 'roro' (RORO) */
NULL, /* 'sara' (SARA) */
NULL, /* 'syre' (SYRE) */
NULL, /* 'syrj' (SYRJ) */
NULL, /* 'syrn' (SYRN) */
NULL, /* 'teng' (TENG) */
NULL, /* 'vai ' (VAII) */
NULL, /* 'visp' (VISP) */
NULL, /* 'xsux' (CUNEIFORM) */
NULL, /* 'zxxx' (ZXXX) */
NULL, /* 'zzzz' (UNKNOWN) */
NULL, /* 'cari' (CARI) */
NULL, /* 'jpan' (JPAN) */
NULL, /* 'lana' (LANA) */
NULL, /* 'lyci' (LYCI) */
NULL, /* 'lydi' (LYDI) */
NULL, /* 'olck' (OLCK) */
NULL, /* 'rjng' (RJNG) */
NULL, /* 'saur' (SAUR) */
NULL, /* 'sgnw' (SGNW) */
NULL, /* 'sund' (SUND) */
NULL, /* 'moon' (MOON) */
NULL, /* 'mtei' (MTEI) */
NULL, /* 'armi' (ARMI) */
NULL, /* 'avst' (AVST) */
NULL, /* 'cakm' (CAKM) */
NULL, /* 'kore' (KORE) */
NULL, /* 'kthi' (KTHI) */
NULL, /* 'mani' (MANI) */
NULL, /* 'phli' (PHLI) */
NULL, /* 'phlp' (PHLP) */
NULL, /* 'phlv' (PHLV) */
NULL, /* 'prti' (PRTI) */
NULL, /* 'samr' (SAMR) */
NULL, /* 'tavt' (TAVT) */
NULL, /* 'zmth' (ZMTH) */
NULL, /* 'zsym' (ZSYM) */
NULL, /* 'bamu' (BAMUM) */
NULL, /* 'lisu' (LISU) */
NULL, /* 'nkgb' (NKGB) */
NULL /* 'sarb' (OLD_SOUTH_ARABIAN) */
};
IndicClassTable::CharClass IndicClassTable::getCharClass(LEUnicode ch) const
......@@ -388,4 +477,15 @@ le_int32 IndicReordering::getWorstCaseExpansion(le_int32 scriptCode)
return classTable->getWorstCaseExpansion();
}
le_bool IndicReordering::getFilterZeroWidth(le_int32 scriptCode)
{
const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
if (classTable == NULL) {
return TRUE;
}
return classTable->getFilterZeroWidth();
}
U_NAMESPACE_END
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
*
*/
......@@ -44,24 +44,31 @@
#include "LEGlyphStorage.h"
#include "IndicReordering.h"
#include <stdio.h>
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable), fMPreFixups(NULL)
le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
{
if ( version2 ) {
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
} else {
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
}
fFeatureOrder = TRUE;
fVersion2 = version2;
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
}
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fMPreFixups(NULL)
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMPreFixups(NULL)
{
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
fVersion2 = FALSE;
}
IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
......@@ -89,8 +96,13 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
return 0;
}
IndicReordering::adjustMPres(fMPreFixups, glyphStorage);
if (fVersion2) {
IndicReordering::finalReordering(glyphStorage,retCount);
IndicReordering::applyPresentationForms(glyphStorage,retCount);
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
} else {
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
}
return retCount;
}
......@@ -128,7 +140,18 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
// NOTE: assumes this allocates featureTags...
// (probably better than doing the worst case stuff here...)
le_int32 outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups);
le_int32 outCharCount;
if (fVersion2) {
outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
} else {
outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
}
if (LE_FAILURE(success)) {
LE_DELETE_ARRAY(outChars);
return 0;
}
glyphStorage.adoptGlyphCount(outCharCount);
return outCharCount;
......
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
*
*/
......@@ -72,6 +72,7 @@ public:
* @param scriptCode - the script
* @param langaugeCode - the language
* @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
*
* @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine
......@@ -80,7 +81,7 @@ public:
* @internal
*/
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable);
le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known
......@@ -89,6 +90,7 @@ public:
* @param fontInstance - the font
* @param scriptCode - the script
* @param langaugeCode - the language
* @param success - set to an error code if the operation fails
*
* @see OpenTypeLayoutEngine
* @see ScriptAndLangaugeTags.h for script and language codes
......@@ -96,7 +98,7 @@ public:
* @internal
*/
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags);
le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
......@@ -177,9 +179,12 @@ protected:
virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEGlyphStorage &glyphStorage, LEErrorCode &success);
le_bool fVersion2;
private:
MPreFixups *fMPreFixups;
};
U_NAMESPACE_END
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
*
*/
......@@ -62,7 +62,8 @@ U_NAMESPACE_BEGIN
#define CC_SPLIT_VOWEL_PIECE_3 12U
#define CC_VIRAMA 13U
#define CC_ZERO_WIDTH_MARK 14U
#define CC_COUNT 15U
#define CC_AL_LAKUNA 15U
#define CC_COUNT 16U
// Character class flags
#define CF_CLASS_MASK 0x0000FFFFU
......@@ -74,6 +75,7 @@ U_NAMESPACE_BEGIN
#define CF_BELOW_BASE 0x10000000U
#define CF_POST_BASE 0x08000000U
#define CF_LENGTH_MARK 0x04000000U
#define CF_PRE_BASE 0x02000000U
#define CF_POS_BEFORE 0x00300000U
#define CF_POS_BELOW 0x00200000U
......@@ -89,6 +91,7 @@ U_NAMESPACE_BEGIN
#define SF_REPH_AFTER_BELOW 0x40000000U
#define SF_EYELASH_RA 0x20000000U
#define SF_MPRE_FIXUP 0x10000000U
#define SF_FILTER_ZERO_WIDTH 0x08000000U
#define SF_POST_BASE_LIMIT_MASK 0x0000FFFFU
#define SF_NO_POST_BASE_LIMIT 0x00007FFFU
......@@ -98,6 +101,15 @@ typedef LEUnicode SplitMatra[3];
class MPreFixups;
class LEGlyphStorage;
// Dynamic Properties ( v2 fonts only )
typedef le_uint32 DynamicProperties;
#define DP_REPH 0x80000000U
#define DP_HALF 0x40000000U
#define DP_PREF 0x20000000U
#define DP_BLWF 0x10000000U
#define DP_PSTF 0x08000000U
struct IndicClassTable
{
typedef le_uint32 CharClass;
......@@ -111,6 +123,7 @@ struct IndicClassTable
const SplitMatra *splitMatraTable;
inline le_int32 getWorstCaseExpansion() const;
inline le_bool getFilterZeroWidth() const;
CharClass getCharClass(LEUnicode ch) const;
......@@ -121,6 +134,7 @@ struct IndicClassTable
inline le_bool isConsonant(LEUnicode ch) const;
inline le_bool isReph(LEUnicode ch) const;
inline le_bool isVirama(LEUnicode ch) const;
inline le_bool isAlLakuna(LEUnicode ch) const;
inline le_bool isNukta(LEUnicode ch) const;
inline le_bool isVattu(LEUnicode ch) const;
inline le_bool isMatra(LEUnicode ch) const;
......@@ -129,12 +143,15 @@ struct IndicClassTable
inline le_bool hasPostOrBelowBaseForm(LEUnicode ch) const;
inline le_bool hasPostBaseForm(LEUnicode ch) const;
inline le_bool hasBelowBaseForm(LEUnicode ch) const;
inline le_bool hasAboveBaseForm(LEUnicode ch) const;
inline le_bool hasPreBaseForm(LEUnicode ch) const;
inline static le_bool isVowelModifier(CharClass charClass);
inline static le_bool isStressMark(CharClass charClass);
inline static le_bool isConsonant(CharClass charClass);
inline static le_bool isReph(CharClass charClass);
inline static le_bool isVirama(CharClass charClass);
inline static le_bool isAlLakuna(CharClass charClass);
inline static le_bool isNukta(CharClass charClass);
inline static le_bool isVattu(CharClass charClass);
inline static le_bool isMatra(CharClass charClass);
......@@ -143,6 +160,8 @@ struct IndicClassTable
inline static le_bool hasPostOrBelowBaseForm(CharClass charClass);
inline static le_bool hasPostBaseForm(CharClass charClass);
inline static le_bool hasBelowBaseForm(CharClass charClass);
inline static le_bool hasAboveBaseForm(CharClass charClass);
inline static le_bool hasPreBaseForm(CharClass charClass);
static const IndicClassTable *getScriptClassTable(le_int32 scriptCode);
};
......@@ -151,14 +170,27 @@ class IndicReordering /* not : public UObject because all methods are static */
public:
static le_int32 getWorstCaseExpansion(le_int32 scriptCode);
static le_bool getFilterZeroWidth(le_int32 scriptCode);
static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
LEUnicode *outChars, LEGlyphStorage &glyphStorage,
MPreFixups **outMPreFixups);
MPreFixups **outMPreFixups, LEErrorCode& success);
static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success);
static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage);
static le_int32 v2process(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
LEUnicode *outChars, LEGlyphStorage &glyphStorage);
static const FeatureMap *getFeatureMap(le_int32 &count);
static const FeatureMap *getv2FeatureMap(le_int32 &count);
static void applyPresentationForms(LEGlyphStorage &glyphStorage, le_int32 count);
static void finalReordering(LEGlyphStorage &glyphStorage, le_int32 count);
static void getDynamicProperties(DynamicProperties *dProps, const IndicClassTable *classTable);
private:
// do not instantiate
IndicReordering();
......@@ -172,6 +204,11 @@ inline le_int32 IndicClassTable::getWorstCaseExpansion() const
return worstCaseExpansion;
}
inline le_bool IndicClassTable::getFilterZeroWidth() const
{
return (scriptFlags & SF_FILTER_ZERO_WIDTH) != 0;
}
inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const
{
le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT;
......@@ -209,6 +246,11 @@ inline le_bool IndicClassTable::isVirama(CharClass charClass)
return (charClass & CF_CLASS_MASK) == CC_VIRAMA;
}
inline le_bool IndicClassTable::isAlLakuna(CharClass charClass)
{
return (charClass & CF_CLASS_MASK) == CC_AL_LAKUNA;
}
inline le_bool IndicClassTable::isVattu(CharClass charClass)
{
return (charClass & CF_VATTU) != 0;
......@@ -241,11 +283,21 @@ inline le_bool IndicClassTable::hasPostBaseForm(CharClass charClass)
return (charClass & CF_POST_BASE) != 0;
}
inline le_bool IndicClassTable::hasPreBaseForm(CharClass charClass)
{
return (charClass & CF_PRE_BASE) != 0;
}
inline le_bool IndicClassTable::hasBelowBaseForm(CharClass charClass)
{
return (charClass & CF_BELOW_BASE) != 0;
}
inline le_bool IndicClassTable::hasAboveBaseForm(CharClass charClass)
{
return ((charClass & CF_POS_MASK) == CF_POS_ABOVE);
}
inline le_bool IndicClassTable::isVowelModifier(LEUnicode ch) const
{
return isVowelModifier(getCharClass(ch));
......@@ -271,6 +323,11 @@ inline le_bool IndicClassTable::isVirama(LEUnicode ch) const
return isVirama(getCharClass(ch));
}
inline le_bool IndicClassTable::isAlLakuna(LEUnicode ch) const
{
return isAlLakuna(getCharClass(ch));
}
inline le_bool IndicClassTable::isNukta(LEUnicode ch) const
{
return isNukta(getCharClass(ch));
......@@ -311,5 +368,14 @@ inline le_bool IndicClassTable::hasBelowBaseForm(LEUnicode ch) const
return hasBelowBaseForm(getCharClass(ch));
}
inline le_bool IndicClassTable::hasPreBaseForm(LEUnicode ch) const
{
return hasPreBaseForm(getCharClass(ch));
}
inline le_bool IndicClassTable::hasAboveBaseForm(LEUnicode ch) const
{
return hasAboveBaseForm(getCharClass(ch));
}
U_NAMESPACE_END
#endif
......@@ -26,7 +26,7 @@
/*
*
*
* (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 2004-2010 - All Rights Reserved
*
*/
......@@ -35,6 +35,7 @@
#include "LEGlyphStorage.h"
#include "LESwaps.h"
#include "OpenTypeUtilities.h"
#include <stdio.h>
......@@ -91,8 +92,8 @@ struct KernTableHeader {
* TODO: support multiple subtables
* TODO: respect header flags
*/
KernTable::KernTable(const LEFontInstance* font, const void* tableData)
: pairs(0), font(font)
KernTable::KernTable(const LEFontInstance* font_, const void* tableData)
: pairs(0), font(font_)
{
const KernTableHeader* header = (const KernTableHeader*)tableData;
if (header == 0) {
......@@ -120,10 +121,18 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData)
coverage = SWAPW(subhead->coverage);
if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning
const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE);
nPairs = SWAPW(table->nPairs);
searchRange = SWAPW(table->searchRange) / KERN_PAIRINFO_SIZE ;
nPairs = SWAPW(table->nPairs);
#if 0 // some old fonts have bad values here...
searchRange = SWAPW(table->searchRange);
entrySelector = SWAPW(table->entrySelector);
rangeShift = SWAPW(table->rangeShift) / KERN_PAIRINFO_SIZE;
rangeShift = SWAPW(table->rangeShift);
#else
entrySelector = OpenTypeUtilities::highBit(nPairs);
searchRange = (1 << entrySelector) * KERN_PAIRINFO_SIZE;
rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange;
#endif
pairs = (PairInfo*)font->getKernPairs();
if (pairs == NULL) {
......
......@@ -25,7 +25,7 @@
/*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
*
* This file is a modification of the ICU file IndicLayoutEngine.cpp
* by Jens Herden and Javier Sola for Khmer language
......@@ -43,16 +43,16 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine)
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable)
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
}
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
......
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
*
* This file is a modification of the ICU file IndicLayoutEngine.h
* by Jens Herden and Javier Sola for Khmer language
......@@ -72,8 +72,9 @@ public:
*
* @param fontInstance - the font
* @param scriptCode - the script
* @param languageCode - the language
* @param langaugeCode - the language
* @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
*
* @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine
......@@ -82,7 +83,7 @@ public:
* @internal
*/
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable);
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known
......@@ -91,6 +92,7 @@ public:
* @param fontInstance - the font
* @param scriptCode - the script
* @param langaugeCode - the language
* @param success - set to an error code if the operation fails
*
* @see OpenTypeLayoutEngine
* @see ScriptAndLangaugeTags.h for script and language codes
......@@ -98,7 +100,7 @@ public:
* @internal
*/
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags);
le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
*
* This file is a modification of the ICU file IndicReordering.cpp
* by Jens Herden and Javier Sola for Khmer language
......@@ -149,8 +149,9 @@ const KhmerClassTable *KhmerClassTable::getKhmerClassTable()
class ReorderingOutput : public UMemory {
class KhmerReorderingOutput : public UMemory {
private:
le_int32 fSyllableCount;
le_int32 fOutIndex;
LEUnicode *fOutChars;
......@@ -158,17 +159,22 @@ private:
public:
ReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage)
: fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage)
KhmerReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage)
: fSyllableCount(0), fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage)
{
// nothing else to do...
}
~ReorderingOutput()
~KhmerReorderingOutput()
{
// nothing to do here...
}
void reset()
{
fSyllableCount += 1;
}
void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask charFeatures)
{
LEErrorCode success = LE_NO_ERROR;
......@@ -176,7 +182,7 @@ public:
fOutChars[fOutIndex] = ch;
fGlyphStorage.setCharIndex(fOutIndex, charIndex, success);
fGlyphStorage.setAuxData(fOutIndex, charFeatures, success);
fGlyphStorage.setAuxData(fOutIndex, charFeatures | (fSyllableCount & LE_GLYPH_GROUP_MASK), success);
fOutIndex += 1;
}
......@@ -328,12 +334,12 @@ static const le_int8 khmerStateTable[][KhmerClassTable::CC_COUNT] =
{-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, // 9 - First consonant or type 3 after ceong
{-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, // 10 - Second Coeng (no register shifter before)
{-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 11 - Second coeng consonant (or ind. vowel) no register shifter before
{-1, -1, 1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, // 12 - Second ZWNJ before a register shifter
{-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, // 12 - Second ZWNJ before a register shifter
{-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 13 - Second register shifter
{-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 14 - ZWJ before vowel
{-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 15 - ZWNJ before vowel
{-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, // 16 - dependent vowel
{-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, // 17 - sign above
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, // 17 - sign above
{-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, // 18 - ZWJ after vowel
{-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, // 19 - Third coeng
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, // 20 - dependent vowel after a Robat
......@@ -380,7 +386,7 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
{
const KhmerClassTable *classTable = KhmerClassTable::getKhmerClassTable();
ReorderingOutput output(outChars, glyphStorage);
KhmerReorderingOutput output(outChars, glyphStorage);
KhmerClassTable::CharClass charClass;
le_int32 i, prev = 0, coengRo;
......@@ -390,6 +396,8 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
while (prev < charCount) {
le_int32 syllable = findSyllable(classTable, chars, prev, charCount);
output.reset();
// write a pre vowel or the pre part of a split vowel first
// and look out for coeng + ro. RO is the only vowel of type 2, and
// therefore the only one that requires saving space before the base.
......
......@@ -26,7 +26,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1999-2005, International Business Machines
* Copyright (C) 1999-2007, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
......@@ -45,6 +45,16 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEFontInstance)
LECharMapper::~LECharMapper()
{
// nothing to do.
}
LEFontInstance::~LEFontInstance()
{
// nothing to do
}
const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int32 *offset, le_int32 limit,
le_int32 script, LEErrorCode &success) const
{
......@@ -62,7 +72,7 @@ const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int
}
void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count,
le_bool reverse, const LECharMapper *mapper, LEGlyphStorage &glyphStorage) const
le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const
{
le_int32 i, out = 0, dir = 1;
......@@ -83,7 +93,7 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset,
}
}
glyphStorage[out] = mapCharToGlyph(code, mapper);
glyphStorage[out] = mapCharToGlyph(code, mapper, filterZeroWidth);
if (code >= 0x10000) {
i += 1;
......@@ -93,15 +103,72 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset,
}
LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
{
return mapCharToGlyph(ch, mapper, TRUE);
}
LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
{
LEUnicode32 mappedChar = mapper->mapChar(ch);
if (mappedChar == 0xFFFE || mappedChar == 0xFFFF ||
mappedChar == 0x200C || mappedChar == 0x200D) {
if (mappedChar == 0xFFFE || mappedChar == 0xFFFF) {
return 0xFFFF;
}
if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) {
return canDisplay(mappedChar)? 0x0001 : 0xFFFF;
}
return mapCharToGlyph(mappedChar);
}
le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const
{
return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0;
}
float LEFontInstance::xUnitsToPoints(float xUnits) const
{
return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM();
}
float LEFontInstance::yUnitsToPoints(float yUnits) const
{
return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM();
}
void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const
{
points.fX = xUnitsToPoints(units.fX);
points.fY = yUnitsToPoints(units.fY);
}
float LEFontInstance::xPixelsToUnits(float xPixels) const
{
return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm();
}
float LEFontInstance::yPixelsToUnits(float yPixels) const
{
return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm();
}
void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const
{
units.fX = xPixelsToUnits(pixels.fX);
units.fY = yPixelsToUnits(pixels.fY);
}
void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const
{
pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX();
pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY();
}
le_int32 LEFontInstance::getLineHeight() const
{
return getAscent() + getDescent() + getLeading();
}
U_NAMESPACE_END
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
*
*/
......@@ -57,7 +57,7 @@ public:
* Destructor.
* @stable ICU 3.2
*/
virtual inline ~LECharMapper() {};
virtual ~LECharMapper();
/**
* This method does the adjustments.
......@@ -75,7 +75,7 @@ public:
* This is a forward reference to the class which holds the per-glyph
* storage.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
class LEGlyphStorage;
......@@ -101,7 +101,7 @@ class LEGlyphStorage;
* methods with some default behavior such as returning constant values, or using the
* values from the first subfont.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
class U_LAYOUT_API LEFontInstance : public UObject
{
......@@ -113,7 +113,7 @@ public:
*
* @stable ICU 2.8
*/
virtual inline ~LEFontInstance() {};
virtual ~LEFontInstance();
/**
* Get a physical font which can render the given text. For composite fonts,
......@@ -209,7 +209,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline le_bool canDisplay(LEUnicode32 ch) const;
virtual le_bool canDisplay(LEUnicode32 ch) const;
/**
* This method returns the number of design units in
......@@ -237,13 +237,31 @@ public:
* @param count - the number of characters
* @param reverse - if <code>TRUE</code>, store the glyph indices in reverse order.
* @param mapper - the character mapper.
* @param filterZeroWidth - <code>TRUE</code> if ZWJ / ZWNJ characters should map to a glyph w/ no contours.
* @param glyphStorage - the object which contains the output glyph array
*
* @see LECharMapper
*
* @draft ICU 3.0
* @stable ICU 3.6
*/
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, LEGlyphStorage &glyphStorage) const;
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const;
/**
* This method maps a single character to a glyph index, using the
* font's character to glyph map. The default implementation of this
* method calls the mapper, and then calls <code>mapCharToGlyph(mappedCh)</code>.
*
* @param ch - the character
* @param mapper - the character mapper
* @param filterZeroWidth - <code>TRUE</code> if ZWJ / ZWNJ characters should map to a glyph w/ no contours.
*
* @return the glyph index
*
* @see LECharMapper
*
* @stable ICU 3.6
*/
virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const;
/**
* This method maps a single character to a glyph index, using the
......@@ -335,7 +353,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline float xUnitsToPoints(float xUnits) const;
virtual float xUnitsToPoints(float xUnits) const;
/**
* This method converts font design units in the
......@@ -347,7 +365,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline float yUnitsToPoints(float yUnits) const;
virtual float yUnitsToPoints(float yUnits) const;
/**
* This method converts font design units to points.
......@@ -357,7 +375,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline void unitsToPoints(LEPoint &units, LEPoint &points) const;
virtual void unitsToPoints(LEPoint &units, LEPoint &points) const;
/**
* This method converts pixels in the
......@@ -369,7 +387,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline float xPixelsToUnits(float xPixels) const;
virtual float xPixelsToUnits(float xPixels) const;
/**
* This method converts pixels in the
......@@ -381,7 +399,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline float yPixelsToUnits(float yPixels) const;
virtual float yPixelsToUnits(float yPixels) const;
/**
* This method converts pixels to font design units.
......@@ -391,7 +409,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline void pixelsToUnits(LEPoint &pixels, LEPoint &units) const;
virtual void pixelsToUnits(LEPoint &pixels, LEPoint &units) const;
/**
* Get the X scale factor from the font's transform. The default
......@@ -433,7 +451,7 @@ public:
*
* @stable ICU 3.2
*/
virtual inline void transformFunits(float xFunits, float yFunits, LEPoint &pixels) const;
virtual void transformFunits(float xFunits, float yFunits, LEPoint &pixels) const;
/**
* This is a convenience method used to convert
......@@ -523,49 +541,6 @@ public:
};
inline le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const
{
return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0;
}
inline float LEFontInstance::xUnitsToPoints(float xUnits) const
{
return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM();
}
inline float LEFontInstance::yUnitsToPoints(float yUnits) const
{
return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM();
}
inline void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const
{
points.fX = xUnitsToPoints(units.fX);
points.fY = yUnitsToPoints(units.fY);
}
inline float LEFontInstance::xPixelsToUnits(float xPixels) const
{
return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm();
}
inline float LEFontInstance::yPixelsToUnits(float yPixels) const
{
return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm();
}
inline void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const
{
units.fX = xPixelsToUnits(pixels.fX);
units.fY = yPixelsToUnits(pixels.fY);
}
inline void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const
{
pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX();
pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY();
}
inline float LEFontInstance::fixedToFloat(le_int32 fixed)
{
return (float) (fixed / 65536.0);
......@@ -576,11 +551,6 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat)
return (le_int32) (theFloat * 65536.0);
}
inline le_int32 LEFontInstance::getLineHeight() const
{
return getAscent() + getDescent() + getLeading();
}
U_NAMESPACE_END
#endif
......
......@@ -25,7 +25,7 @@
/*
**********************************************************************
* Copyright (C) 1998-2005, International Business Machines
* Copyright (C) 1998-2009, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
......@@ -38,6 +38,11 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
LEInsertionCallback::~LEInsertionCallback()
{
// nothing to do...
}
LEGlyphStorage::LEGlyphStorage()
: fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
......@@ -129,8 +134,18 @@ void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool righ
if (fInsertionList == NULL) {
// FIXME: check this for failure?
fInsertionList = new LEInsertionList(rightToLeft);
if (fInsertionList == NULL) {
LE_DELETE_ARRAY(fCharIndices);
fCharIndices = NULL;
LE_DELETE_ARRAY(fGlyphs);
fGlyphs = NULL;
success = LE_MEMORY_ALLOCATION_ERROR;
return;
}
}
}
// FIXME: do we want to initialize the positions to [0, 0]?
le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
......@@ -139,6 +154,11 @@ le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
return -1;
}
if (fPositions != NULL) {
success = LE_INTERNAL_ERROR;
return -1;
}
fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
if (fPositions == NULL) {
......@@ -156,6 +176,11 @@ le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
return -1;
}
if (fAuxData != NULL) {
success = LE_INTERNAL_ERROR;
return -1;
}
fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount);
if (fAuxData == NULL) {
......@@ -510,10 +535,49 @@ void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
fGlyphCount = newGlyphCount;
}
// FIXME: add error checking?
// Move a glyph to a different position in the LEGlyphStorage ( used for Indic v2 processing )
void LEGlyphStorage::moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker )
{
LEErrorCode success = LE_NO_ERROR;
LEGlyphID holdGlyph = getGlyphID(fromPosition,success);
le_int32 holdCharIndex = getCharIndex(fromPosition,success);
le_uint32 holdAuxData = getAuxData(fromPosition,success);
if ( fromPosition < toPosition ) {
for ( le_int32 i = fromPosition ; i < toPosition ; i++ ) {
setGlyphID(i,getGlyphID(i+1,success),success);
setCharIndex(i,getCharIndex(i+1,success),success);
setAuxData(i,getAuxData(i+1,success),success);
}
} else {
for ( le_int32 i = toPosition ; i > fromPosition ; i-- ) {
setGlyphID(i,getGlyphID(i-1,success),success);
setCharIndex(i,getCharIndex(i-1,success),success);
setAuxData(i,getAuxData(i-1,success),success);
}
}
setGlyphID(toPosition,holdGlyph,success);
setCharIndex(toPosition,holdCharIndex,success);
setAuxData(toPosition,holdAuxData | marker,success);
}
// Glue code for existing stable API
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount)
{
return fInsertionList->insert(atIndex, insertCount);
LEErrorCode ignored = LE_NO_LAYOUT_ERROR;
return insertGlyphs(atIndex, insertCount, ignored);
}
// FIXME: add error checking?
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success)
{
return fInsertionList->insert(atIndex, insertCount, success);
}
le_int32 LEGlyphStorage::applyInsertions()
......@@ -526,11 +590,27 @@ le_int32 LEGlyphStorage::applyInsertions()
le_int32 newGlyphCount = fGlyphCount + growAmount;
fGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
fCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
if (newGlyphs == NULL) {
// Could not grow the glyph array
return fGlyphCount;
}
fGlyphs = newGlyphs;
le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
if (newCharIndices == NULL) {
// Could not grow the glyph array
return fGlyphCount;
}
fCharIndices = newCharIndices;
if (fAuxData != NULL) {
fAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount);
le_uint32 *newAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount);
if (newAuxData == NULL) {
// could not grow the aux data array
return fGlyphCount;
}
fAuxData = (le_uint32 *)newAuxData;
}
fSrcIndex = fGlyphCount - 1;
......
......@@ -25,7 +25,7 @@
/*
**********************************************************************
* Copyright (C) 1998-2005, International Business Machines
* Copyright (C) 1998-2010, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
......@@ -54,7 +54,7 @@ U_NAMESPACE_BEGIN
*
* @see LEInsertionList.h
*
* @draft ICU 3.6
* @stable ICU 3.6
*/
class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback
{
......@@ -130,7 +130,7 @@ protected:
*
* @see LEInsertionList.h
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]);
......@@ -141,14 +141,14 @@ public:
* <code>allocateGlyphArray, allocatePositions and allocateAuxData</code>
* to allocate the data.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
LEGlyphStorage();
/**
* The destructor. This will deallocate all of the arrays.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
~LEGlyphStorage();
......@@ -157,7 +157,7 @@ public:
*
* @return the number of glyphs in the glyph array
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
inline le_int32 getGlyphCount() const;
......@@ -169,7 +169,7 @@ public:
* @param glyphs - the destiniation glyph array
* @param success - set to an error code if the operation fails
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const;
......@@ -183,7 +183,7 @@ public:
* @param extraBits - this value will be ORed with each glyph index
* @param success - set to an error code if the operation fails
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const;
......@@ -195,7 +195,7 @@ public:
* @param charIndices - the destiniation character index array
* @param success - set to an error code if the operation fails
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void getCharIndices(le_int32 charIndices[], LEErrorCode &success) const;
......@@ -208,7 +208,7 @@ public:
* @param indexBase - an offset which will be added to each index
* @param success - set to an error code if the operation fails
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const;
......@@ -221,7 +221,7 @@ public:
* @param positions - the destiniation position array
* @param success - set to an error code if the operation fails
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void getGlyphPositions(float positions[], LEErrorCode &success) const;
......@@ -237,7 +237,7 @@ public:
* @param y - the glyph's Y position
* @param success - set to an error code if the operation fails
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const;
......@@ -251,7 +251,7 @@ public:
* @param success set to an error code if the storage cannot be allocated of if the initial
* glyph count is not positive.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success);
......@@ -263,7 +263,7 @@ public:
*
* @return the number of X, Y position pairs allocated.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
le_int32 allocatePositions(LEErrorCode &success);
......@@ -274,7 +274,7 @@ public:
*
* @return the size of the auxillary data array.
*
* @draft ICU 3.6
* @stable ICU 3.6
*/
le_int32 allocateAuxData(LEErrorCode &success);
......@@ -284,7 +284,7 @@ public:
* @param auxData the auxillary data array will be copied to this address
* @param success set to an error code if the data cannot be copied
*
* @draft ICU 3.6
* @stable ICU 3.6
*/
void getAuxData(le_uint32 auxData[], LEErrorCode &success) const;
......@@ -296,7 +296,7 @@ public:
*
* @return the glyph ID
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const;
......@@ -308,7 +308,7 @@ public:
*
* @return the character index
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
le_int32 getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const;
......@@ -321,7 +321,7 @@ public:
*
* @return the auxillary data
*
* @draft ICU 3.6
* @stable ICU 3.6
*/
le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const;
......@@ -333,7 +333,7 @@ public:
*
* @return a reference to the given location in the glyph array
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
inline LEGlyphID &operator[](le_int32 glyphIndex) const;
......@@ -346,15 +346,51 @@ public:
*
* @param atIndex the index of the glyph to be replaced
* @param insertCount the number of glyphs to replace it with
* @param success set to an error code if the auxillary data cannot be retrieved.
*
* @return the address at which to store the replacement glyphs.
*
* @see LEInsertionList.h
*
* @stable ICU 4.2
*/
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success);
/**
* Call this method to replace a single glyph in the glyph array
* with multiple glyphs. This method uses the <code>LEInsertionList</code>
* to do the insertion. It returns the address of storage where the new
* glyph IDs can be stored. They will not actually be inserted into the
* glyph array until <code>applyInsertions</code> is called.
*
* Note: Don't use this version, use the other version of this function which has an error code.
*
* @param atIndex the index of the glyph to be replaced
* @param insertCount the number of glyphs to replace it with
*
* @return the address at which to store the replacement glyphs.
*
* @see LEInsetionList.h
* @see LEInsertionList.h
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount);
/**
* This method is used to reposition glyphs during Indic v2 processing. It moves
* all of the relevant glyph information ( glyph, indices, positions, and auxData ),
* from the source position to the target position, and also allows for a marker bit
* to be set in the target glyph's auxData so that it won't be reprocessed later in the
* cycle.
*
* @param fromPosition - position of the glyph to be moved
* @param toPosition - target position of the glyph
* @param marker marker bit
*
* @stable ICU 4.2
*/
void moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker);
/**
* This method causes all of the glyph insertions recorded by
* <code>insertGlyphs</code> to be applied to the glyph array. The
......@@ -365,7 +401,7 @@ public:
*
* @see LEInsertionList.h
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
le_int32 applyInsertions();
......@@ -376,7 +412,7 @@ public:
* @param glyphID the new glyph ID
* @param success will be set to an error code if the glyph ID cannot be set.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success);
......@@ -387,7 +423,7 @@ public:
* @param charIndex the new char index
* @param success will be set to an error code if the char index cannot be set.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success);
......@@ -399,7 +435,7 @@ public:
* @param y the new Y position
* @param success will be set to an error code if the position cannot be set.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success);
......@@ -411,7 +447,7 @@ public:
* @param yAdjust the adjustment to the glyph's Y position
* @param success will be set to an error code if the glyph's position cannot be adjusted.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success);
......@@ -422,7 +458,7 @@ public:
* @param auxData the new auxillary data
* @param success will be set to an error code if the auxillary data cannot be set.
*
* @draft ICU 3.6
* @stable ICU 3.6
*/
void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success);
......@@ -434,7 +470,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which
* to get the new glyph array.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void adoptGlyphArray(LEGlyphStorage &from);
......@@ -446,7 +482,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which
* to get the new char indices array.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void adoptCharIndicesArray(LEGlyphStorage &from);
......@@ -458,7 +494,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which
* to get the new position array.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void adoptPositionArray(LEGlyphStorage &from);
......@@ -470,7 +506,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which
* to get the new auxillary data array.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void adoptAuxDataArray(LEGlyphStorage &from);
......@@ -481,7 +517,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which
* to get the new glyph count.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void adoptGlyphCount(LEGlyphStorage &from);
......@@ -490,7 +526,7 @@ public:
*
* @param newGlyphCount the new glyph count.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void adoptGlyphCount(le_int32 newGlyphCount);
......@@ -500,21 +536,21 @@ public:
* to layout a different characer array. (This method is also called
* by the destructor)
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
void reset();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
virtual UClassID getDynamicClassID() const;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.0
* @stable ICU 3.0
*/
static UClassID getStaticClassID();
};
......
......@@ -25,7 +25,7 @@
/*
**********************************************************************
* Copyright (C) 1998-2004, International Business Machines
* Copyright (C) 1998-2008, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
......@@ -76,9 +76,17 @@ le_int32 LEInsertionList::getGrowAmount()
return growAmount;
}
LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count)
LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return 0;
}
InsertionRecord *insertion = (InsertionRecord *) LE_NEW_ARRAY(char, sizeof(InsertionRecord) + (count - ANY_NUMBER) * sizeof (LEGlyphID));
if (insertion == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
insertion->position = position;
insertion->count = count;
......
......@@ -25,7 +25,7 @@
/*
**********************************************************************
* Copyright (C) 1998-2004, International Business Machines
* Copyright (C) 1998-2008, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
......@@ -45,7 +45,7 @@ struct InsertionRecord;
*
* @internal
*/
class LEInsertionCallback
class U_LAYOUT_API LEInsertionCallback
{
public:
/**
......@@ -62,6 +62,11 @@ public:
* @internal
*/
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0;
/**
* The destructor
*/
virtual ~LEInsertionCallback();
};
/**
......@@ -103,13 +108,14 @@ public:
* @param position the glyph at this position in the array will be
* replaced by the new glyphs.
* @param count the number of new glyphs
* @param success set to an error code if the auxillary data cannot be retrieved.
*
* @return the address of an array in which to store the new glyphs. This will
* <em>not</em> be in the glyph array.
*
* @internal
*/
LEGlyphID *insert(le_int32 position, le_int32 count);
LEGlyphID *insert(le_int32 position, le_int32 count, LEErrorCode &success);
/**
* Return the number of new glyphs that have been inserted.
......
......@@ -25,12 +25,12 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005. All Rights Reserved.
* (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
*
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* YOU REALLY KNOW WHAT YOU'RE DOING.
*
* Generated on: 07/19/2005 01:01:08 PM PDT
* Generated on: 10/26/2010 02:53:33 PM PDT
*/
#ifndef __LELANGUAGES_H
......@@ -50,7 +50,7 @@ U_NAMESPACE_BEGIN
* this is just a list of languages which the LayoutEngine
* supports.
*
* @draft ICU 3.4
* @stable ICU 2.6
*/
enum LanguageCodes {
......@@ -85,7 +85,51 @@ enum LanguageCodes {
zhsLanguageCode = 28,
zhtLanguageCode = 29,
languageCodeCount = 30
/** New language codes added 03/13/2008 @stable ICU 4.0 */
afkLanguageCode = 30,
belLanguageCode = 31,
bgrLanguageCode = 32,
catLanguageCode = 33,
cheLanguageCode = 34,
copLanguageCode = 35,
csyLanguageCode = 36,
danLanguageCode = 37,
deuLanguageCode = 38,
dznLanguageCode = 39,
ellLanguageCode = 40,
engLanguageCode = 41,
espLanguageCode = 42,
etiLanguageCode = 43,
euqLanguageCode = 44,
finLanguageCode = 45,
fraLanguageCode = 46,
gaeLanguageCode = 47,
hauLanguageCode = 48,
hrvLanguageCode = 49,
hunLanguageCode = 50,
hyeLanguageCode = 51,
indLanguageCode = 52,
itaLanguageCode = 53,
khmLanguageCode = 54,
mngLanguageCode = 55,
mtsLanguageCode = 56,
nepLanguageCode = 57,
nldLanguageCode = 58,
pasLanguageCode = 59,
plkLanguageCode = 60,
ptgLanguageCode = 61,
romLanguageCode = 62,
rusLanguageCode = 63,
skyLanguageCode = 64,
slvLanguageCode = 65,
sqiLanguageCode = 66,
srbLanguageCode = 67,
sveLanguageCode = 68,
tibLanguageCode = 69,
trkLanguageCode = 70,
welLanguageCode = 71,
languageCodeCount = 72
};
U_NAMESPACE_END
......
......@@ -25,40 +25,43 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005. All Rights Reserved.
* (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
*
* 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
*/
#ifndef __LESCRIPTS_H
#define __LESCRIPTS_H
#include "LETypes.h"
/**
* \file
* \brief C++ API: Constants for Unicode script values
*/
U_NAMESPACE_BEGIN
/**
* Constants for Unicode script values, generated using
* ICU4J's <code>UScript</code> class.
*
* @draft ICU 3.0
* @stable ICU 2.2
*/
enum ScriptCodes {
zyyyScriptCode = 0,
qaaiScriptCode = 1,
zinhScriptCode = 1,
qaaiScriptCode = zinhScriptCode, /* manually added alias, for API stability */
arabScriptCode = 2,
armnScriptCode = 3,
bengScriptCode = 4,
bopoScriptCode = 5,
cherScriptCode = 6,
qaacScriptCode = 7,
coptScriptCode = 7,
cyrlScriptCode = 8,
dsrtScriptCode = 9,
devaScriptCode = 10,
......@@ -91,12 +94,24 @@ enum ScriptCodes {
thaaScriptCode = 37,
thaiScriptCode = 38,
tibtScriptCode = 39,
/**
* @stable ICU 2.6
*/
cansScriptCode = 40,
/**
* @stable ICU 2.2
*/
yiiiScriptCode = 41,
tglgScriptCode = 42,
hanoScriptCode = 43,
buhdScriptCode = 44,
tagbScriptCode = 45,
/**
* @stable ICU 2.6
*/
braiScriptCode = 46,
cprtScriptCode = 47,
limbScriptCode = 48,
......@@ -105,9 +120,129 @@ enum ScriptCodes {
shawScriptCode = 51,
taleScriptCode = 52,
ugarScriptCode = 53,
/**
* @stable ICU 3.0
*/
hrktScriptCode = 54,
/**
* @stable ICU 3.4
*/
bugiScriptCode = 55,
glagScriptCode = 56,
kharScriptCode = 57,
syloScriptCode = 58,
taluScriptCode = 59,
tfngScriptCode = 60,
xpeoScriptCode = 61,
/**
* @stable ICU 3.6
*/
baliScriptCode = 62,
batkScriptCode = 63,
blisScriptCode = 64,
brahScriptCode = 65,
chamScriptCode = 66,
cirtScriptCode = 67,
cyrsScriptCode = 68,
egydScriptCode = 69,
egyhScriptCode = 70,
egypScriptCode = 71,
geokScriptCode = 72,
hansScriptCode = 73,
hantScriptCode = 74,
hmngScriptCode = 75,
hungScriptCode = 76,
indsScriptCode = 77,
javaScriptCode = 78,
kaliScriptCode = 79,
latfScriptCode = 80,
latgScriptCode = 81,
lepcScriptCode = 82,
linaScriptCode = 83,
mandScriptCode = 84,
mayaScriptCode = 85,
meroScriptCode = 86,
nkooScriptCode = 87,
orkhScriptCode = 88,
permScriptCode = 89,
phagScriptCode = 90,
phnxScriptCode = 91,
plrdScriptCode = 92,
roroScriptCode = 93,
saraScriptCode = 94,
syreScriptCode = 95,
syrjScriptCode = 96,
syrnScriptCode = 97,
tengScriptCode = 98,
vaiiScriptCode = 99,
vispScriptCode = 100,
xsuxScriptCode = 101,
zxxxScriptCode = 102,
zzzzScriptCode = 103,
/**
* @stable ICU 3.8
*/
cariScriptCode = 104,
jpanScriptCode = 105,
lanaScriptCode = 106,
lyciScriptCode = 107,
lydiScriptCode = 108,
olckScriptCode = 109,
rjngScriptCode = 110,
saurScriptCode = 111,
sgnwScriptCode = 112,
sundScriptCode = 113,
moonScriptCode = 114,
mteiScriptCode = 115,
/**
* @stable ICU 4.0
*/
armiScriptCode = 116,
avstScriptCode = 117,
cakmScriptCode = 118,
koreScriptCode = 119,
kthiScriptCode = 120,
maniScriptCode = 121,
phliScriptCode = 122,
phlpScriptCode = 123,
phlvScriptCode = 124,
prtiScriptCode = 125,
samrScriptCode = 126,
tavtScriptCode = 127,
zmthScriptCode = 128,
zsymScriptCode = 129,
/**
* @stable ICU 4.4
*/
bamuScriptCode = 130,
lisuScriptCode = 131,
nkgbScriptCode = 132,
sarbScriptCode = 133,
/**
* @stable ICU 4.6
*/
bassScriptCode = 134,
duplScriptCode = 135,
elbaScriptCode = 136,
granScriptCode = 137,
kpelScriptCode = 138,
lomaScriptCode = 139,
mendScriptCode = 140,
mercScriptCode = 141,
narbScriptCode = 142,
nbatScriptCode = 143,
palmScriptCode = 144,
sindScriptCode = 145,
waraScriptCode = 146,
scriptCodeCount = 55
scriptCodeCount = 147
};
U_NAMESPACE_END
......
......@@ -26,6 +26,15 @@
#ifndef __LESTANDALONE
#define __LESTANDALONE
#ifndef U_COPYRIGHT_STRING
#define U_COPYRIGHT_STRING " (C) Copyright IBM Corp and Others. 1998-2010 - All Rights Reserved"
#endif
/* ICU Version number */
#ifndef U_ICU_VERSION
#define U_ICU_VERSION "4.6"
#endif
/* Definitions to make Layout Engine work away from ICU. */
#ifndef U_NAMESPACE_BEGIN
#define U_NAMESPACE_BEGIN
......
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -472,6 +472,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_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */
LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */
LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */
......@@ -535,6 +536,7 @@ enum LEFeatureTags {
LE_RAND_FEATURE_TAG = 0x72616E64UL, /**< 'rand' */
LE_RLIG_FEATURE_TAG = 0x726C6967UL, /**< 'rlig' */
LE_RPHF_FEATURE_TAG = 0x72706866UL, /**< 'rphf' */
LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */
LE_RTBD_FEATURE_TAG = 0x72746264UL, /**< 'rtbd' */
LE_RTLA_FEATURE_TAG = 0x72746C61UL, /**< 'rtla' */
LE_RUBY_FEATURE_TAG = 0x72756279UL, /**< 'ruby' */
......
......@@ -38,10 +38,11 @@
#include "ArabicLayoutEngine.h"
#include "CanonShaping.h"
#include "HanLayoutEngine.h"
#include "HangulLayoutEngine.h"
#include "IndicLayoutEngine.h"
#include "KhmerLayoutEngine.h"
#include "ThaiLayoutEngine.h"
//#include "TibetanLayoutEngine.h"
#include "TibetanLayoutEngine.h"
#include "GXLayoutEngine.h"
#include "ScriptAndLanguageTags.h"
#include "CharSubstitutionFilter.h"
......@@ -59,6 +60,9 @@
U_NAMESPACE_BEGIN
/* Leave this copyright notice here! It needs to go somewhere in this library. */
static const char copyright[] = U_COPYRIGHT_STRING;
const LEUnicode32 DefaultCharMapper::controlChars[] = {
0x0009, 0x000A, 0x000D,
/*0x200C, 0x200D,*/ 0x200E, 0x200F,
......@@ -96,9 +100,8 @@ LEUnicode32 DefaultCharMapper::mapChar(LEUnicode32 ch) const
}
if (fFilterControls) {
le_int32 index = OpenTypeUtilities::search((le_uint32)ch,
(le_uint32 *)controlChars,
controlCharsCount);
le_int32 index = OpenTypeUtilities::search((le_uint32)ch, (le_uint32 *)controlChars, controlCharsCount);
if (controlChars[index] == ch) {
return 0xFFFF;
}
......@@ -134,6 +137,37 @@ CharSubstitutionFilter::~CharSubstitutionFilter()
// nothing to do
}
class CanonMarkFilter : public UMemory, public LEGlyphFilter
{
private:
const GlyphClassDefinitionTable *classDefTable;
CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
public:
CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const;
};
CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
{
classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
}
CanonMarkFilter::~CanonMarkFilter()
{
// nothing to do?
}
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
{
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
return glyphClass != 0;
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
......@@ -150,11 +184,22 @@ static const FeatureMap canonFeatureMap[] =
static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap);
LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags)
LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
le_int32 scriptCode,
le_int32 languageCode,
le_int32 typoFlags,
LEErrorCode &success)
: fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode),
fTypoFlags(typoFlags)
fTypoFlags(typoFlags), fFilterZeroWidth(TRUE)
{
if (LE_FAILURE(success)) {
return;
}
fGlyphStorage = new LEGlyphStorage();
if (fGlyphStorage == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
}
}
le_int32 LayoutEngine::getGlyphCount() const
......@@ -183,37 +228,6 @@ void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
fGlyphStorage->getGlyphs(glyphs, success);
}
class CanonMarkFilter : public LEGlyphFilter
{
private:
const GlyphClassDefinitionTable *classDefTable;
CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
public:
CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const;
};
CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
{
classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
}
CanonMarkFilter::~CanonMarkFilter()
{
// nothing to do?
}
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
{
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
return glyphClass != 0;
}
void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const
{
......@@ -244,8 +258,21 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
if (canonGSUBTable->coversScript(scriptTag)) {
CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
if (substitutionFilter == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
const LEUnicode *inChars = &chars[offset];
LEUnicode *reordered = NULL;
LEGlyphStorage fakeGlyphStorage;
fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success);
if (LE_FAILURE(success)) {
delete substitutionFilter;
return 0;
}
// This is the cheapest way to get mark reordering only for Hebrew.
// We could just do the mark reordering for all scripts, but most
......@@ -254,18 +281,19 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
reordered = LE_NEW_ARRAY(LEUnicode, count);
if (reordered == NULL) {
delete substitutionFilter;
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, glyphStorage);
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
inChars = reordered;
}
glyphStorage.allocateGlyphArray(count, rightToLeft, success);
glyphStorage.allocateAuxData(success);
fakeGlyphStorage.allocateAuxData(success);
if (LE_FAILURE(success)) {
delete substitutionFilter;
return 0;
}
......@@ -275,21 +303,41 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
}
for (i = 0; i < count; i += 1, out += dir) {
glyphStorage[out] = (LEGlyphID) inChars[i];
glyphStorage.setAuxData(out, canonFeatures, success);
fakeGlyphStorage[out] = (LEGlyphID) inChars[i];
fakeGlyphStorage.setAuxData(out, canonFeatures, success);
}
if (reordered != NULL) {
LE_DELETE_ARRAY(reordered);
}
outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE);
outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
if (LE_FAILURE(success)) {
delete substitutionFilter;
return 0;
}
out = (rightToLeft? outCharCount - 1 : 0);
out = (rightToLeft? count - 1 : 0);
/*
* The char indices array in fakeGlyphStorage has the correct mapping
* back to the original input characters. Save it in glyphStorage. The
* subsequent call to glyphStoratge.allocateGlyphArray will keep this
* array rather than allocating and initializing a new one.
*/
glyphStorage.adoptCharIndicesArray(fakeGlyphStorage);
outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);
if (outChars == NULL) {
delete substitutionFilter;
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
for (i = 0; i < outCharCount; i += 1, out += dir) {
outChars[out] = (LEUnicode) LE_GET_GLYPH(glyphStorage[i]);
outChars[out] = (LEUnicode) LE_GET_GLYPH(fakeGlyphStorage[i]);
}
delete substitutionFilter;
......@@ -474,7 +522,7 @@ void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le
DefaultCharMapper charMapper(TRUE, mirror);
fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, glyphStorage);
fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, fFilterZeroWidth, glyphStorage);
}
// Input: characters, font?
......@@ -494,6 +542,10 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_
le_int32 glyphCount;
if (fGlyphStorage->getGlyphCount() > 0) {
fGlyphStorage->reset();
}
glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success);
positionGlyphs(*fGlyphStorage, x, y, success);
adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success);
......@@ -525,8 +577,15 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
LayoutEngine *result = NULL;
LETag scriptTag = 0x00000000;
LETag languageTag = 0x00000000;
LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
// Right now, only invoke V2 processing for Devanagari. TODO: Allow more V2 scripts as they are
// properly tested.
if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) {
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
}
else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
switch (scriptCode) {
case bengScriptCode:
case devaScriptCode:
......@@ -538,11 +597,15 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case tamlScriptCode:
case teluScriptCode:
case sinhScriptCode:
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, FALSE, gsubTable, success);
break;
case arabScriptCode:
result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
case hangScriptCode:
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
case haniScriptCode:
......@@ -554,36 +617,35 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case zhtLanguageCode:
case zhsLanguageCode:
if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) {
result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
}
// note: falling through to default case.
default:
result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
}
break;
#if 0
case tibtScriptCode:
result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
#endif
case khmrScriptCode:
result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
default:
result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
}
} else {
const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
if (morphTable != NULL) {
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable);
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable, success);
} else {
switch (scriptCode) {
case bengScriptCode:
......@@ -597,29 +659,38 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case teluScriptCode:
case sinhScriptCode:
{
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
}
case arabScriptCode:
//case hebrScriptCode:
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
//case hebrScriptCode:
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
case thaiScriptCode:
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
result = new ThaiLayoutEngine(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);
result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
}
}
}
if (result && LE_FAILURE(success)) {
delete result;
result = NULL;
}
if (result == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
}
......
......@@ -26,7 +26,7 @@
/*
*
*
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
*
*/
......@@ -58,10 +58,6 @@ le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
le_uint16 comp;
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, ligGlyph))) {
continue;
}
for (comp = 0; comp < compCount; comp += 1) {
if (! glyphIterator->next()) {
break;
......@@ -72,7 +68,7 @@ le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
}
}
if (comp == compCount) {
if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph)))) {
GlyphIterator tempIterator(*glyphIterator);
TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF;
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved
*
*/
......@@ -54,7 +54,7 @@ public:
void add(le_int32 baseIndex, le_int32 mpreIndex);
void apply(LEGlyphStorage &glyphStorage);
void apply(LEGlyphStorage &glyphStorage, LEErrorCode& success);
private:
FixupData *fFixupData;
......
......@@ -74,7 +74,7 @@ void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage)
if (offset != 0) {
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset);
TTGlyphID newGlyph = (TTGlyphID)SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册