提交 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;
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -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
*
*/
......@@ -38,10 +38,12 @@
U_NAMESPACE_BEGIN
#define loclFeatureTag LE_LOCL_FEATURE_TAG
#define initFeatureTag LE_INIT_FEATURE_TAG
#define nuktFeatureTag LE_NUKT_FEATURE_TAG
#define akhnFeatureTag LE_AKHN_FEATURE_TAG
#define rphfFeatureTag LE_RPHF_FEATURE_TAG
#define rkrfFeatureTag LE_RKRF_FEATURE_TAG
#define blwfFeatureTag LE_BLWF_FEATURE_TAG
#define halfFeatureTag LE_HALF_FEATURE_TAG
#define pstfFeatureTag LE_PSTF_FEATURE_TAG
......@@ -51,30 +53,69 @@ U_NAMESPACE_BEGIN
#define abvsFeatureTag LE_ABVS_FEATURE_TAG
#define pstsFeatureTag LE_PSTS_FEATURE_TAG
#define halnFeatureTag LE_HALN_FEATURE_TAG
#define cjctFeatureTag LE_CJCT_FEATURE_TAG
#define blwmFeatureTag LE_BLWM_FEATURE_TAG
#define abvmFeatureTag LE_ABVM_FEATURE_TAG
#define distFeatureTag LE_DIST_FEATURE_TAG
#define rphfFeatureMask 0x80000000UL
#define blwfFeatureMask 0x40000000UL
#define halfFeatureMask 0x20000000UL
#define pstfFeatureMask 0x10000000UL
#define nuktFeatureMask 0x08000000UL
#define akhnFeatureMask 0x04000000UL
#define vatuFeatureMask 0x02000000UL
#define presFeatureMask 0x01000000UL
#define blwsFeatureMask 0x00800000UL
#define abvsFeatureMask 0x00400000UL
#define pstsFeatureMask 0x00200000UL
#define halnFeatureMask 0x00100000UL
#define blwmFeatureMask 0x00080000UL
#define abvmFeatureMask 0x00040000UL
#define distFeatureMask 0x00020000UL
#define initFeatureMask 0x00010000UL
class ReorderingOutput : public UMemory {
#define caltFeatureTag LE_CALT_FEATURE_TAG
#define kernFeatureTag LE_KERN_FEATURE_TAG
#define loclFeatureMask 0x80000000UL
#define rphfFeatureMask 0x40000000UL
#define blwfFeatureMask 0x20000000UL
#define halfFeatureMask 0x10000000UL
#define pstfFeatureMask 0x08000000UL
#define nuktFeatureMask 0x04000000UL
#define akhnFeatureMask 0x02000000UL
#define vatuFeatureMask 0x01000000UL
#define presFeatureMask 0x00800000UL
#define blwsFeatureMask 0x00400000UL
#define abvsFeatureMask 0x00200000UL
#define pstsFeatureMask 0x00100000UL
#define halnFeatureMask 0x00080000UL
#define blwmFeatureMask 0x00040000UL
#define abvmFeatureMask 0x00020000UL
#define distFeatureMask 0x00010000UL
#define initFeatureMask 0x00008000UL
#define cjctFeatureMask 0x00004000UL
#define rkrfFeatureMask 0x00002000UL
#define caltFeatureMask 0x00001000UL
#define kernFeatureMask 0x00000800UL
// Syllable structure bits
#define baseConsonantMask 0x00000400UL
#define consonantMask 0x00000200UL
#define halfConsonantMask 0x00000100UL
#define rephConsonantMask 0x00000080UL
#define matraMask 0x00000040UL
#define vowelModifierMask 0x00000020UL
#define markPositionMask 0x00000018UL
#define postBasePosition 0x00000000UL
#define preBasePosition 0x00000008UL
#define aboveBasePosition 0x00000010UL
#define belowBasePosition 0x00000018UL
#define repositionedGlyphMask 0x00000002UL
#define basicShapingFormsMask ( loclFeatureMask | nuktFeatureMask | akhnFeatureMask | rkrfFeatureMask | blwfFeatureMask | halfFeatureMask | vatuFeatureMask | cjctFeatureMask )
#define positioningFormsMask ( kernFeatureMask | distFeatureMask | abvmFeatureMask | blwmFeatureMask )
#define presentationFormsMask ( presFeatureMask | abvsFeatureMask | blwsFeatureMask | pstsFeatureMask | halnFeatureMask | caltFeatureMask )
#define C_MALAYALAM_VOWEL_SIGN_U 0x0D41
#define C_DOTTED_CIRCLE 0x25CC
#define NO_GLYPH 0xFFFF
// Some level of debate as to the proper value for MAX_CONSONANTS_PER_SYLLABLE. Ticket 5588 states that 4
// is the magic number according to ISCII, but 5 seems to be the more consistent with XP.
#define MAX_CONSONANTS_PER_SYLLABLE 5
#define INDIC_BLOCK_SIZE 0x7F
class IndicReorderingOutput : public UMemory {
private:
le_int32 fSyllableCount;
le_int32 fOutIndex;
LEUnicode *fOutChars;
......@@ -95,8 +136,8 @@ private:
LEUnicode fLengthMark;
le_int32 fLengthMarkIndex;
LEUnicode fVirama;
le_int32 fViramaIndex;
LEUnicode fAlLakuna;
le_int32 fAlLakunaIndex;
FeatureMask fMatraFeatures;
......@@ -113,15 +154,20 @@ private:
le_int32 fSMIndex;
FeatureMask fSMFeatures;
LEUnicode fPreBaseConsonant;
LEUnicode fPreBaseVirama;
le_int32 fPBCIndex;
FeatureMask fPBCFeatures;
void saveMatra(LEUnicode matra, le_int32 matraIndex, IndicClassTable::CharClass matraClass)
{
// FIXME: check if already set, or if not a matra...
if (IndicClassTable::isLengthMark(matraClass)) {
fLengthMark = matra;
fLengthMarkIndex = matraIndex;
} else if (IndicClassTable::isVirama(matraClass)) {
fVirama = matra;
fViramaIndex = matraIndex;
} else if (IndicClassTable::isAlLakuna(matraClass)) {
fAlLakuna = matra;
fAlLakunaIndex = matraIndex;
} else {
switch (matraClass & CF_POS_MASK) {
case CF_POS_BEFORE:
......@@ -152,29 +198,34 @@ private:
}
public:
ReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage, MPreFixups *mpreFixups)
: fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage),
IndicReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage, MPreFixups *mpreFixups)
: fSyllableCount(0), fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage),
fMpre(0), fMpreIndex(0), fMbelow(0), fMbelowIndex(0), fMabove(0), fMaboveIndex(0),
fMpost(0), fMpostIndex(0), fLengthMark(0), fLengthMarkIndex(0), fVirama(0), fViramaIndex(0),
fMpost(0), fMpostIndex(0), fLengthMark(0), fLengthMarkIndex(0), fAlLakuna(0), fAlLakunaIndex(0),
fMatraFeatures(0), fMPreOutIndex(-1), fMPreFixups(mpreFixups),
fVMabove(0), fVMpost(0), fVMIndex(0), fVMFeatures(0),
fSMabove(0), fSMbelow(0), fSMIndex(0), fSMFeatures(0)
fSMabove(0), fSMbelow(0), fSMIndex(0), fSMFeatures(0),
fPreBaseConsonant(0), fPreBaseVirama(0), fPBCIndex(0), fPBCFeatures(0)
{
// nothing else to do...
}
~ReorderingOutput()
~IndicReorderingOutput()
{
// nothing to do here...
}
void reset()
{
fMpre = fMbelow = fMabove = fMpost = fLengthMark = fVirama = 0;
fSyllableCount += 1;
fMpre = fMbelow = fMabove = fMpost = fLengthMark = fAlLakuna = 0;
fMPreOutIndex = -1;
fVMabove = fVMpost = 0;
fSMabove = fSMbelow = 0;
fPreBaseConsonant = fPreBaseVirama = 0;
}
void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask charFeatures)
......@@ -184,11 +235,113 @@ 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;
}
void setFeatures ( le_uint32 charIndex, FeatureMask charFeatures)
{
LEErrorCode success = LE_NO_ERROR;
fGlyphStorage.setAuxData( charIndex, charFeatures, success );
}
FeatureMask getFeatures ( le_uint32 charIndex )
{
LEErrorCode success = LE_NO_ERROR;
return fGlyphStorage.getAuxData(charIndex,success);
}
void decomposeReorderMatras ( const IndicClassTable *classTable, le_int32 beginSyllable, le_int32 nextSyllable, le_int32 inv_count ) {
le_int32 i;
LEErrorCode success = LE_NO_ERROR;
for ( i = beginSyllable ; i < nextSyllable ; i++ ) {
if ( classTable->isMatra(fOutChars[i+inv_count])) {
IndicClassTable::CharClass matraClass = classTable->getCharClass(fOutChars[i+inv_count]);
if ( classTable->isSplitMatra(matraClass)) {
le_int32 saveIndex = fGlyphStorage.getCharIndex(i+inv_count,success);
le_uint32 saveAuxData = fGlyphStorage.getAuxData(i+inv_count,success);
const SplitMatra *splitMatra = classTable->getSplitMatra(matraClass);
int j;
for (j = 0 ; *(splitMatra)[j] != 0 ; j++) {
LEUnicode piece = (*splitMatra)[j];
if ( j == 0 ) {
fOutChars[i+inv_count] = piece;
matraClass = classTable->getCharClass(piece);
} else {
insertCharacter(piece,i+1+inv_count,saveIndex,saveAuxData);
nextSyllable++;
}
}
}
if ((matraClass & CF_POS_MASK) == CF_POS_BEFORE) {
moveCharacter(i+inv_count,beginSyllable+inv_count);
}
}
}
}
void moveCharacter( le_int32 fromPosition, le_int32 toPosition ) {
le_int32 i,saveIndex;
le_uint32 saveAuxData;
LEUnicode saveChar = fOutChars[fromPosition];
LEErrorCode success = LE_NO_ERROR;
LEErrorCode success2 = LE_NO_ERROR;
saveIndex = fGlyphStorage.getCharIndex(fromPosition,success);
saveAuxData = fGlyphStorage.getAuxData(fromPosition,success);
if ( fromPosition > toPosition ) {
for ( i = fromPosition ; i > toPosition ; i-- ) {
fOutChars[i] = fOutChars[i-1];
fGlyphStorage.setCharIndex(i,fGlyphStorage.getCharIndex(i-1,success2),success);
fGlyphStorage.setAuxData(i,fGlyphStorage.getAuxData(i-1,success2), success);
}
} else {
for ( i = fromPosition ; i < toPosition ; i++ ) {
fOutChars[i] = fOutChars[i+1];
fGlyphStorage.setCharIndex(i,fGlyphStorage.getCharIndex(i+1,success2),success);
fGlyphStorage.setAuxData(i,fGlyphStorage.getAuxData(i+1,success2), success);
}
}
fOutChars[toPosition] = saveChar;
fGlyphStorage.setCharIndex(toPosition,saveIndex,success);
fGlyphStorage.setAuxData(toPosition,saveAuxData,success);
}
void insertCharacter( LEUnicode ch, le_int32 toPosition, le_int32 charIndex, le_uint32 auxData ) {
LEErrorCode success = LE_NO_ERROR;
le_int32 i;
fOutIndex += 1;
for ( i = fOutIndex ; i > toPosition ; i--) {
fOutChars[i] = fOutChars[i-1];
fGlyphStorage.setCharIndex(i,fGlyphStorage.getCharIndex(i-1,success),success);
fGlyphStorage.setAuxData(i,fGlyphStorage.getAuxData(i-1,success), success);
}
fOutChars[toPosition] = ch;
fGlyphStorage.setCharIndex(toPosition,charIndex,success);
fGlyphStorage.setAuxData(toPosition,auxData,success);
}
void removeCharacter( le_int32 fromPosition ) {
LEErrorCode success = LE_NO_ERROR;
le_int32 i;
fOutIndex -= 1;
for ( i = fromPosition ; i < fOutIndex ; i--) {
fOutChars[i] = fOutChars[i+1];
fGlyphStorage.setCharIndex(i,fGlyphStorage.getCharIndex(i+1,success),success);
fGlyphStorage.setAuxData(i,fGlyphStorage.getAuxData(i+1,success), success);
}
}
le_bool noteMatra(const IndicClassTable *classTable, LEUnicode matra, le_uint32 matraIndex, FeatureMask matraFeatures, le_bool wordStart)
{
IndicClassTable::CharClass matraClass = classTable->getCharClass(matra);
......@@ -268,6 +421,14 @@ public:
}
}
void notePreBaseConsonant(le_uint32 index,LEUnicode PBConsonant, LEUnicode PBVirama, FeatureMask features)
{
fPBCIndex = index;
fPreBaseConsonant = PBConsonant;
fPreBaseVirama = PBVirama;
fPBCFeatures = features;
}
void noteBaseConsonant()
{
if (fMPreFixups != NULL && fMPreOutIndex >= 0) {
......@@ -275,11 +436,11 @@ public:
}
}
// Handles virama in Sinhala split vowels.
void writeVirama()
// Handles Al-Lakuna in Sinhala split vowels.
void writeAlLakuna()
{
if (fVirama != 0) {
writeChar(fVirama, fViramaIndex, fMatraFeatures);
if (fAlLakuna != 0) {
writeChar(fAlLakuna, fAlLakunaIndex, fMatraFeatures);
}
}
......@@ -347,26 +508,39 @@ public:
}
}
void writePreBaseConsonant()
{
// The TDIL spec says that consonant + virama + RRA should produce a rakar in Malayalam. However,
// it seems that almost none of the fonts for Malayalam are set up to handle this.
// So, we're going to force the issue here by using the rakar as defined with RA in most fonts.
if (fPreBaseConsonant == 0x0d31) { // RRA
fPreBaseConsonant = 0x0d30; // RA
}
if (fPreBaseConsonant != 0) {
writeChar(fPreBaseConsonant, fPBCIndex, fPBCFeatures);
writeChar(fPreBaseVirama,fPBCIndex-1,fPBCFeatures);
}
}
le_int32 getOutputIndex()
{
return fOutIndex;
}
};
enum
{
C_DOTTED_CIRCLE = 0x25CC
};
// TODO: Find better names for these!
#define tagArray4 (nuktFeatureMask | akhnFeatureMask | vatuFeatureMask | presFeatureMask | blwsFeatureMask | abvsFeatureMask | pstsFeatureMask | halnFeatureMask | blwmFeatureMask | abvmFeatureMask | distFeatureMask)
#define tagArray4 (loclFeatureMask | nuktFeatureMask | akhnFeatureMask | vatuFeatureMask | presFeatureMask | blwsFeatureMask | abvsFeatureMask | pstsFeatureMask | halnFeatureMask | blwmFeatureMask | abvmFeatureMask | distFeatureMask)
#define tagArray3 (pstfFeatureMask | tagArray4)
#define tagArray2 (halfFeatureMask | tagArray3)
#define tagArray1 (blwfFeatureMask | tagArray2)
#define tagArray0 (rphfFeatureMask | tagArray1)
static const FeatureMap featureMap[] =
{
static const FeatureMap featureMap[] = {
{loclFeatureTag, loclFeatureMask},
{initFeatureTag, initFeatureMask},
{nuktFeatureTag, nuktFeatureMask},
{akhnFeatureTag, akhnFeatureMask},
......@@ -387,21 +561,47 @@ static const FeatureMap featureMap[] =
static const le_int32 featureCount = LE_ARRAY_SIZE(featureMap);
static const FeatureMap v2FeatureMap[] = {
{loclFeatureTag, loclFeatureMask},
{nuktFeatureTag, nuktFeatureMask},
{akhnFeatureTag, akhnFeatureMask},
{rphfFeatureTag, rphfFeatureMask},
{rkrfFeatureTag, rkrfFeatureMask},
{blwfFeatureTag, blwfFeatureMask},
{halfFeatureTag, halfFeatureMask},
{vatuFeatureTag, vatuFeatureMask},
{cjctFeatureTag, cjctFeatureMask},
{presFeatureTag, presFeatureMask},
{abvsFeatureTag, abvsFeatureMask},
{blwsFeatureTag, blwsFeatureMask},
{pstsFeatureTag, pstsFeatureMask},
{halnFeatureTag, halnFeatureMask},
{caltFeatureTag, caltFeatureMask},
{kernFeatureTag, kernFeatureMask},
{distFeatureTag, distFeatureMask},
{abvmFeatureTag, abvmFeatureMask},
{blwmFeatureTag, blwmFeatureMask}
};
static const le_int32 v2FeatureMapCount = LE_ARRAY_SIZE(v2FeatureMap);
static const le_int8 stateTable[][CC_COUNT] =
{
// xx vm sm iv i2 i3 ct cn nu dv s1 s2 s3 vr zw
{ 1, 1, 1, 5, 8, 11, 3, 2, 1, 5, 9, 5, 1, 1, 1}, // 0 - ground state
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 - exit state
{-1, 6, 1, -1, -1, -1, -1, -1, -1, 5, 9, 5, 5, 4, -1}, // 2 - consonant with nukta
{-1, 6, 1, -1, -1, -1, -1, -1, 2, 5, 9, 5, 5, 4, -1}, // 3 - consonant
{-1, -1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, 7}, // 4 - consonant virama
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 5 - dependent vowels
{-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - vowel mark
{-1, -1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, -1}, // 7 - ZWJ, ZWNJ
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1}, // 8 - independent vowels that can take a virama
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 5, -1, -1}, // 9 - first part of split vowel
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1}, // 10 - second part of split vowel
{-1, 6, 1, -1, -1, -1, -1, -1, -1, 5, 9, 5, 5, 4, -1} // 11 - independent vowels that can take an iv
// xx vm sm iv i2 i3 ct cn nu dv s1 s2 s3 vr zw al
{ 1, 6, 1, 5, 8, 11, 3, 2, 1, 5, 9, 5, 5, 1, 1, 1}, // 0 - ground state
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 - exit state
{-1, 6, 1, -1, -1, -1, -1, -1, -1, 5, 9, 5, 5, 4, 12, -1}, // 2 - consonant with nukta
{-1, 6, 1, -1, -1, -1, -1, -1, 2, 5, 9, 5, 5, 4, 12, 13}, // 3 - consonant
{-1, -1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, 7, -1}, // 4 - consonant virama
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 5 - dependent vowels
{-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - vowel mark
{-1, -1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1}, // 7 - consonant virama ZWJ, consonant ZWJ virama
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1}, // 8 - independent vowels that can take a virama
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 5, -1, -1, -1}, // 9 - first part of split vowel
{-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1}, // 10 - second part of split vowel
{-1, 6, 1, -1, -1, -1, -1, -1, -1, 5, 9, 5, 5, 4, -1, -1}, // 11 - independent vowels that can take an iv
{-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, 7}, // 12 - consonant ZWJ (TODO: Take everything else that can be after a consonant?)
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1} // 13 - consonant al-lakuna ZWJ consonant
};
......@@ -412,14 +612,29 @@ const FeatureMap *IndicReordering::getFeatureMap(le_int32 &count)
return featureMap;
}
const FeatureMap *IndicReordering::getv2FeatureMap(le_int32 &count)
{
count = v2FeatureMapCount;
return v2FeatureMap;
}
le_int32 IndicReordering::findSyllable(const IndicClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount)
{
le_int32 cursor = prev;
le_int8 state = 0;
le_int8 consonant_count = 0;
while (cursor < charCount) {
IndicClassTable::CharClass charClass = classTable->getCharClass(chars[cursor]);
if ( IndicClassTable::isConsonant(charClass) ) {
consonant_count++;
if ( consonant_count > MAX_CONSONANTS_PER_SYLLABLE ) {
break;
}
}
state = stateTable[state][charClass & CF_CLASS_MASK];
if (state < 0) {
......@@ -434,16 +649,24 @@ le_int32 IndicReordering::findSyllable(const IndicClassTable *classTable, const
le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le_int32 scriptCode,
LEUnicode *outChars, LEGlyphStorage &glyphStorage,
MPreFixups **outMPreFixups)
MPreFixups **outMPreFixups, LEErrorCode& success)
{
if (LE_FAILURE(success)) {
return 0;
}
MPreFixups *mpreFixups = NULL;
const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
if (classTable->scriptFlags & SF_MPRE_FIXUP) {
mpreFixups = new MPreFixups(charCount);
if (mpreFixups == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
}
ReorderingOutput output(outChars, glyphStorage, mpreFixups);
IndicReorderingOutput output(outChars, glyphStorage, mpreFixups);
le_int32 i, prev = 0;
le_bool lastInWord = FALSE;
......@@ -458,7 +681,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
output.noteStressMark(classTable, chars[markStart], markStart, tagArray1);
}
if (classTable->isVowelModifier(chars[markStart - 1])) {
if (markStart != prev && classTable->isVowelModifier(chars[markStart - 1])) {
markStart -= 1;
output.noteVowelModifier(classTable, chars[markStart], markStart, tagArray1);
}
......@@ -484,9 +707,20 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
break;
case CC_AL_LAKUNA:
case CC_NUKTA:
output.writeChar(C_DOTTED_CIRCLE, prev, tagArray1);
output.writeChar(chars[prev], prev, tagArray1);
break;
case CC_VIRAMA:
// A lone virama is illegal unless it follows a
// MALAYALAM_VOWEL_SIGN_U. Such a usage is called
// "samvruthokaram".
if (chars[prev - 1] != C_MALAYALAM_VOWEL_SIGN_U) {
output.writeChar(C_DOTTED_CIRCLE, prev, tagArray1);
}
output.writeChar(chars[prev], prev, tagArray1);
break;
......@@ -518,7 +752,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
}
output.writeLengthMark();
output.writeVirama();
output.writeAlLakuna();
if ((classTable->scriptFlags & SF_REPH_AFTER_BELOW) == 0) {
output.writeVMabove();
......@@ -538,7 +772,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
le_int32 baseLimit = prev;
// Check for REPH at front of syllable
if (length > 2 && classTable->isReph(chars[prev]) && classTable->isVirama(chars[prev + 1])) {
if (length > 2 && classTable->isReph(chars[prev]) && classTable->isVirama(chars[prev + 1]) && chars[prev + 2] != C_SIGN_ZWNJ) {
baseLimit += 2;
// Check for eyelash RA, if the script supports it
......@@ -556,35 +790,59 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
lastConsonant -= 1;
}
IndicClassTable::CharClass charClass = CC_RESERVED;
IndicClassTable::CharClass nextClass = CC_RESERVED;
le_int32 baseConsonant = lastConsonant;
le_int32 postBase = lastConsonant + 1;
le_int32 postBaseLimit = classTable->scriptFlags & SF_POST_BASE_LIMIT_MASK;
le_bool seenVattu = FALSE;
le_bool seenBelowBaseForm = FALSE;
le_bool seenPreBaseForm = FALSE;
le_bool hasNukta = FALSE;
le_bool hasBelowBaseForm = FALSE;
le_bool hasPostBaseForm = FALSE;
le_bool hasPreBaseForm = FALSE;
if (postBase < markStart && classTable->isNukta(chars[postBase])) {
charClass = CC_NUKTA;
postBase += 1;
}
while (baseConsonant > baseLimit) {
IndicClassTable::CharClass charClass = classTable->getCharClass(chars[baseConsonant]);
nextClass = charClass;
hasNukta = IndicClassTable::isNukta(nextClass);
charClass = classTable->getCharClass(chars[baseConsonant]);
hasBelowBaseForm = IndicClassTable::hasBelowBaseForm(charClass) && !hasNukta;
hasPostBaseForm = IndicClassTable::hasPostBaseForm(charClass) && !hasNukta;
hasPreBaseForm = IndicClassTable::hasPreBaseForm(charClass) && !hasNukta;
if (IndicClassTable::isConsonant(charClass)) {
if (postBaseLimit == 0 || seenVattu ||
(baseConsonant > baseLimit && !classTable->isVirama(chars[baseConsonant - 1])) ||
!IndicClassTable::hasPostOrBelowBaseForm(charClass)) {
!(hasBelowBaseForm || hasPostBaseForm || hasPreBaseForm)) {
break;
}
seenVattu = IndicClassTable::isVattu(charClass);
// Note any pre-base consonants
if ( baseConsonant == lastConsonant && lastConsonant > 0 &&
hasPreBaseForm && classTable->isVirama(chars[baseConsonant - 1])) {
output.notePreBaseConsonant(lastConsonant,chars[lastConsonant],chars[lastConsonant-1],tagArray2);
seenPreBaseForm = TRUE;
if (IndicClassTable::hasPostBaseForm(charClass)) {
}
// consonants with nuktas are never vattus
seenVattu = IndicClassTable::isVattu(charClass) && !hasNukta;
// consonants with nuktas never have below- or post-base forms
if (hasPostBaseForm) {
if (seenBelowBaseForm) {
break;
}
postBase = baseConsonant;
} else if (IndicClassTable::hasBelowBaseForm(charClass)) {
} else if (hasBelowBaseForm) {
seenBelowBaseForm = TRUE;
}
......@@ -606,20 +864,25 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
}
// write any pre-base consonants
output.writePreBaseConsonant();
le_bool supressVattu = TRUE;
for (i = baseLimit; i < baseConsonant; i += 1) {
LEUnicode ch = chars[i];
// Don't put 'blwf' on first consonant.
FeatureMask features = (i == baseLimit? tagArray2 : tagArray1);
IndicClassTable::CharClass charClass = classTable->getCharClass(ch);
// Don't put 'pstf' or 'blwf' on anything before the base consonant.
FeatureMask features = tagArray1 & ~( pstfFeatureMask | blwfFeatureMask );
charClass = classTable->getCharClass(ch);
nextClass = classTable->getCharClass(chars[i + 1]);
hasNukta = IndicClassTable::isNukta(nextClass);
if (IndicClassTable::isConsonant(charClass)) {
if (IndicClassTable::isVattu(charClass) && supressVattu) {
if (IndicClassTable::isVattu(charClass) && !hasNukta && supressVattu) {
features = tagArray4;
}
supressVattu = IndicClassTable::isVattu(charClass);
supressVattu = IndicClassTable::isVattu(charClass) && !hasNukta;
} else if (IndicClassTable::isVirama(charClass) && chars[i + 1] == C_SIGN_ZWNJ)
{
features = tagArray4;
......@@ -634,7 +897,8 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
bcSpan += 1;
}
if (baseConsonant == lastConsonant && bcSpan < markStart && classTable->isVirama(chars[bcSpan])) {
if (baseConsonant == lastConsonant && bcSpan < markStart &&
(classTable->isVirama(chars[bcSpan]) || classTable->isAlLakuna(chars[bcSpan]))) {
bcSpan += 1;
if (bcSpan < markStart && chars[bcSpan] == C_SIGN_ZWNJ) {
......@@ -658,7 +922,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
}
// write below-base consonants
if (baseConsonant != lastConsonant) {
if (baseConsonant != lastConsonant && !seenPreBaseForm) {
for (i = bcSpan + 1; i < postBase; i += 1) {
output.writeChar(chars[i], i, tagArray1);
}
......@@ -688,7 +952,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
// write post-base consonants
// FIXME: does this put the right tags on post-base consonants?
if (baseConsonant != lastConsonant) {
if (baseConsonant != lastConsonant && !seenPreBaseForm) {
if (postBase <= lastConsonant) {
for (i = postBase; i <= lastConsonant; i += 1) {
output.writeChar(chars[i], i, tagArray3);
......@@ -710,7 +974,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
}
output.writeLengthMark();
output.writeVirama();
output.writeAlLakuna();
// write reph
if ((classTable->scriptFlags & SF_REPH_AFTER_BELOW) == 0) {
......@@ -740,13 +1004,250 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
return output.getOutputIndex();
}
void IndicReordering::adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage)
void IndicReordering::adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success)
{
if (mpreFixups != NULL) {
mpreFixups->apply(glyphStorage);
mpreFixups->apply(glyphStorage, success);
delete mpreFixups;
}
}
void IndicReordering::applyPresentationForms(LEGlyphStorage &glyphStorage, le_int32 count)
{
LEErrorCode success = LE_NO_ERROR;
// This sets us up for 2nd pass of glyph substitution as well as setting the feature masks for the
// GPOS table lookups
for ( le_int32 i = 0 ; i < count ; i++ ) {
glyphStorage.setAuxData(i, ( presentationFormsMask | positioningFormsMask ), success);
}
}
void IndicReordering::finalReordering(LEGlyphStorage &glyphStorage, le_int32 count)
{
LEErrorCode success = LE_NO_ERROR;
// Reposition REPH as appropriate
for ( le_int32 i = 0 ; i < count ; i++ ) {
le_int32 tmpAuxData = glyphStorage.getAuxData(i,success);
LEGlyphID tmpGlyph = glyphStorage.getGlyphID(i,success);
if ( ( tmpGlyph != NO_GLYPH ) && (tmpAuxData & rephConsonantMask) && !(tmpAuxData & repositionedGlyphMask)) {
le_bool targetPositionFound = false;
le_int32 targetPosition = i+1;
le_int32 baseConsonantData;
while (!targetPositionFound) {
tmpGlyph = glyphStorage.getGlyphID(targetPosition,success);
tmpAuxData = glyphStorage.getAuxData(targetPosition,success);
if ( tmpAuxData & baseConsonantMask ) {
baseConsonantData = tmpAuxData;
targetPositionFound = true;
} else {
targetPosition++;
}
}
// Make sure we are not putting the reph into an empty hole
le_bool targetPositionHasGlyph = false;
while (!targetPositionHasGlyph) {
tmpGlyph = glyphStorage.getGlyphID(targetPosition,success);
if ( tmpGlyph != NO_GLYPH ) {
targetPositionHasGlyph = true;
} else {
targetPosition--;
}
}
// Make sure that REPH is positioned after any above base or post base matras
//
le_bool checkMatraDone = false;
le_int32 checkMatraPosition = targetPosition+1;
while ( !checkMatraDone ) {
tmpAuxData = glyphStorage.getAuxData(checkMatraPosition,success);
if ( checkMatraPosition >= count || ( (tmpAuxData ^ baseConsonantData) & LE_GLYPH_GROUP_MASK)) {
checkMatraDone = true;
continue;
}
if ( (tmpAuxData & matraMask) &&
(((tmpAuxData & markPositionMask) == aboveBasePosition) ||
((tmpAuxData & markPositionMask) == postBasePosition))) {
targetPosition = checkMatraPosition;
}
checkMatraPosition++;
}
glyphStorage.moveGlyph(i,targetPosition,repositionedGlyphMask);
}
}
}
le_int32 IndicReordering::v2process(const LEUnicode *chars, le_int32 charCount, le_int32 scriptCode,
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{
const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
DynamicProperties dynProps[INDIC_BLOCK_SIZE];
IndicReordering::getDynamicProperties(dynProps,classTable);
IndicReorderingOutput output(outChars, glyphStorage, NULL);
le_int32 i, firstConsonant, baseConsonant, secondConsonant, inv_count = 0, beginSyllable = 0;
//le_bool lastInWord = FALSE;
while (beginSyllable < charCount) {
le_int32 nextSyllable = findSyllable(classTable, chars, beginSyllable, charCount);
output.reset();
// Find the First Consonant
for ( firstConsonant = beginSyllable ; firstConsonant < nextSyllable ; firstConsonant++ ) {
if ( classTable->isConsonant(chars[firstConsonant]) ) {
break;
}
}
// Find the base consonant
baseConsonant = nextSyllable - 1;
secondConsonant = firstConsonant;
// TODO: Use Dynamic Properties for hasBelowBaseForm and hasPostBaseForm()
while ( baseConsonant > firstConsonant ) {
if ( classTable->isConsonant(chars[baseConsonant]) &&
!classTable->hasBelowBaseForm(chars[baseConsonant]) &&
!classTable->hasPostBaseForm(chars[baseConsonant]) ) {
break;
}
else {
if ( classTable->isConsonant(chars[baseConsonant]) ) {
secondConsonant = baseConsonant;
}
baseConsonant--;
}
}
// If the syllable starts with Ra + Halant ( in a script that has Reph ) and has more than one
// consonant, Ra is excluced from candidates for base consonants
if ( classTable->isReph(chars[beginSyllable]) &&
beginSyllable+1 < nextSyllable && classTable->isVirama(chars[beginSyllable+1]) &&
secondConsonant != firstConsonant) {
baseConsonant = secondConsonant;
}
// Populate the output
for ( i = beginSyllable ; i < nextSyllable ; i++ ) {
// Handle invalid combinartions
if ( classTable->isVirama(chars[beginSyllable]) ||
classTable->isMatra(chars[beginSyllable]) ||
classTable->isVowelModifier(chars[beginSyllable]) ||
classTable->isNukta(chars[beginSyllable]) ) {
output.writeChar(C_DOTTED_CIRCLE,beginSyllable,basicShapingFormsMask);
inv_count++;
}
output.writeChar(chars[i],i, basicShapingFormsMask);
}
// Adjust features and set syllable structure bits
for ( i = beginSyllable ; i < nextSyllable ; i++ ) {
FeatureMask outMask = output.getFeatures(i+inv_count);
FeatureMask saveMask = outMask;
// Since reph can only validly occur at the beginning of a syllable
// We only apply it to the first 2 characters in the syllable, to keep it from
// conflicting with other features ( i.e. rkrf )
// TODO : Use the dynamic property for determining isREPH
if ( i == beginSyllable && i < baseConsonant && classTable->isReph(chars[i]) &&
i+1 < nextSyllable && classTable->isVirama(chars[i+1])) {
outMask |= rphfFeatureMask;
outMask |= rephConsonantMask;
output.setFeatures(i+1+inv_count,outMask);
}
if ( i == baseConsonant ) {
outMask |= baseConsonantMask;
}
if ( classTable->isMatra(chars[i])) {
outMask |= matraMask;
if ( classTable->hasAboveBaseForm(chars[i])) {
outMask |= aboveBasePosition;
} else if ( classTable->hasBelowBaseForm(chars[i])) {
outMask |= belowBasePosition;
}
}
// Don't apply half form to virama that stands alone at the end of a syllable
// to prevent half forms from forming when syllable ends with virama
if ( classTable->isVirama(chars[i]) && (i+1 == nextSyllable) ) {
outMask ^= halfFeatureMask;
if ( classTable->isConsonant(chars[i-1]) ) {
FeatureMask tmp = output.getFeatures(i-1+inv_count);
tmp ^= halfFeatureMask;
output.setFeatures(i-1+inv_count,tmp);
}
}
if ( outMask != saveMask ) {
output.setFeatures(i+inv_count,outMask);
}
}
output.decomposeReorderMatras(classTable,beginSyllable,nextSyllable,inv_count);
beginSyllable = nextSyllable;
}
return output.getOutputIndex();
}
void IndicReordering::getDynamicProperties( DynamicProperties *, const IndicClassTable *classTable ) {
LEUnicode currentChar;
LEUnicode virama;
LEUnicode workChars[2];
LEGlyphStorage workGlyphs;
IndicReorderingOutput workOutput(workChars, workGlyphs, NULL);
//le_int32 offset = 0;
// First find the relevant virama for the script we are dealing with
for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) {
if ( classTable->isVirama(currentChar)) {
virama = currentChar;
break;
}
}
for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) {
if ( classTable->isConsonant(currentChar)) {
workOutput.reset();
}
}
}
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-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
*
*/
......@@ -132,6 +132,14 @@ protected:
*/
le_int32 fTypoFlags;
/**
* <code>TRUE</code> if <code>mapCharsToGlyphs</code> should replace ZWJ / ZWNJ with a glyph
* with no contours.
*
* @internal
*/
le_bool fFilterZeroWidth;
/**
* This constructs an instance for a given font, script and language. Subclass constructors
* must call this constructor.
......@@ -141,13 +149,18 @@ protected:
* @param languageCode - the language for the text
* @param typoFlags - the typographic control flags for the text. Set bit 1 if kerning
* is desired, set bit 2 if ligature formation is desired. Others are reserved.
* @param success - set to an error code if the operation fails
*
* @see LEFontInstance
* @see ScriptAndLanguageTags.h
*
* @internal
*/
LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags);
LayoutEngine(const LEFontInstance *fontInstance,
le_int32 scriptCode,
le_int32 languageCode,
le_int32 typoFlags,
LEErrorCode &success);
/**
* This overrides the default no argument constructor to make it
......@@ -338,7 +351,7 @@ public:
/**
* This method will invoke the layout steps in their correct order by calling
* the computeGlyphs, positionGlyphs and adjustGlyphPosition methods.. It will
* the computeGlyphs, positionGlyphs and adjustGlyphPosition methods. It will
* compute the glyph, character index and position arrays.
*
* @param chars - the input character context
......@@ -352,8 +365,12 @@ public:
*
* @return the number of glyphs in the glyph array
*
* Note; the glyph, character index and position array can be accessed
* using the getter method below.
* Note: The glyph, character index and position array can be accessed
* using the getter methods below.
*
* Note: If you call this method more than once, you must call the reset()
* method first to free the glyph, character index and position arrays
* allocated by the previous call.
*
* @stable ICU 2.8
*/
......@@ -479,7 +496,7 @@ public:
/**
* Override of existing call that provides flags to control typography.
* @draft ICU 3.4
* @stable ICU 3.4
*/
static LayoutEngine *layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typo_flags, LEErrorCode &success);
......
......@@ -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. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -33,7 +33,7 @@
#include "OpenTypeUtilities.h"
#include "LEFontInstance.h"
#include "OpenTypeTables.h"
#include "Features.h"
#include "ICUFeatures.h"
#include "Lookups.h"
#include "ScriptAndLanguage.h"
#include "GlyphDefinitionTables.h"
......@@ -45,8 +45,12 @@
U_NAMESPACE_BEGIN
le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const
const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
}
le_uint16 lookupType = SWAPW(lookupTable->lookupType);
le_uint16 subtableCount = SWAPW(lookupTable->subTableCount);
le_int32 startPosition = glyphIterator->getCurrStreamPosition();
......@@ -55,9 +59,9 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance);
delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
if (delta > 0) {
if (delta > 0 && LE_FAILURE(success)) {
return 1;
}
......@@ -69,8 +73,12 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEFontInstance *fontInstance) const
const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
}
le_int32 glyphCount = glyphStorage.getGlyphCount();
if (lookupSelectArray == NULL) {
......@@ -92,10 +100,9 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
glyphIterator.reset(lookupFlags, selectMask);
while (glyphIterator.findFeatureTag()) {
le_uint32 delta = 1;
while (glyphIterator.next(delta)) {
delta = applyLookupTable(lookupTable, &glyphIterator, fontInstance);
applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
if (LE_FAILURE(success)) {
return 0;
}
}
......@@ -107,12 +114,16 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
}
le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const
const LEFontInstance *fontInstance, LEErrorCode& success) const
{
if (LE_FAILURE(success)) {
return 0;
}
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
GlyphIterator tempIterator(*glyphIterator, lookupFlags);
le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance);
le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
return delta;
}
......@@ -134,7 +145,8 @@ le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, Featur
LookupProcessor::LookupProcessor(const char *baseAddress,
Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures)
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures,
LEErrorCode& success)
: lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL),
lookupOrderArray(NULL), lookupOrderCount(0)
{
......@@ -144,6 +156,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
le_uint16 lookupListCount = 0;
le_uint16 requiredFeatureIndex;
if (LE_FAILURE(success)) {
return;
}
if (scriptListOffset != 0) {
scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
......@@ -170,6 +186,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
if (lookupSelectArray == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return;
}
for (int i = 0; i < lookupListCount; i += 1) {
lookupSelectArray[i] = 0;
......@@ -200,6 +220,10 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
}
lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
if (lookupOrderArray == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return;
}
for (le_int32 f = 0; f < featureMapCount; f += 1) {
FeatureMap fm = featureMap[f];
......@@ -289,6 +313,8 @@ LookupProcessor::LookupProcessor(const char *baseAddress,
LookupProcessor::LookupProcessor()
{
lookupOrderArray = NULL;
lookupSelectArray = NULL;
}
LookupProcessor::~LookupProcessor()
......
......@@ -26,7 +26,7 @@
/*
*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
*
*/
......@@ -59,21 +59,28 @@ struct LookupTable;
class LookupProcessor : public UMemory {
public:
le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance) const;
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
le_uint32 applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
le_uint32 applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 subtableType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const = 0;
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const = 0;
virtual ~LookupProcessor();
protected:
LookupProcessor(const char *baseAddress,
Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures);
Offset scriptListOffset,
Offset featureListOffset,
Offset lookupListOffset,
LETag scriptTag,
LETag languageTag,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool orderFeatures,
LEErrorCode& success);
LookupProcessor();
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved
*
*/
......@@ -65,8 +65,12 @@ void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex)
}
}
void MPreFixups::apply(LEGlyphStorage &glyphStorage)
void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success)
{
if (LE_FAILURE(success)) {
return;
}
for (le_int32 fixup = 0; fixup < fFixupCount; fixup += 1) {
le_int32 baseIndex = fFixupData[fixup].fBaseIndex;
le_int32 mpreIndex = fFixupData[fixup].fMPreIndex;
......@@ -90,6 +94,14 @@ void MPreFixups::apply(LEGlyphStorage &glyphStorage)
le_int32 mpreDest = baseIndex - mpreCount;
LEGlyphID *mpreSave = LE_NEW_ARRAY(LEGlyphID, mpreCount);
le_int32 *indexSave = LE_NEW_ARRAY(le_int32, mpreCount);
if (mpreSave == NULL || indexSave == NULL) {
LE_DELETE_ARRAY(mpreSave);
LE_DELETE_ARRAY(indexSave);
success = LE_MEMORY_ALLOCATION_ERROR;
return;
}
le_int32 i;
for (i = 0; i < mpreCount; i += 1) {
......
......@@ -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;
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -108,11 +108,27 @@ le_int32 MarkToBasePositioningSubtable::process(GlyphIterator *glyphIterator, co
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
if (glyphIterator->isRightToLeft()) {
// FIXME: need similar patch to below; also in MarkToLigature and MarkToMark
// (is there a better way to approach this for all the cases?)
glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX, anchorDiffY, -markAdvance.fX, -markAdvance.fY);
} else {
LEPoint baseAdvance;
fontInstance->getGlyphAdvance(baseGlyph, pixels);
//JK: adjustment needs to account for non-zero advance of any marks between base glyph and current mark
GlyphIterator gi(baseIterator, (le_uint16)0); // copy of baseIterator that won't ignore marks
gi.next(); // point beyond the base glyph
while (gi.getCurrStreamPosition() < glyphIterator->getCurrStreamPosition()) { // for all intervening glyphs (marks)...
LEGlyphID otherMark = gi.getCurrGlyphID();
LEPoint px;
fontInstance->getGlyphAdvance(otherMark, px); // get advance, in case it's non-zero
pixels.fX += px.fX; // and add that to the base glyph's advance
pixels.fY += px.fY;
gi.next();
}
// end of JK patch
fontInstance->pixelsToUnits(pixels, baseAdvance);
glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY);
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
*
*/
......@@ -39,8 +39,12 @@
U_NAMESPACE_BEGIN
le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const
{
if (LE_FAILURE(success)) {
return 0;
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
// If there's a filter, we only want to do the
......@@ -87,7 +91,11 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
}
}
LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount);
LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success);
if (LE_FAILURE(success)) {
return 0;
}
le_int32 insert = 0, direction = 1;
if (glyphIterator->isRightToLeft()) {
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
*
*/
......@@ -56,7 +56,7 @@ struct MultipleSubstitutionSubtable : GlyphSubstitutionSubtable
le_uint16 sequenceCount;
Offset sequenceTableOffsetArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
le_uint32 process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const;
};
U_NAMESPACE_END
......
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -35,8 +35,10 @@
#include "LELanguages.h"
#include "LayoutEngine.h"
#include "CanonShaping.h"
#include "OpenTypeLayoutEngine.h"
#include "ScriptAndLanguageTags.h"
#include "CharSubstitutionFilter.h"
#include "GlyphSubstitutionTables.h"
#include "GlyphDefinitionTables.h"
......@@ -47,6 +49,8 @@
#include "GDEFMarkFilter.h"
#include "KernTable.h"
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine)
......@@ -57,6 +61,8 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine)
#define kernFeatureTag LE_KERN_FEATURE_TAG
#define markFeatureTag LE_MARK_FEATURE_TAG
#define mkmkFeatureTag LE_MKMK_FEATURE_TAG
#define loclFeatureTag LE_LOCL_FEATURE_TAG
#define caltFeatureTag LE_CALT_FEATURE_TAG
// 'dlig' not used at the moment
#define dligFeatureTag 0x646C6967
......@@ -71,8 +77,10 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine)
#define paltFeatureMask 0x08000000UL
#define markFeatureMask 0x04000000UL
#define mkmkFeatureMask 0x02000000UL
#define loclFeatureMask 0x01000000UL
#define caltFeatureMask 0x00800000UL
#define minimalFeatures (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask)
#define minimalFeatures (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask | loclFeatureMask | caltFeatureMask)
#define ligaFeatures (ligaFeatureMask | cligFeatureMask | minimalFeatures)
#define kernFeatures (kernFeatureMask | paltFeatureMask | minimalFeatures)
#define kernAndLigaFeatures (ligaFeatures | kernFeatures)
......@@ -85,14 +93,16 @@ static const FeatureMap featureMap[] =
{kernFeatureTag, kernFeatureMask},
{paltFeatureTag, paltFeatureMask},
{markFeatureTag, markFeatureMask},
{mkmkFeatureTag, mkmkFeatureMask}
{mkmkFeatureTag, mkmkFeatureMask},
{loclFeatureTag, loclFeatureMask},
{caltFeatureTag, caltFeatureMask}
};
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureMask(minimalFeatures),
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureMask(minimalFeatures),
fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE),
fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
{
......@@ -101,7 +111,7 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, l
const GlyphPositioningTableHeader *gposTable = (const GlyphPositioningTableHeader *) getFontTable(gposTableTag);
// todo: switch to more flags and bitfield rather than list of feature tags?
switch (typoFlags) {
switch (typoFlags & ~0x80000000L) {
case 0: break; // default
case 1: fFeatureMask = kernFeatures; break;
case 2: fFeatureMask = ligaFeatures; break;
......@@ -109,11 +119,17 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, l
default: break;
}
if (typoFlags & 0x80000000L) {
fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
}
setScriptAndLanguageTags();
fGDEFTable = (const GlyphDefinitionTableHeader *) getFontTable(gdefTableTag);
if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) {
// JK patch, 2008-05-30 - see Sinhala bug report and LKLUG font
// if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) {
if (gposTable != NULL && gposTable->coversScript(fScriptTag)) {
fGPOSTable = gposTable;
}
}
......@@ -128,8 +144,8 @@ void OpenTypeLayoutEngine::reset()
}
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureOrder(FALSE),
le_int32 typoFlags, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureOrder(FALSE),
fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
{
setScriptAndLanguageTags();
......@@ -137,6 +153,10 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, l
OpenTypeLayoutEngine::~OpenTypeLayoutEngine()
{
if (fTypoFlags & 0x80000000L) {
delete fSubstitutionFilter;
}
reset();
}
......@@ -145,10 +165,25 @@ LETag OpenTypeLayoutEngine::getScriptTag(le_int32 scriptCode)
if (scriptCode < 0 || scriptCode >= scriptCodeCount) {
return 0xFFFFFFFF;
}
return scriptTags[scriptCode];
}
LETag OpenTypeLayoutEngine::getV2ScriptTag(le_int32 scriptCode)
{
switch (scriptCode) {
case bengScriptCode : return bng2ScriptTag;
case devaScriptCode : return dev2ScriptTag;
case gujrScriptCode : return gjr2ScriptTag;
case guruScriptCode : return gur2ScriptTag;
case kndaScriptCode : return knd2ScriptTag;
case mlymScriptCode : return mlm2ScriptTag;
case oryaScriptCode : return ory2ScriptTag;
case tamlScriptCode : return tml2ScriptTag;
case teluScriptCode : return tel2ScriptTag;
default: return nullScriptTag;
}
}
LETag OpenTypeLayoutEngine::getLangSysTag(le_int32 languageCode)
{
if (languageCode < 0 || languageCode >= languageCodeCount) {
......@@ -161,6 +196,7 @@ LETag OpenTypeLayoutEngine::getLangSysTag(le_int32 languageCode)
void OpenTypeLayoutEngine::setScriptAndLanguageTags()
{
fScriptTag = getScriptTag(fScriptCode);
fScriptTagV2 = getV2ScriptTag(fScriptCode);
fLangSysTag = getLangSysTag(fLanguageCode);
}
......@@ -176,20 +212,39 @@ le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_i
return 0;
}
le_int32 outCharCount = LayoutEngine::characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success);
// This is the cheapest way to get mark reordering only for Hebrew.
// We could just do the mark reordering for all scripts, but most
// of them probably don't need it... Another option would be to
// add a HebrewOpenTypeLayoutEngine subclass, but the only thing it
// would need to do is mark reordering, so that seems like overkill.
if (fScriptCode == hebrScriptCode) {
outChars = LE_NEW_ARRAY(LEUnicode, count);
if (outChars == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
if (LE_FAILURE(success)) {
LE_DELETE_ARRAY(outChars);
return 0;
}
glyphStorage.allocateGlyphArray(outCharCount, rightToLeft, success);
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);
}
if (LE_FAILURE(success)) {
return 0;
}
glyphStorage.allocateGlyphArray(count, rightToLeft, success);
glyphStorage.allocateAuxData(success);
for (le_int32 i = 0; i < outCharCount; i += 1) {
for (le_int32 i = 0; i < count; i += 1) {
glyphStorage.setAuxData(i, fFeatureMask, success);
}
return outCharCount;
return count;
}
// Input: characters, tags
......@@ -213,13 +268,45 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32
}
if (fGSUBTable != NULL) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} else {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder);
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
}
}
return count;
}
// Input: characters, tags
// Output: glyphs, char indices
le_int32 OpenTypeLayoutEngine::glyphSubstitution(le_int32 count, le_int32 max, le_bool rightToLeft,
LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return 0;
}
if ( count < 0 || max < 0 ) {
success = LE_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
if (fGSUBTable != NULL) {
if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
} else {
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
}
}
return count;
}
le_int32 OpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
......@@ -251,6 +338,10 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o
outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, fakeGlyphStorage, success);
if (LE_FAILURE(success)) {
return 0;
}
if (outChars != NULL) {
fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success);
LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work...
......@@ -260,6 +351,10 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o
//adjustGlyphs(chars, offset, count, rightToLeft, fakeGlyphs, fakeGlyphCount);
}
if (LE_FAILURE(success)) {
return 0;
}
outGlyphCount = glyphPostProcessing(fakeGlyphStorage, glyphStorage, success);
return outGlyphCount;
......@@ -279,8 +374,11 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
}
le_int32 glyphCount = glyphStorage.getGlyphCount();
if (glyphCount == 0) {
return;
}
if (glyphCount > 0 && fGPOSTable != NULL) {
if (fGPOSTable != NULL) {
GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount);
le_int32 i;
......@@ -303,9 +401,21 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
}
#endif
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance,
if (fGPOSTable != NULL) {
if (fScriptTagV2 != nullScriptTag && fGPOSTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGDEFTable, success, fFontInstance,
fFeatureMap, fFeatureMapCount, fFeatureOrder);
} else {
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, success, fFontInstance,
fFeatureMap, fFeatureMapCount, fFeatureOrder);
}
} else if ( fTypoFlags & 0x1 ) {
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
KernTable kt(fFontInstance, getFontTable(kernTableTag));
kt.process(glyphStorage);
}
float xAdjust = 0, yAdjust = 0;
for (i = 0; i < glyphCount; i += 1) {
......@@ -338,6 +448,21 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
glyphStorage.adjustPosition(glyphCount, xAdjust, -yAdjust, success);
delete adjustments;
} else {
// if there was no GPOS table, maybe there's non-OpenType kerning we can use
LayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
}
LEGlyphID zwnj = fFontInstance->mapCharToGlyph(0x200C);
if (zwnj != 0x0000) {
for (le_int32 g = 0; g < glyphCount; g += 1) {
LEGlyphID glyph = glyphStorage[g];
if (glyph == zwnj) {
glyphStorage[g] = LE_SET_GLYPH(glyph, 0xFFFF);
}
}
}
#if 0
......
......@@ -24,7 +24,7 @@
*/
/*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -67,7 +67,7 @@ U_NAMESPACE_BEGIN
*
* @internal
*/
class OpenTypeLayoutEngine : public LayoutEngine
class U_LAYOUT_API OpenTypeLayoutEngine : public LayoutEngine
{
public:
/**
......@@ -80,6 +80,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 ScriptAndLangaugeTags.h for script and language codes
......@@ -87,7 +88,7 @@ public:
* @internal
*/
OpenTypeLayoutEngine(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
......@@ -96,11 +97,12 @@ public:
* @param fontInstance - the font
* @param scriptCode - the script
* @param langaugeCode - the language
* @param success - set to an error code if the operation fails
*
* @internal
*/
OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags);
le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
......@@ -112,6 +114,8 @@ public:
/**
* A convenience method used to convert the script code into
* the four byte script tag required by OpenType.
* For Indic languages where multiple script tags exist,
* the version 1 (old style) tag is returned.
*
* @param scriptCode - the script code
*
......@@ -120,6 +124,19 @@ public:
* @internal
*/
static LETag getScriptTag(le_int32 scriptCode);
/**
* A convenience method used to convert the script code into
* the four byte script tag required by OpenType.
* For Indic languages where multiple script tags exist,
* the version 2 tag is returned.
*
* @param scriptCode - the script code
*
* @return the four byte script tag
*
* @internal
*/
static LETag getV2ScriptTag(le_int32 scriptCode);
/**
* A convenience method used to convert the langauge code into
......@@ -147,6 +164,13 @@ public:
*/
static UClassID getStaticClassID();
/**
* The array of language tags, indexed by language code.
*
* @internal
*/
static const LETag languageTags[];
private:
/**
......@@ -160,11 +184,6 @@ private:
*/
static const LETag scriptTags[];
/**
* The array of language tags, indexed by language code.
*/
static const LETag languageTags[];
protected:
/**
* A set of "default" features. The default characterProcessing method
......@@ -237,6 +256,13 @@ protected:
*/
LETag fScriptTag;
/**
* The four byte script tag for V2 fonts.
*
* @internal
*/
LETag fScriptTagV2;
/**
* The four byte language tag
*
......@@ -304,6 +330,8 @@ protected:
virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEGlyphStorage &glyphStorage, LEErrorCode &success);
virtual le_int32 glyphSubstitution(le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success);
/**
* This method does any processing necessary to convert "fake"
* glyph indices used by the glyphProcessing method into "real" glyph
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -46,6 +46,8 @@ U_NAMESPACE_BEGIN
typedef le_uint16 Offset;
typedef le_uint8 ATag[4];
typedef le_uint32 fixed32;
#define LE_GLYPH_GROUP_MASK 0x00000001UL
typedef le_uint32 FeatureMask;
#define SWAPT(atag) ((LETag) ((atag[0] << 24) + (atag[1] << 16) + (atag[2] << 8) + atag[3]))
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -111,6 +111,10 @@ le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRan
le_int32 probe = power;
le_int32 range = 0;
if (recordCount == 0) {
return -1;
}
if (SWAPW(records[extra].firstGlyph) <= glyphID) {
range = extra;
}
......
......@@ -101,7 +101,10 @@ le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator,
valueRecord2->adjustPosition(SWAPW(valueFormat2), (char *) this, *glyphIterator, fontInstance);
}
return 2;
// back up glyphIterator so second glyph can be
// first glyph in the next pair
glyphIterator->prev();
return 1;
}
return 0;
......@@ -137,7 +140,10 @@ le_uint32 PairPositioningFormat2Subtable::process(GlyphIterator *glyphIterator,
valueRecord2->adjustPosition(SWAPW(valueFormat2), (const char *) this, *glyphIterator, fontInstance);
}
return 2;
// back up glyphIterator so second glyph can be
// first glyph in the next pair
glyphIterator->prev();
return 1;
}
return 0;
......@@ -145,6 +151,20 @@ le_uint32 PairPositioningFormat2Subtable::process(GlyphIterator *glyphIterator,
const PairValueRecord *PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize) const
{
#if 1
// The OpenType spec. says that the ValueRecord table is
// sorted by secondGlyph. Unfortunately, there are fonts
// around that have an unsorted ValueRecord table.
const PairValueRecord *record = records;
for(le_int32 r = 0; r < recordCount; r += 1) {
if (SWAPW(record->secondGlyph) == glyphID) {
return record;
}
record = (const PairValueRecord *) ((char *) record + recordSize);
}
#else
le_uint8 bit = OpenTypeUtilities::highBit(recordCount);
le_uint16 power = 1 << bit;
le_uint16 extra = (recordCount - power) * recordSize;
......@@ -168,6 +188,7 @@ const PairValueRecord *PairPositioningFormat1Subtable::findPairValueRecord(TTGly
if (SWAPW(record->secondGlyph) == glyphID) {
return record;
}
#endif
return NULL;
}
......
......@@ -26,7 +26,7 @@
/*
*
*
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -56,20 +56,45 @@ const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMa
return (const LangSysTable *) ((char *)this + langSysTableOffset);
}
return 0;
return NULL;
}
const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const
{
/*
* There are some fonts that have a large, bogus value for scriptCount. To try
* and protect against this, we use the offset in the first scriptRecord,
* which we know has to be past the end of the scriptRecordArray, to compute
* a value which is greater than or equal to the actual script count.
*
* Note: normally, the first offset will point to just after the scriptRecordArray,
* but there's no guarantee of this, only that it's *after* the scriptRecordArray.
* Because of this, a binary serach isn't safe, because the new count may include
* data that's not actually in the scriptRecordArray and hence the array will appear
* to be unsorted.
*/
le_uint16 count = SWAPW(scriptCount);
Offset scriptTableOffset =
OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count);
le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER;
Offset scriptTableOffset = 0;
if (count > limit) {
// the scriptCount value is bogus; do a linear search
// because limit may still be too large.
for(le_int32 s = 0; s < limit; s += 1) {
if (SWAPT(scriptRecordArray[s].tag) == scriptTag) {
scriptTableOffset = SWAPW(scriptRecordArray[s].offset);
break;
}
}
} else {
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count);
}
if (scriptTableOffset != 0) {
return (const ScriptTable *) ((char *)this + scriptTableOffset);
}
return 0;
return NULL;
}
const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const
......@@ -77,7 +102,7 @@ const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languag
const ScriptTable *scriptTable = findScript(scriptTag);
if (scriptTable == 0) {
return 0;
return NULL;
}
return scriptTable->findLanguage(languageTag, exactMatch);
......
......@@ -25,10 +25,12 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004. 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
*/
#include "LETypes.h"
......@@ -39,13 +41,13 @@ U_NAMESPACE_BEGIN
const LETag OpenTypeLayoutEngine::scriptTags[] = {
zyyyScriptTag, /* 'zyyy' (COMMON) */
qaaiScriptTag, /* 'qaai' (INHERITED) */
zinhScriptTag, /* 'zinh' (INHERITED) */
arabScriptTag, /* 'arab' (ARABIC) */
armnScriptTag, /* 'armn' (ARMENIAN) */
bengScriptTag, /* 'beng' (BENGALI) */
bopoScriptTag, /* 'bopo' (BOPOMOFO) */
cherScriptTag, /* 'cher' (CHEROKEE) */
qaacScriptTag, /* 'qaac' (COPTIC) */
coptScriptTag, /* 'copt' (COPTIC) */
cyrlScriptTag, /* 'cyrl' (CYRILLIC) */
dsrtScriptTag, /* 'dsrt' (DESERET) */
devaScriptTag, /* 'deva' (DEVANAGARI) */
......@@ -62,7 +64,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
kndaScriptTag, /* 'knda' (KANNADA) */
kanaScriptTag, /* 'kana' (KATAKANA) */
khmrScriptTag, /* 'khmr' (KHMER) */
laooScriptTag, /* 'laoo' (LAO) */
laooScriptTag, /* 'lao ' (LAO) */
latnScriptTag, /* 'latn' (LATIN) */
mlymScriptTag, /* 'mlym' (MALAYALAM) */
mongScriptTag, /* 'mong' (MONGOLIAN) */
......@@ -79,7 +81,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
thaiScriptTag, /* 'thai' (THAI) */
tibtScriptTag, /* 'tibt' (TIBETAN) */
cansScriptTag, /* 'cans' (CANADIAN_ABORIGINAL) */
yiiiScriptTag, /* 'yiii' (YI) */
yiiiScriptTag, /* 'yi ' (YI) */
tglgScriptTag, /* 'tglg' (TAGALOG) */
hanoScriptTag, /* 'hano' (HANUNOO) */
buhdScriptTag, /* 'buhd' (BUHID) */
......@@ -92,7 +94,99 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = {
shawScriptTag, /* 'shaw' (SHAVIAN) */
taleScriptTag, /* 'tale' (TAI_LE) */
ugarScriptTag, /* 'ugar' (UGARITIC) */
hrktScriptTag /* 'hrkt' (KATAKANA_OR_HIRAGANA) */
hrktScriptTag, /* 'hrkt' (KATAKANA_OR_HIRAGANA) */
bugiScriptTag, /* 'bugi' (BUGINESE) */
glagScriptTag, /* 'glag' (GLAGOLITIC) */
kharScriptTag, /* 'khar' (KHAROSHTHI) */
syloScriptTag, /* 'sylo' (SYLOTI_NAGRI) */
taluScriptTag, /* 'talu' (NEW_TAI_LUE) */
tfngScriptTag, /* 'tfng' (TIFINAGH) */
xpeoScriptTag, /* 'xpeo' (OLD_PERSIAN) */
baliScriptTag, /* 'bali' (BALINESE) */
batkScriptTag, /* 'batk' (BATAK) */
blisScriptTag, /* 'blis' (BLIS) */
brahScriptTag, /* 'brah' (BRAHMI) */
chamScriptTag, /* 'cham' (CHAM) */
cirtScriptTag, /* 'cirt' (CIRT) */
cyrsScriptTag, /* 'cyrs' (CYRS) */
egydScriptTag, /* 'egyd' (EGYD) */
egyhScriptTag, /* 'egyh' (EGYH) */
egypScriptTag, /* 'egyp' (EGYPTIAN_HIEROGLYPHS) */
geokScriptTag, /* 'geok' (GEOK) */
hansScriptTag, /* 'hans' (HANS) */
hantScriptTag, /* 'hant' (HANT) */
hmngScriptTag, /* 'hmng' (HMNG) */
hungScriptTag, /* 'hung' (HUNG) */
indsScriptTag, /* 'inds' (INDS) */
javaScriptTag, /* 'java' (JAVANESE) */
kaliScriptTag, /* 'kali' (KAYAH_LI) */
latfScriptTag, /* 'latf' (LATF) */
latgScriptTag, /* 'latg' (LATG) */
lepcScriptTag, /* 'lepc' (LEPCHA) */
linaScriptTag, /* 'lina' (LINA) */
mandScriptTag, /* 'mand' (MANDAIC) */
mayaScriptTag, /* 'maya' (MAYA) */
meroScriptTag, /* 'mero' (MERO) */
nkooScriptTag, /* 'nko ' (NKO) */
orkhScriptTag, /* 'orkh' (OLD_TURKIC) */
permScriptTag, /* 'perm' (PERM) */
phagScriptTag, /* 'phag' (PHAGS_PA) */
phnxScriptTag, /* 'phnx' (PHOENICIAN) */
plrdScriptTag, /* 'plrd' (PLRD) */
roroScriptTag, /* 'roro' (RORO) */
saraScriptTag, /* 'sara' (SARA) */
syreScriptTag, /* 'syre' (SYRE) */
syrjScriptTag, /* 'syrj' (SYRJ) */
syrnScriptTag, /* 'syrn' (SYRN) */
tengScriptTag, /* 'teng' (TENG) */
vaiiScriptTag, /* 'vai ' (VAI) */
vispScriptTag, /* 'visp' (VISP) */
xsuxScriptTag, /* 'xsux' (CUNEIFORM) */
zxxxScriptTag, /* 'zxxx' (ZXXX) */
zzzzScriptTag, /* 'zzzz' (UNKNOWN) */
cariScriptTag, /* 'cari' (CARIAN) */
jpanScriptTag, /* 'jpan' (JPAN) */
lanaScriptTag, /* 'lana' (TAI_THAM) */
lyciScriptTag, /* 'lyci' (LYCIAN) */
lydiScriptTag, /* 'lydi' (LYDIAN) */
olckScriptTag, /* 'olck' (OL_CHIKI) */
rjngScriptTag, /* 'rjng' (REJANG) */
saurScriptTag, /* 'saur' (SAURASHTRA) */
sgnwScriptTag, /* 'sgnw' (SGNW) */
sundScriptTag, /* 'sund' (SUNDANESE) */
moonScriptTag, /* 'moon' (MOON) */
mteiScriptTag, /* 'mtei' (MEETEI_MAYEK) */
armiScriptTag, /* 'armi' (IMPERIAL_ARAMAIC) */
avstScriptTag, /* 'avst' (AVESTAN) */
cakmScriptTag, /* 'cakm' (CAKM) */
koreScriptTag, /* 'kore' (KORE) */
kthiScriptTag, /* 'kthi' (KAITHI) */
maniScriptTag, /* 'mani' (MANI) */
phliScriptTag, /* 'phli' (INSCRIPTIONAL_PAHLAVI) */
phlpScriptTag, /* 'phlp' (PHLP) */
phlvScriptTag, /* 'phlv' (PHLV) */
prtiScriptTag, /* 'prti' (INSCRIPTIONAL_PARTHIAN) */
samrScriptTag, /* 'samr' (SAMARITAN) */
tavtScriptTag, /* 'tavt' (TAI_VIET) */
zmthScriptTag, /* 'zmth' (ZMTH) */
zsymScriptTag, /* 'zsym' (ZSYM) */
bamuScriptTag, /* 'bamu' (BAMUM) */
lisuScriptTag, /* 'lisu' (LISU) */
nkgbScriptTag, /* 'nkgb' (NKGB) */
sarbScriptTag, /* 'sarb' (OLD_SOUTH_ARABIAN) */
bassScriptTag, /* 'bass' (BASS) */
duplScriptTag, /* 'dupl' (DUPL) */
elbaScriptTag, /* 'elba' (ELBA) */
granScriptTag, /* 'gran' (GRAN) */
kpelScriptTag, /* 'kpel' (KPEL) */
lomaScriptTag, /* 'loma' (LOMA) */
mendScriptTag, /* 'mend' (MEND) */
mercScriptTag, /* 'merc' (MERC) */
narbScriptTag, /* 'narb' (NARB) */
nbatScriptTag, /* 'nbat' (NBAT) */
palmScriptTag, /* 'palm' (PALM) */
sindScriptTag, /* 'sind' (SIND) */
waraScriptTag /* 'wara' (WARA) */
};
const LETag OpenTypeLayoutEngine::languageTags[] = {
......@@ -125,7 +219,49 @@ const LETag OpenTypeLayoutEngine::languageTags[] = {
urdLanguageTag, /* 'URD' (Urdu) */
zhpLanguageTag, /* 'ZHP' (Chinese (Phonetic)) */
zhsLanguageTag, /* 'ZHS' (Chinese (Simplified)) */
zhtLanguageTag /* 'ZHT' (Chinese (Traditional)) */
zhtLanguageTag, /* 'ZHT' (Chinese (Traditional)) */
afkLanguageTag, /* 'AFK' (Afrikaans) */
belLanguageTag, /* 'BEL' (Belarussian) */
bgrLanguageTag, /* 'BGR' (Bulgarian) */
catLanguageTag, /* 'CAT' (Catalan) */
cheLanguageTag, /* 'CHE' (Chechen) */
copLanguageTag, /* 'COP' (Coptic) */
csyLanguageTag, /* 'CSY' (Czech) */
danLanguageTag, /* 'DAN' (Danish) */
deuLanguageTag, /* 'DEU' (German) */
dznLanguageTag, /* 'DZN' (Dzongkha) */
ellLanguageTag, /* 'ELL' (Greek) */
engLanguageTag, /* 'ENG' (English) */
espLanguageTag, /* 'ESP' (Spanish) */
etiLanguageTag, /* 'ETI' (Estonian) */
euqLanguageTag, /* 'EUQ' (Basque) */
finLanguageTag, /* 'FIN' (Finnish) */
fraLanguageTag, /* 'FRA' (French) */
gaeLanguageTag, /* 'GAE' (Gaelic) */
hauLanguageTag, /* 'HAU' (Hausa) */
hrvLanguageTag, /* 'HRV' (Croation) */
hunLanguageTag, /* 'HUN' (Hungarian) */
hyeLanguageTag, /* 'HYE' (Armenian) */
indLanguageTag, /* 'IND' (Indonesian) */
itaLanguageTag, /* 'ITA' (Italian) */
khmLanguageTag, /* 'KHM' (Khmer) */
mngLanguageTag, /* 'MNG' (Mongolian) */
mtsLanguageTag, /* 'MTS' (Maltese) */
nepLanguageTag, /* 'NEP' (Nepali) */
nldLanguageTag, /* 'NLD' (Dutch) */
pasLanguageTag, /* 'PAS' (Pashto) */
plkLanguageTag, /* 'PLK' (Polish) */
ptgLanguageTag, /* 'PTG' (Portuguese) */
romLanguageTag, /* 'ROM' (Romanian) */
rusLanguageTag, /* 'RUS' (Russian) */
skyLanguageTag, /* 'SKY' (Slovak) */
slvLanguageTag, /* 'SLV' (Slovenian) */
sqiLanguageTag, /* 'SQI' (Albanian) */
srbLanguageTag, /* 'SRB' (Serbian) */
sveLanguageTag, /* 'SVE' (Swedish) */
tibLanguageTag, /* 'TIB' (Tibetan) */
trkLanguageTag, /* 'TRK' (Turkish) */
welLanguageTag /* 'WEL' (Welsh) */
};
U_NAMESPACE_END
......@@ -25,10 +25,12 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004. 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 __SCRIPTANDLANGUAGES_H
......@@ -36,55 +38,64 @@
#include "LETypes.h"
U_NAMESPACE_BEGIN
/**
* \file
* \internal
*/
U_NAMESPACE_BEGIN
const LETag zyyyScriptTag = 0x7A797979; /* 'zyyy' (COMMON) */
const LETag qaaiScriptTag = 0x71616169; /* 'qaai' (INHERITED) */
const LETag zinhScriptTag = 0x7A696E68; /* 'zinh' (INHERITED) */
const LETag arabScriptTag = 0x61726162; /* 'arab' (ARABIC) */
const LETag armnScriptTag = 0x61726D6E; /* 'armn' (ARMENIAN) */
const LETag bengScriptTag = 0x62656E67; /* 'beng' (BENGALI) */
const LETag bng2ScriptTag = 0x626E6732; /* 'bng2' (BENGALI v.2) (manually added) */
const LETag bopoScriptTag = 0x626F706F; /* 'bopo' (BOPOMOFO) */
const LETag cherScriptTag = 0x63686572; /* 'cher' (CHEROKEE) */
const LETag qaacScriptTag = 0x71616163; /* 'qaac' (COPTIC) */
const LETag coptScriptTag = 0x636F7074; /* 'copt' (COPTIC) */
const LETag cyrlScriptTag = 0x6379726C; /* 'cyrl' (CYRILLIC) */
const LETag dsrtScriptTag = 0x64737274; /* 'dsrt' (DESERET) */
const LETag devaScriptTag = 0x64657661; /* 'deva' (DEVANAGARI) */
const LETag dev2ScriptTag = 0x64657632; /* 'dev2' (DEVANAGARI v.2) (manually added) */
const LETag ethiScriptTag = 0x65746869; /* 'ethi' (ETHIOPIC) */
const LETag georScriptTag = 0x67656F72; /* 'geor' (GEORGIAN) */
const LETag gothScriptTag = 0x676F7468; /* 'goth' (GOTHIC) */
const LETag grekScriptTag = 0x6772656B; /* 'grek' (GREEK) */
const LETag gujrScriptTag = 0x67756A72; /* 'gujr' (GUJARATI) */
const LETag gjr2ScriptTag = 0x676A7232; /* 'gjr2' (GUJARATI v.2) (manually added) */
const LETag guruScriptTag = 0x67757275; /* 'guru' (GURMUKHI) */
const LETag gur2ScriptTag = 0x67757232; /* 'gur2' (GURMUKHI v.2) (manually added) */
const LETag haniScriptTag = 0x68616E69; /* 'hani' (HAN) */
const LETag hangScriptTag = 0x68616E67; /* 'hang' (HANGUL) */
const LETag hebrScriptTag = 0x68656272; /* 'hebr' (HEBREW) */
const LETag hiraScriptTag = 0x68697261; /* 'hira' (HIRAGANA) */
const LETag kndaScriptTag = 0x6B6E6461; /* 'knda' (KANNADA) */
const LETag knd2ScriptTag = 0x6B6E6432; /* 'knd2' (KANNADA v.2) (manually added) */
const LETag kanaScriptTag = 0x6B616E61; /* 'kana' (KATAKANA) */
const LETag khmrScriptTag = 0x6B686D72; /* 'khmr' (KHMER) */
const LETag laooScriptTag = 0x6C616F6F; /* 'laoo' (LAO) */
const LETag laooScriptTag = 0x6C616F20; /* 'lao ' (LAO) */
const LETag latnScriptTag = 0x6C61746E; /* 'latn' (LATIN) */
const LETag mlymScriptTag = 0x6D6C796D; /* 'mlym' (MALAYALAM) */
const LETag mlm2ScriptTag = 0x6D6C6D32; /* 'mlm2' (MALAYALAM v.2) (manually added) */
const LETag mongScriptTag = 0x6D6F6E67; /* 'mong' (MONGOLIAN) */
const LETag mymrScriptTag = 0x6D796D72; /* 'mymr' (MYANMAR) */
const LETag ogamScriptTag = 0x6F67616D; /* 'ogam' (OGHAM) */
const LETag italScriptTag = 0x6974616C; /* 'ital' (OLD_ITALIC) */
const LETag oryaScriptTag = 0x6F727961; /* 'orya' (ORIYA) */
const LETag ory2ScriptTag = 0x6F727932; /* 'ory2' (ORIYA v.2) (manually added) */
const LETag runrScriptTag = 0x72756E72; /* 'runr' (RUNIC) */
const LETag sinhScriptTag = 0x73696E68; /* 'sinh' (SINHALA) */
const LETag syrcScriptTag = 0x73797263; /* 'syrc' (SYRIAC) */
const LETag tamlScriptTag = 0x74616D6C; /* 'taml' (TAMIL) */
const LETag tml2ScriptTag = 0x746D6C32; /* 'tml2' (TAMIL v.2) (manually added) */
const LETag teluScriptTag = 0x74656C75; /* 'telu' (TELUGU) */
const LETag tel2ScriptTag = 0x74656C32; /* 'tel2' (TELUGU v.2) (manually added) */
const LETag thaaScriptTag = 0x74686161; /* 'thaa' (THAANA) */
const LETag thaiScriptTag = 0x74686169; /* 'thai' (THAI) */
const LETag tibtScriptTag = 0x74696274; /* 'tibt' (TIBETAN) */
const LETag cansScriptTag = 0x63616E73; /* 'cans' (CANADIAN_ABORIGINAL) */
const LETag yiiiScriptTag = 0x79696969; /* 'yiii' (YI) */
const LETag yiiiScriptTag = 0x79692020; /* 'yi ' (YI) */
const LETag tglgScriptTag = 0x74676C67; /* 'tglg' (TAGALOG) */
const LETag hanoScriptTag = 0x68616E6F; /* 'hano' (HANUNOO) */
const LETag buhdScriptTag = 0x62756864; /* 'buhd' (BUHID) */
......@@ -98,6 +109,98 @@ const LETag shawScriptTag = 0x73686177; /* 'shaw' (SHAVIAN) */
const LETag taleScriptTag = 0x74616C65; /* 'tale' (TAI_LE) */
const LETag ugarScriptTag = 0x75676172; /* 'ugar' (UGARITIC) */
const LETag hrktScriptTag = 0x68726B74; /* 'hrkt' (KATAKANA_OR_HIRAGANA) */
const LETag bugiScriptTag = 0x62756769; /* 'bugi' (BUGINESE) */
const LETag glagScriptTag = 0x676C6167; /* 'glag' (GLAGOLITIC) */
const LETag kharScriptTag = 0x6B686172; /* 'khar' (KHAROSHTHI) */
const LETag syloScriptTag = 0x73796C6F; /* 'sylo' (SYLOTI_NAGRI) */
const LETag taluScriptTag = 0x74616C75; /* 'talu' (NEW_TAI_LUE) */
const LETag tfngScriptTag = 0x74666E67; /* 'tfng' (TIFINAGH) */
const LETag xpeoScriptTag = 0x7870656F; /* 'xpeo' (OLD_PERSIAN) */
const LETag baliScriptTag = 0x62616C69; /* 'bali' (BALINESE) */
const LETag batkScriptTag = 0x6261746B; /* 'batk' (BATAK) */
const LETag blisScriptTag = 0x626C6973; /* 'blis' (BLIS) */
const LETag brahScriptTag = 0x62726168; /* 'brah' (BRAHMI) */
const LETag chamScriptTag = 0x6368616D; /* 'cham' (CHAM) */
const LETag cirtScriptTag = 0x63697274; /* 'cirt' (CIRT) */
const LETag cyrsScriptTag = 0x63797273; /* 'cyrs' (CYRS) */
const LETag egydScriptTag = 0x65677964; /* 'egyd' (EGYD) */
const LETag egyhScriptTag = 0x65677968; /* 'egyh' (EGYH) */
const LETag egypScriptTag = 0x65677970; /* 'egyp' (EGYPTIAN_HIEROGLYPHS) */
const LETag geokScriptTag = 0x67656F6B; /* 'geok' (GEOK) */
const LETag hansScriptTag = 0x68616E73; /* 'hans' (HANS) */
const LETag hantScriptTag = 0x68616E74; /* 'hant' (HANT) */
const LETag hmngScriptTag = 0x686D6E67; /* 'hmng' (HMNG) */
const LETag hungScriptTag = 0x68756E67; /* 'hung' (HUNG) */
const LETag indsScriptTag = 0x696E6473; /* 'inds' (INDS) */
const LETag javaScriptTag = 0x6A617661; /* 'java' (JAVANESE) */
const LETag kaliScriptTag = 0x6B616C69; /* 'kali' (KAYAH_LI) */
const LETag latfScriptTag = 0x6C617466; /* 'latf' (LATF) */
const LETag latgScriptTag = 0x6C617467; /* 'latg' (LATG) */
const LETag lepcScriptTag = 0x6C657063; /* 'lepc' (LEPCHA) */
const LETag linaScriptTag = 0x6C696E61; /* 'lina' (LINA) */
const LETag mandScriptTag = 0x6D616E64; /* 'mand' (MANDAIC) */
const LETag mayaScriptTag = 0x6D617961; /* 'maya' (MAYA) */
const LETag meroScriptTag = 0x6D65726F; /* 'mero' (MERO) */
const LETag nkooScriptTag = 0x6E6B6F20; /* 'nko ' (NKO) */
const LETag orkhScriptTag = 0x6F726B68; /* 'orkh' (OLD_TURKIC) */
const LETag permScriptTag = 0x7065726D; /* 'perm' (PERM) */
const LETag phagScriptTag = 0x70686167; /* 'phag' (PHAGS_PA) */
const LETag phnxScriptTag = 0x70686E78; /* 'phnx' (PHOENICIAN) */
const LETag plrdScriptTag = 0x706C7264; /* 'plrd' (PLRD) */
const LETag roroScriptTag = 0x726F726F; /* 'roro' (RORO) */
const LETag saraScriptTag = 0x73617261; /* 'sara' (SARA) */
const LETag syreScriptTag = 0x73797265; /* 'syre' (SYRE) */
const LETag syrjScriptTag = 0x7379726A; /* 'syrj' (SYRJ) */
const LETag syrnScriptTag = 0x7379726E; /* 'syrn' (SYRN) */
const LETag tengScriptTag = 0x74656E67; /* 'teng' (TENG) */
const LETag vaiiScriptTag = 0x76616920; /* 'vai ' (VAI) */
const LETag vispScriptTag = 0x76697370; /* 'visp' (VISP) */
const LETag xsuxScriptTag = 0x78737578; /* 'xsux' (CUNEIFORM) */
const LETag zxxxScriptTag = 0x7A787878; /* 'zxxx' (ZXXX) */
const LETag zzzzScriptTag = 0x7A7A7A7A; /* 'zzzz' (UNKNOWN) */
const LETag cariScriptTag = 0x63617269; /* 'cari' (CARIAN) */
const LETag jpanScriptTag = 0x6A70616E; /* 'jpan' (JPAN) */
const LETag lanaScriptTag = 0x6C616E61; /* 'lana' (TAI_THAM) */
const LETag lyciScriptTag = 0x6C796369; /* 'lyci' (LYCIAN) */
const LETag lydiScriptTag = 0x6C796469; /* 'lydi' (LYDIAN) */
const LETag olckScriptTag = 0x6F6C636B; /* 'olck' (OL_CHIKI) */
const LETag rjngScriptTag = 0x726A6E67; /* 'rjng' (REJANG) */
const LETag saurScriptTag = 0x73617572; /* 'saur' (SAURASHTRA) */
const LETag sgnwScriptTag = 0x73676E77; /* 'sgnw' (SGNW) */
const LETag sundScriptTag = 0x73756E64; /* 'sund' (SUNDANESE) */
const LETag moonScriptTag = 0x6D6F6F6E; /* 'moon' (MOON) */
const LETag mteiScriptTag = 0x6D746569; /* 'mtei' (MEETEI_MAYEK) */
const LETag armiScriptTag = 0x61726D69; /* 'armi' (IMPERIAL_ARAMAIC) */
const LETag avstScriptTag = 0x61767374; /* 'avst' (AVESTAN) */
const LETag cakmScriptTag = 0x63616B6D; /* 'cakm' (CAKM) */
const LETag koreScriptTag = 0x6B6F7265; /* 'kore' (KORE) */
const LETag kthiScriptTag = 0x6B746869; /* 'kthi' (KAITHI) */
const LETag maniScriptTag = 0x6D616E69; /* 'mani' (MANI) */
const LETag phliScriptTag = 0x70686C69; /* 'phli' (INSCRIPTIONAL_PAHLAVI) */
const LETag phlpScriptTag = 0x70686C70; /* 'phlp' (PHLP) */
const LETag phlvScriptTag = 0x70686C76; /* 'phlv' (PHLV) */
const LETag prtiScriptTag = 0x70727469; /* 'prti' (INSCRIPTIONAL_PARTHIAN) */
const LETag samrScriptTag = 0x73616D72; /* 'samr' (SAMARITAN) */
const LETag tavtScriptTag = 0x74617674; /* 'tavt' (TAI_VIET) */
const LETag zmthScriptTag = 0x7A6D7468; /* 'zmth' (ZMTH) */
const LETag zsymScriptTag = 0x7A73796D; /* 'zsym' (ZSYM) */
const LETag bamuScriptTag = 0x62616D75; /* 'bamu' (BAMUM) */
const LETag lisuScriptTag = 0x6C697375; /* 'lisu' (LISU) */
const LETag nkgbScriptTag = 0x6E6B6762; /* 'nkgb' (NKGB) */
const LETag sarbScriptTag = 0x73617262; /* 'sarb' (OLD_SOUTH_ARABIAN) */
const LETag bassScriptTag = 0x62617373; /* 'bass' (BASS) */
const LETag duplScriptTag = 0x6475706C; /* 'dupl' (DUPL) */
const LETag elbaScriptTag = 0x656C6261; /* 'elba' (ELBA) */
const LETag granScriptTag = 0x6772616E; /* 'gran' (GRAN) */
const LETag kpelScriptTag = 0x6B70656C; /* 'kpel' (KPEL) */
const LETag lomaScriptTag = 0x6C6F6D61; /* 'loma' (LOMA) */
const LETag mendScriptTag = 0x6D656E64; /* 'mend' (MEND) */
const LETag mercScriptTag = 0x6D657263; /* 'merc' (MERC) */
const LETag narbScriptTag = 0x6E617262; /* 'narb' (NARB) */
const LETag nbatScriptTag = 0x6E626174; /* 'nbat' (NBAT) */
const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */
const LETag sindScriptTag = 0x73696E64; /* 'sind' (SIND) */
const LETag waraScriptTag = 0x77617261; /* 'wara' (WARA) */
const LETag nullScriptTag = 0x00000000; /* '' (NULL) */
......@@ -132,6 +235,48 @@ const LETag urdLanguageTag = 0x55524420; /* 'URD' (Urdu) */
const LETag zhpLanguageTag = 0x5A485020; /* 'ZHP' (Chinese (Phonetic)) */
const LETag zhsLanguageTag = 0x5A485320; /* 'ZHS' (Chinese (Simplified)) */
const LETag zhtLanguageTag = 0x5A485420; /* 'ZHT' (Chinese (Traditional)) */
const LETag afkLanguageTag = 0x41464B20; /* 'AFK' (Afrikaans) */
const LETag belLanguageTag = 0x42454C20; /* 'BEL' (Belarussian) */
const LETag bgrLanguageTag = 0x42475220; /* 'BGR' (Bulgarian) */
const LETag catLanguageTag = 0x43415420; /* 'CAT' (Catalan) */
const LETag cheLanguageTag = 0x43484520; /* 'CHE' (Chechen) */
const LETag copLanguageTag = 0x434F5020; /* 'COP' (Coptic) */
const LETag csyLanguageTag = 0x43535920; /* 'CSY' (Czech) */
const LETag danLanguageTag = 0x44414E20; /* 'DAN' (Danish) */
const LETag deuLanguageTag = 0x44455520; /* 'DEU' (German) */
const LETag dznLanguageTag = 0x445A4E20; /* 'DZN' (Dzongkha) */
const LETag ellLanguageTag = 0x454C4C20; /* 'ELL' (Greek) */
const LETag engLanguageTag = 0x454E4720; /* 'ENG' (English) */
const LETag espLanguageTag = 0x45535020; /* 'ESP' (Spanish) */
const LETag etiLanguageTag = 0x45544920; /* 'ETI' (Estonian) */
const LETag euqLanguageTag = 0x45555120; /* 'EUQ' (Basque) */
const LETag finLanguageTag = 0x46494E20; /* 'FIN' (Finnish) */
const LETag fraLanguageTag = 0x46524120; /* 'FRA' (French) */
const LETag gaeLanguageTag = 0x47414520; /* 'GAE' (Gaelic) */
const LETag hauLanguageTag = 0x48415520; /* 'HAU' (Hausa) */
const LETag hrvLanguageTag = 0x48525620; /* 'HRV' (Croation) */
const LETag hunLanguageTag = 0x48554E20; /* 'HUN' (Hungarian) */
const LETag hyeLanguageTag = 0x48594520; /* 'HYE' (Armenian) */
const LETag indLanguageTag = 0x494E4420; /* 'IND' (Indonesian) */
const LETag itaLanguageTag = 0x49544120; /* 'ITA' (Italian) */
const LETag khmLanguageTag = 0x4B484D20; /* 'KHM' (Khmer) */
const LETag mngLanguageTag = 0x4D4E4720; /* 'MNG' (Mongolian) */
const LETag mtsLanguageTag = 0x4D545320; /* 'MTS' (Maltese) */
const LETag nepLanguageTag = 0x4E455020; /* 'NEP' (Nepali) */
const LETag nldLanguageTag = 0x4E4C4420; /* 'NLD' (Dutch) */
const LETag pasLanguageTag = 0x50415320; /* 'PAS' (Pashto) */
const LETag plkLanguageTag = 0x504C4B20; /* 'PLK' (Polish) */
const LETag ptgLanguageTag = 0x50544720; /* 'PTG' (Portuguese) */
const LETag romLanguageTag = 0x524F4D20; /* 'ROM' (Romanian) */
const LETag rusLanguageTag = 0x52555320; /* 'RUS' (Russian) */
const LETag skyLanguageTag = 0x534B5920; /* 'SKY' (Slovak) */
const LETag slvLanguageTag = 0x534C5620; /* 'SLV' (Slovenian) */
const LETag sqiLanguageTag = 0x53514920; /* 'SQI' (Albanian) */
const LETag srbLanguageTag = 0x53524220; /* 'SRB' (Serbian) */
const LETag sveLanguageTag = 0x53564520; /* 'SVE' (Swedish) */
const LETag tibLanguageTag = 0x54494220; /* 'TIB' (Tibetan) */
const LETag trkLanguageTag = 0x54524B20; /* 'TRK' (Turkish) */
const LETag welLanguageTag = 0x57454C20; /* 'WEL' (Welsh) */
U_NAMESPACE_END
......
......@@ -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);
}
......
......@@ -25,7 +25,7 @@
/*
*
* (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.
......@@ -39,72 +39,87 @@
U_NAMESPACE_BEGIN
const le_uint8 ArabicShaping::shapingTypeTable[] = {
0x00, 0x02, 0x00, 0xAD, 0x00, 0xAD, 0x00, 0xAD, 0x00, 0x05, 0x03, 0x00, 0x03, 0x6F, 0x00, 0x05,
0x04, 0x83, 0x04, 0x86, 0x00, 0x05, 0x04, 0x88, 0x04, 0x89, 0x00, 0x05, 0x05, 0x91, 0x05, 0xB9,
0x00, 0x05, 0x05, 0xBB, 0x05, 0xBD, 0x00, 0x05, 0x05, 0xBF, 0x05, 0xBF, 0x00, 0x05, 0x05, 0xC1,
0x05, 0xC2, 0x00, 0x05, 0x05, 0xC4, 0x05, 0xC5, 0x00, 0x05, 0x05, 0xC7, 0x05, 0xC7, 0x00, 0x05,
0x06, 0x10, 0x06, 0x15, 0x00, 0x05, 0x06, 0x22, 0x06, 0x25, 0x00, 0x04, 0x06, 0x26, 0x06, 0x26,
0x00, 0x02, 0x06, 0x27, 0x06, 0x27, 0x00, 0x04, 0x06, 0x28, 0x06, 0x28, 0x00, 0x02, 0x06, 0x29,
0x06, 0x29, 0x00, 0x04, 0x06, 0x2A, 0x06, 0x2E, 0x00, 0x02, 0x06, 0x2F, 0x06, 0x32, 0x00, 0x04,
0x06, 0x33, 0x06, 0x3A, 0x00, 0x02, 0x06, 0x40, 0x06, 0x40, 0x00, 0x01, 0x06, 0x41, 0x06, 0x47,
0x00, 0x02, 0x06, 0x48, 0x06, 0x48, 0x00, 0x04, 0x06, 0x49, 0x06, 0x4A, 0x00, 0x02, 0x06, 0x4B,
0x06, 0x5E, 0x00, 0x05, 0x06, 0x6E, 0x06, 0x6F, 0x00, 0x02, 0x06, 0x70, 0x06, 0x70, 0x00, 0x05,
0x06, 0x71, 0x06, 0x73, 0x00, 0x04, 0x06, 0x75, 0x06, 0x77, 0x00, 0x04, 0x06, 0x78, 0x06, 0x87,
0x00, 0x02, 0x06, 0x88, 0x06, 0x99, 0x00, 0x04, 0x06, 0x9A, 0x06, 0xBF, 0x00, 0x02, 0x06, 0xC0,
0x06, 0xC0, 0x00, 0x04, 0x06, 0xC1, 0x06, 0xC2, 0x00, 0x02, 0x06, 0xC3, 0x06, 0xCB, 0x00, 0x04,
0x06, 0xCC, 0x06, 0xCC, 0x00, 0x02, 0x06, 0xCD, 0x06, 0xCD, 0x00, 0x04, 0x06, 0xCE, 0x06, 0xCE,
0x00, 0x02, 0x06, 0xCF, 0x06, 0xCF, 0x00, 0x04, 0x06, 0xD0, 0x06, 0xD1, 0x00, 0x02, 0x06, 0xD2,
0x06, 0xD3, 0x00, 0x04, 0x06, 0xD5, 0x06, 0xD5, 0x00, 0x04, 0x06, 0xD6, 0x06, 0xDC, 0x00, 0x05,
0x06, 0xDE, 0x06, 0xE4, 0x00, 0x05, 0x06, 0xE7, 0x06, 0xE8, 0x00, 0x05, 0x06, 0xEA, 0x06, 0xED,
0x00, 0x05, 0x06, 0xEE, 0x06, 0xEF, 0x00, 0x04, 0x06, 0xFA, 0x06, 0xFC, 0x00, 0x02, 0x06, 0xFF,
0x06, 0xFF, 0x00, 0x02, 0x07, 0x0F, 0x07, 0x0F, 0x00, 0x05, 0x07, 0x10, 0x07, 0x10, 0x00, 0x04,
0x07, 0x11, 0x07, 0x11, 0x00, 0x05, 0x07, 0x12, 0x07, 0x14, 0x00, 0x02, 0x07, 0x15, 0x07, 0x19,
0x00, 0x04, 0x07, 0x1A, 0x07, 0x1D, 0x00, 0x02, 0x07, 0x1E, 0x07, 0x1E, 0x00, 0x04, 0x07, 0x1F,
0x07, 0x27, 0x00, 0x02, 0x07, 0x28, 0x07, 0x28, 0x00, 0x04, 0x07, 0x29, 0x07, 0x29, 0x00, 0x02,
0x07, 0x2A, 0x07, 0x2A, 0x00, 0x04, 0x07, 0x2B, 0x07, 0x2B, 0x00, 0x02, 0x07, 0x2C, 0x07, 0x2C,
0x00, 0x04, 0x07, 0x2D, 0x07, 0x2E, 0x00, 0x02, 0x07, 0x2F, 0x07, 0x2F, 0x00, 0x04, 0x07, 0x30,
0x07, 0x4A, 0x00, 0x05, 0x07, 0x4D, 0x07, 0x4D, 0x00, 0x04, 0x07, 0x4E, 0x07, 0x58, 0x00, 0x02,
0x07, 0x59, 0x07, 0x5B, 0x00, 0x04, 0x07, 0x5C, 0x07, 0x6A, 0x00, 0x02, 0x07, 0x6B, 0x07, 0x6C,
0x00, 0x04, 0x07, 0x6D, 0x07, 0x6D, 0x00, 0x02, 0x07, 0xA6, 0x07, 0xB0, 0x00, 0x05, 0x09, 0x01,
0x09, 0x02, 0x00, 0x05, 0x09, 0x3C, 0x09, 0x3C, 0x00, 0x05, 0x09, 0x41, 0x09, 0x48, 0x00, 0x05,
0x09, 0x4D, 0x09, 0x4D, 0x00, 0x05, 0x09, 0x51, 0x09, 0x54, 0x00, 0x05, 0x09, 0x62, 0x09, 0x63,
0x00, 0x05, 0x09, 0x81, 0x09, 0x81, 0x00, 0x05, 0x09, 0xBC, 0x09, 0xBC, 0x00, 0x05, 0x09, 0xC1,
0x09, 0xC4, 0x00, 0x05, 0x09, 0xCD, 0x09, 0xCD, 0x00, 0x05, 0x09, 0xE2, 0x09, 0xE3, 0x00, 0x05,
0x0A, 0x01, 0x0A, 0x02, 0x00, 0x05, 0x0A, 0x3C, 0x0A, 0x3C, 0x00, 0x05, 0x0A, 0x41, 0x0A, 0x42,
0x00, 0x05, 0x0A, 0x47, 0x0A, 0x48, 0x00, 0x05, 0x0A, 0x4B, 0x0A, 0x4D, 0x00, 0x05, 0x0A, 0x70,
0x0A, 0x71, 0x00, 0x05, 0x0A, 0x81, 0x0A, 0x82, 0x00, 0x05, 0x0A, 0xBC, 0x0A, 0xBC, 0x00, 0x05,
0x0A, 0xC1, 0x0A, 0xC5, 0x00, 0x05, 0x0A, 0xC7, 0x0A, 0xC8, 0x00, 0x05, 0x0A, 0xCD, 0x0A, 0xCD,
0x00, 0x05, 0x0A, 0xE2, 0x0A, 0xE3, 0x00, 0x05, 0x0B, 0x01, 0x0B, 0x01, 0x00, 0x05, 0x0B, 0x3C,
0x0B, 0x3C, 0x00, 0x05, 0x0B, 0x3F, 0x0B, 0x3F, 0x00, 0x05, 0x0B, 0x41, 0x0B, 0x43, 0x00, 0x05,
0x0B, 0x4D, 0x0B, 0x4D, 0x00, 0x05, 0x0B, 0x56, 0x0B, 0x56, 0x00, 0x05, 0x0B, 0x82, 0x0B, 0x82,
0x00, 0x05, 0x0B, 0xC0, 0x0B, 0xC0, 0x00, 0x05, 0x0B, 0xCD, 0x0B, 0xCD, 0x00, 0x05, 0x0C, 0x3E,
0x0C, 0x40, 0x00, 0x05, 0x0C, 0x46, 0x0C, 0x48, 0x00, 0x05, 0x0C, 0x4A, 0x0C, 0x4D, 0x00, 0x05,
0x0C, 0x55, 0x0C, 0x56, 0x00, 0x05, 0x0C, 0xBC, 0x0C, 0xBC, 0x00, 0x05, 0x0C, 0xBF, 0x0C, 0xBF,
0x00, 0x05, 0x0C, 0xC6, 0x0C, 0xC6, 0x00, 0x05, 0x0C, 0xCC, 0x0C, 0xCD, 0x00, 0x05, 0x0D, 0x41,
0x0D, 0x43, 0x00, 0x05, 0x0D, 0x4D, 0x0D, 0x4D, 0x00, 0x05, 0x0D, 0xCA, 0x0D, 0xCA, 0x00, 0x05,
0x0D, 0xD2, 0x0D, 0xD4, 0x00, 0x05, 0x0D, 0xD6, 0x0D, 0xD6, 0x00, 0x05, 0x0E, 0x31, 0x0E, 0x31,
0x00, 0x05, 0x0E, 0x34, 0x0E, 0x3A, 0x00, 0x05, 0x0E, 0x47, 0x0E, 0x4E, 0x00, 0x05, 0x0E, 0xB1,
0x0E, 0xB1, 0x00, 0x05, 0x0E, 0xB4, 0x0E, 0xB9, 0x00, 0x05, 0x0E, 0xBB, 0x0E, 0xBC, 0x00, 0x05,
0x0E, 0xC8, 0x0E, 0xCD, 0x00, 0x05, 0x0F, 0x18, 0x0F, 0x19, 0x00, 0x05, 0x0F, 0x35, 0x0F, 0x35,
0x00, 0x05, 0x0F, 0x37, 0x0F, 0x37, 0x00, 0x05, 0x0F, 0x39, 0x0F, 0x39, 0x00, 0x05, 0x0F, 0x71,
0x0F, 0x7E, 0x00, 0x05, 0x0F, 0x80, 0x0F, 0x84, 0x00, 0x05, 0x0F, 0x86, 0x0F, 0x87, 0x00, 0x05,
0x0F, 0x90, 0x0F, 0x97, 0x00, 0x05, 0x0F, 0x99, 0x0F, 0xBC, 0x00, 0x05, 0x0F, 0xC6, 0x0F, 0xC6,
0x00, 0x05, 0x10, 0x2D, 0x10, 0x30, 0x00, 0x05, 0x10, 0x32, 0x10, 0x32, 0x00, 0x05, 0x10, 0x36,
0x10, 0x37, 0x00, 0x05, 0x10, 0x39, 0x10, 0x39, 0x00, 0x05, 0x10, 0x58, 0x10, 0x59, 0x00, 0x05,
0x13, 0x5F, 0x13, 0x5F, 0x00, 0x05, 0x17, 0x12, 0x17, 0x14, 0x00, 0x05, 0x17, 0x32, 0x17, 0x34,
0x00, 0x05, 0x17, 0x52, 0x17, 0x53, 0x00, 0x05, 0x17, 0x72, 0x17, 0x73, 0x00, 0x05, 0x17, 0xB4,
0x17, 0xB5, 0x00, 0x05, 0x17, 0xB7, 0x17, 0xBD, 0x00, 0x05, 0x17, 0xC6, 0x17, 0xC6, 0x00, 0x05,
0x17, 0xC9, 0x17, 0xD3, 0x00, 0x05, 0x17, 0xDD, 0x17, 0xDD, 0x00, 0x05, 0x18, 0x0B, 0x18, 0x0D,
0x00, 0x05, 0x18, 0xA9, 0x18, 0xA9, 0x00, 0x05, 0x19, 0x20, 0x19, 0x22, 0x00, 0x05, 0x19, 0x27,
0x19, 0x28, 0x00, 0x05, 0x19, 0x32, 0x19, 0x32, 0x00, 0x05, 0x19, 0x39, 0x19, 0x3B, 0x00, 0x05,
0x1A, 0x17, 0x1A, 0x18, 0x00, 0x05, 0x1D, 0xC0, 0x1D, 0xC3, 0x00, 0x05, 0x20, 0x0B, 0x20, 0x0B,
0x00, 0x05, 0x20, 0x0D, 0x20, 0x0D, 0x00, 0x01, 0x20, 0x0E, 0x20, 0x0F, 0x00, 0x05, 0x20, 0x2A,
0x20, 0x2E, 0x00, 0x05, 0x20, 0x60, 0x20, 0x63, 0x00, 0x05, 0x20, 0x6A, 0x20, 0x6F, 0x00, 0x05,
0x20, 0xD0, 0x20, 0xEB, 0x00, 0x05, 0x30, 0x2A, 0x30, 0x2F, 0x00, 0x05, 0x30, 0x99, 0x30, 0x9A,
0x00, 0x05, 0xA8, 0x06, 0xA8, 0x06, 0x00, 0x05, 0xA8, 0x0B, 0xA8, 0x0B, 0x00, 0x05, 0xA8, 0x25,
0xA8, 0x26, 0x00, 0x05, 0xFB, 0x1E, 0xFB, 0x1E, 0x00, 0x05, 0xFE, 0x00, 0xFE, 0x0F, 0x00, 0x05,
0xFE, 0x20, 0xFE, 0x23, 0x00, 0x05, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x05, 0xFF, 0xF9, 0xFF, 0xFB,
0x00, 0x05
0x00, 0x02, 0x00, 0xD7, 0x00, 0xAD, 0x00, 0xAD, 0x00, 0x05, 0x03, 0x00, 0x03, 0x6F, 0x00, 0x05,
0x04, 0x83, 0x04, 0x89, 0x00, 0x05, 0x05, 0x91, 0x05, 0xBD, 0x00, 0x05, 0x05, 0xBF, 0x05, 0xBF,
0x00, 0x05, 0x05, 0xC1, 0x05, 0xC2, 0x00, 0x05, 0x05, 0xC4, 0x05, 0xC5, 0x00, 0x05, 0x05, 0xC7,
0x05, 0xC7, 0x00, 0x05, 0x06, 0x10, 0x06, 0x1A, 0x00, 0x05, 0x06, 0x22, 0x06, 0x25, 0x00, 0x04,
0x06, 0x26, 0x06, 0x26, 0x00, 0x02, 0x06, 0x27, 0x06, 0x27, 0x00, 0x04, 0x06, 0x28, 0x06, 0x28,
0x00, 0x02, 0x06, 0x29, 0x06, 0x29, 0x00, 0x04, 0x06, 0x2A, 0x06, 0x2E, 0x00, 0x02, 0x06, 0x2F,
0x06, 0x32, 0x00, 0x04, 0x06, 0x33, 0x06, 0x3F, 0x00, 0x02, 0x06, 0x40, 0x06, 0x40, 0x00, 0x01,
0x06, 0x41, 0x06, 0x47, 0x00, 0x02, 0x06, 0x48, 0x06, 0x48, 0x00, 0x04, 0x06, 0x49, 0x06, 0x4A,
0x00, 0x02, 0x06, 0x4B, 0x06, 0x5E, 0x00, 0x05, 0x06, 0x6E, 0x06, 0x6F, 0x00, 0x02, 0x06, 0x70,
0x06, 0x70, 0x00, 0x05, 0x06, 0x71, 0x06, 0x73, 0x00, 0x04, 0x06, 0x75, 0x06, 0x77, 0x00, 0x04,
0x06, 0x78, 0x06, 0x87, 0x00, 0x02, 0x06, 0x88, 0x06, 0x99, 0x00, 0x04, 0x06, 0x9A, 0x06, 0xBF,
0x00, 0x02, 0x06, 0xC0, 0x06, 0xC0, 0x00, 0x04, 0x06, 0xC1, 0x06, 0xC2, 0x00, 0x02, 0x06, 0xC3,
0x06, 0xCB, 0x00, 0x04, 0x06, 0xCC, 0x06, 0xCC, 0x00, 0x02, 0x06, 0xCD, 0x06, 0xCD, 0x00, 0x04,
0x06, 0xCE, 0x06, 0xCE, 0x00, 0x02, 0x06, 0xCF, 0x06, 0xCF, 0x00, 0x04, 0x06, 0xD0, 0x06, 0xD1,
0x00, 0x02, 0x06, 0xD2, 0x06, 0xD3, 0x00, 0x04, 0x06, 0xD5, 0x06, 0xD5, 0x00, 0x04, 0x06, 0xD6,
0x06, 0xDC, 0x00, 0x05, 0x06, 0xDE, 0x06, 0xE4, 0x00, 0x05, 0x06, 0xE7, 0x06, 0xE8, 0x00, 0x05,
0x06, 0xEA, 0x06, 0xED, 0x00, 0x05, 0x06, 0xEE, 0x06, 0xEF, 0x00, 0x04, 0x06, 0xFA, 0x06, 0xFC,
0x00, 0x02, 0x06, 0xFF, 0x06, 0xFF, 0x00, 0x02, 0x07, 0x0F, 0x07, 0x0F, 0x00, 0x05, 0x07, 0x10,
0x07, 0x10, 0x00, 0x04, 0x07, 0x11, 0x07, 0x11, 0x00, 0x05, 0x07, 0x12, 0x07, 0x14, 0x00, 0x02,
0x07, 0x15, 0x07, 0x19, 0x00, 0x04, 0x07, 0x1A, 0x07, 0x1D, 0x00, 0x02, 0x07, 0x1E, 0x07, 0x1E,
0x00, 0x04, 0x07, 0x1F, 0x07, 0x27, 0x00, 0x02, 0x07, 0x28, 0x07, 0x28, 0x00, 0x04, 0x07, 0x29,
0x07, 0x29, 0x00, 0x02, 0x07, 0x2A, 0x07, 0x2A, 0x00, 0x04, 0x07, 0x2B, 0x07, 0x2B, 0x00, 0x02,
0x07, 0x2C, 0x07, 0x2C, 0x00, 0x04, 0x07, 0x2D, 0x07, 0x2E, 0x00, 0x02, 0x07, 0x2F, 0x07, 0x2F,
0x00, 0x04, 0x07, 0x30, 0x07, 0x4A, 0x00, 0x05, 0x07, 0x4D, 0x07, 0x4D, 0x00, 0x04, 0x07, 0x4E,
0x07, 0x58, 0x00, 0x02, 0x07, 0x59, 0x07, 0x5B, 0x00, 0x04, 0x07, 0x5C, 0x07, 0x6A, 0x00, 0x02,
0x07, 0x6B, 0x07, 0x6C, 0x00, 0x04, 0x07, 0x6D, 0x07, 0x70, 0x00, 0x02, 0x07, 0x71, 0x07, 0x71,
0x00, 0x04, 0x07, 0x72, 0x07, 0x72, 0x00, 0x02, 0x07, 0x73, 0x07, 0x74, 0x00, 0x04, 0x07, 0x75,
0x07, 0x77, 0x00, 0x02, 0x07, 0x78, 0x07, 0x79, 0x00, 0x04, 0x07, 0x7A, 0x07, 0x7F, 0x00, 0x02,
0x07, 0xA6, 0x07, 0xB0, 0x00, 0x05, 0x07, 0xCA, 0x07, 0xEA, 0x00, 0x02, 0x07, 0xEB, 0x07, 0xF3,
0x00, 0x05, 0x07, 0xFA, 0x07, 0xFA, 0x00, 0x01, 0x09, 0x01, 0x09, 0x02, 0x00, 0x05, 0x09, 0x3C,
0x09, 0x3C, 0x00, 0x05, 0x09, 0x41, 0x09, 0x48, 0x00, 0x05, 0x09, 0x4D, 0x09, 0x4D, 0x00, 0x05,
0x09, 0x51, 0x09, 0x54, 0x00, 0x05, 0x09, 0x62, 0x09, 0x63, 0x00, 0x05, 0x09, 0x81, 0x09, 0x81,
0x00, 0x05, 0x09, 0xBC, 0x09, 0xBC, 0x00, 0x05, 0x09, 0xC1, 0x09, 0xC4, 0x00, 0x05, 0x09, 0xCD,
0x09, 0xCD, 0x00, 0x05, 0x09, 0xE2, 0x09, 0xE3, 0x00, 0x05, 0x0A, 0x01, 0x0A, 0x02, 0x00, 0x05,
0x0A, 0x3C, 0x0A, 0x3C, 0x00, 0x05, 0x0A, 0x41, 0x0A, 0x42, 0x00, 0x05, 0x0A, 0x47, 0x0A, 0x48,
0x00, 0x05, 0x0A, 0x4B, 0x0A, 0x4D, 0x00, 0x05, 0x0A, 0x51, 0x0A, 0x51, 0x00, 0x05, 0x0A, 0x70,
0x0A, 0x71, 0x00, 0x05, 0x0A, 0x75, 0x0A, 0x75, 0x00, 0x05, 0x0A, 0x81, 0x0A, 0x82, 0x00, 0x05,
0x0A, 0xBC, 0x0A, 0xBC, 0x00, 0x05, 0x0A, 0xC1, 0x0A, 0xC5, 0x00, 0x05, 0x0A, 0xC7, 0x0A, 0xC8,
0x00, 0x05, 0x0A, 0xCD, 0x0A, 0xCD, 0x00, 0x05, 0x0A, 0xE2, 0x0A, 0xE3, 0x00, 0x05, 0x0B, 0x01,
0x0B, 0x01, 0x00, 0x05, 0x0B, 0x3C, 0x0B, 0x3C, 0x00, 0x05, 0x0B, 0x3F, 0x0B, 0x3F, 0x00, 0x05,
0x0B, 0x41, 0x0B, 0x44, 0x00, 0x05, 0x0B, 0x4D, 0x0B, 0x4D, 0x00, 0x05, 0x0B, 0x56, 0x0B, 0x56,
0x00, 0x05, 0x0B, 0x62, 0x0B, 0x63, 0x00, 0x05, 0x0B, 0x82, 0x0B, 0x82, 0x00, 0x05, 0x0B, 0xC0,
0x0B, 0xC0, 0x00, 0x05, 0x0B, 0xCD, 0x0B, 0xCD, 0x00, 0x05, 0x0C, 0x3E, 0x0C, 0x40, 0x00, 0x05,
0x0C, 0x46, 0x0C, 0x48, 0x00, 0x05, 0x0C, 0x4A, 0x0C, 0x4D, 0x00, 0x05, 0x0C, 0x55, 0x0C, 0x56,
0x00, 0x05, 0x0C, 0x62, 0x0C, 0x63, 0x00, 0x05, 0x0C, 0xBC, 0x0C, 0xBC, 0x00, 0x05, 0x0C, 0xBF,
0x0C, 0xBF, 0x00, 0x05, 0x0C, 0xC6, 0x0C, 0xC6, 0x00, 0x05, 0x0C, 0xCC, 0x0C, 0xCD, 0x00, 0x05,
0x0C, 0xE2, 0x0C, 0xE3, 0x00, 0x05, 0x0D, 0x41, 0x0D, 0x44, 0x00, 0x05, 0x0D, 0x4D, 0x0D, 0x4D,
0x00, 0x05, 0x0D, 0x62, 0x0D, 0x63, 0x00, 0x05, 0x0D, 0xCA, 0x0D, 0xCA, 0x00, 0x05, 0x0D, 0xD2,
0x0D, 0xD4, 0x00, 0x05, 0x0D, 0xD6, 0x0D, 0xD6, 0x00, 0x05, 0x0E, 0x31, 0x0E, 0x31, 0x00, 0x05,
0x0E, 0x34, 0x0E, 0x3A, 0x00, 0x05, 0x0E, 0x47, 0x0E, 0x4E, 0x00, 0x05, 0x0E, 0xB1, 0x0E, 0xB1,
0x00, 0x05, 0x0E, 0xB4, 0x0E, 0xB9, 0x00, 0x05, 0x0E, 0xBB, 0x0E, 0xBC, 0x00, 0x05, 0x0E, 0xC8,
0x0E, 0xCD, 0x00, 0x05, 0x0F, 0x18, 0x0F, 0x19, 0x00, 0x05, 0x0F, 0x35, 0x0F, 0x35, 0x00, 0x05,
0x0F, 0x37, 0x0F, 0x37, 0x00, 0x05, 0x0F, 0x39, 0x0F, 0x39, 0x00, 0x05, 0x0F, 0x71, 0x0F, 0x7E,
0x00, 0x05, 0x0F, 0x80, 0x0F, 0x84, 0x00, 0x05, 0x0F, 0x86, 0x0F, 0x87, 0x00, 0x05, 0x0F, 0x90,
0x0F, 0x97, 0x00, 0x05, 0x0F, 0x99, 0x0F, 0xBC, 0x00, 0x05, 0x0F, 0xC6, 0x0F, 0xC6, 0x00, 0x05,
0x10, 0x2D, 0x10, 0x30, 0x00, 0x05, 0x10, 0x32, 0x10, 0x37, 0x00, 0x05, 0x10, 0x39, 0x10, 0x3A,
0x00, 0x05, 0x10, 0x3D, 0x10, 0x3E, 0x00, 0x05, 0x10, 0x58, 0x10, 0x59, 0x00, 0x05, 0x10, 0x5E,
0x10, 0x60, 0x00, 0x05, 0x10, 0x71, 0x10, 0x74, 0x00, 0x05, 0x10, 0x82, 0x10, 0x82, 0x00, 0x05,
0x10, 0x85, 0x10, 0x86, 0x00, 0x05, 0x10, 0x8D, 0x10, 0x8D, 0x00, 0x05, 0x13, 0x5F, 0x13, 0x5F,
0x00, 0x05, 0x17, 0x12, 0x17, 0x14, 0x00, 0x05, 0x17, 0x32, 0x17, 0x34, 0x00, 0x05, 0x17, 0x52,
0x17, 0x53, 0x00, 0x05, 0x17, 0x72, 0x17, 0x73, 0x00, 0x05, 0x17, 0xB4, 0x17, 0xB5, 0x00, 0x05,
0x17, 0xB7, 0x17, 0xBD, 0x00, 0x05, 0x17, 0xC6, 0x17, 0xC6, 0x00, 0x05, 0x17, 0xC9, 0x17, 0xD3,
0x00, 0x05, 0x17, 0xDD, 0x17, 0xDD, 0x00, 0x05, 0x18, 0x0B, 0x18, 0x0D, 0x00, 0x05, 0x18, 0xA9,
0x18, 0xA9, 0x00, 0x05, 0x19, 0x20, 0x19, 0x22, 0x00, 0x05, 0x19, 0x27, 0x19, 0x28, 0x00, 0x05,
0x19, 0x32, 0x19, 0x32, 0x00, 0x05, 0x19, 0x39, 0x19, 0x3B, 0x00, 0x05, 0x1A, 0x17, 0x1A, 0x18,
0x00, 0x05, 0x1B, 0x00, 0x1B, 0x03, 0x00, 0x05, 0x1B, 0x34, 0x1B, 0x34, 0x00, 0x05, 0x1B, 0x36,
0x1B, 0x3A, 0x00, 0x05, 0x1B, 0x3C, 0x1B, 0x3C, 0x00, 0x05, 0x1B, 0x42, 0x1B, 0x42, 0x00, 0x05,
0x1B, 0x6B, 0x1B, 0x73, 0x00, 0x05, 0x1B, 0x80, 0x1B, 0x81, 0x00, 0x05, 0x1B, 0xA2, 0x1B, 0xA5,
0x00, 0x05, 0x1B, 0xA8, 0x1B, 0xA9, 0x00, 0x05, 0x1C, 0x2C, 0x1C, 0x33, 0x00, 0x05, 0x1C, 0x36,
0x1C, 0x37, 0x00, 0x05, 0x1D, 0xC0, 0x1D, 0xE6, 0x00, 0x05, 0x1D, 0xFE, 0x1D, 0xFF, 0x00, 0x05,
0x20, 0x0B, 0x20, 0x0B, 0x00, 0x05, 0x20, 0x0D, 0x20, 0x0D, 0x00, 0x01, 0x20, 0x0E, 0x20, 0x0F,
0x00, 0x05, 0x20, 0x2A, 0x20, 0x2E, 0x00, 0x05, 0x20, 0x60, 0x20, 0x64, 0x00, 0x05, 0x20, 0x6A,
0x20, 0x6F, 0x00, 0x05, 0x20, 0xD0, 0x20, 0xF0, 0x00, 0x05, 0x2D, 0xE0, 0x2D, 0xFF, 0x00, 0x05,
0x30, 0x2A, 0x30, 0x2F, 0x00, 0x05, 0x30, 0x99, 0x30, 0x9A, 0x00, 0x05, 0xA6, 0x6F, 0xA6, 0x72,
0x00, 0x05, 0xA6, 0x7C, 0xA6, 0x7D, 0x00, 0x05, 0xA8, 0x02, 0xA8, 0x02, 0x00, 0x05, 0xA8, 0x06,
0xA8, 0x06, 0x00, 0x05, 0xA8, 0x0B, 0xA8, 0x0B, 0x00, 0x05, 0xA8, 0x25, 0xA8, 0x26, 0x00, 0x05,
0xA8, 0xC4, 0xA8, 0xC4, 0x00, 0x05, 0xA9, 0x26, 0xA9, 0x2D, 0x00, 0x05, 0xA9, 0x47, 0xA9, 0x51,
0x00, 0x05, 0xAA, 0x29, 0xAA, 0x2E, 0x00, 0x05, 0xAA, 0x31, 0xAA, 0x32, 0x00, 0x05, 0xAA, 0x35,
0xAA, 0x36, 0x00, 0x05, 0xAA, 0x43, 0xAA, 0x43, 0x00, 0x05, 0xAA, 0x4C, 0xAA, 0x4C, 0x00, 0x05,
0xFB, 0x1E, 0xFB, 0x1E, 0x00, 0x05, 0xFE, 0x00, 0xFE, 0x0F, 0x00, 0x05, 0xFE, 0x20, 0xFE, 0x26,
0x00, 0x05, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x05, 0xFF, 0xF9, 0xFF, 0xFB, 0x00, 0x05
};
U_NAMESPACE_END
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -53,18 +53,23 @@ void SubstitutionLookup::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_uint16 subst = 0; subst < substCount; subst += 1) {
for (le_uint16 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);
}
}
......
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -60,7 +60,8 @@ struct SubstitutionLookup
le_uint16 substCount,
GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
le_int32 position);
le_int32 position,
LEErrorCode& success);
};
U_NAMESPACE_END
......
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -36,19 +36,24 @@
#include "ScriptAndLanguageTags.h"
#include "LEGlyphStorage.h"
#include "KernTable.h"
#include "ThaiShaping.h"
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ThaiLayoutEngine)
ThaiLayoutEngine::ThaiLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
ThaiLayoutEngine::ThaiLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
fErrorChar = 0x25CC;
// Figure out which presentation forms the font uses
if (fontInstance->canDisplay(0x0E64)) {
if (! fontInstance->canDisplay(0x0E01)) {
// No Thai in font; don't use presentation forms.
fGlyphSet = 3;
} else if (fontInstance->canDisplay(0x0E64)) {
// WorldType uses reserved space in Thai block
fGlyphSet = 0;
} else if (fontInstance->canDisplay(0xF701)) {
......@@ -116,4 +121,28 @@ le_int32 ThaiLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offse
return glyphCount;
}
// This is the same as LayoutEngline::adjustGlyphPositions() except that it doesn't call adjustMarkGlyphs
void ThaiLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/,
LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return;
}
if (chars == NULL || offset < 0 || count < 0) {
success = LE_ILLEGAL_ARGUMENT_ERROR;
return;
}
if (fTypoFlags & 0x1) { /* kerning enabled */
static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
KernTable kt(fFontInstance, getFontTable(kernTableTag));
kt.process(glyphStorage);
}
// default is no adjustments
return;
}
U_NAMESPACE_END
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
*
*/
......@@ -62,13 +62,14 @@ 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
*
* @internal
*/
ThaiLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags);
ThaiLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
......@@ -139,6 +140,28 @@ protected:
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEGlyphStorage &glyphStorage, LEErrorCode &success);
/**
* This method does positioning adjustments like accent positioning and
* kerning. The default implementation does nothing. Subclasses needing
* position adjustments must override this method.
*
* Note that this method has both characters and glyphs as input so that
* it can use the character codes to determine glyph types if that information
* isn't directly available. (e.g. Some Arabic OpenType fonts don't have a GDEF
* table)
*
* @param chars - the input character context
* @param offset - the offset of the first character to process
* @param count - the number of characters to process
* @param reverse - <code>TRUE</code> if the glyphs in the glyph array have been reordered
* @param glyphStorage - the object which holds the per-glyph storage. The glyph positions will be
* adjusted as needed.
* @param success - output parameter set to an error code if the operation fails
*
* @internal
*/
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success);
};
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
*
* Developed at DIT - Government of Bhutan
*
* Contact person: Pema Geyleg - <pema_geyleg@druknet.bt>
*
* This file is a modification of the ICU file KhmerReordering.cpp
* by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan
* A first module for Dzongkha was developed by Karunakar under Panlocalisation funding.
* Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola
*
*/
#include "OpenTypeLayoutEngine.h"
#include "TibetanLayoutEngine.h"
#include "LEGlyphStorage.h"
#include "TibetanReordering.h"
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TibetanOpenTypeLayoutEngine)
TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = TibetanReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
}
TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
fFeatureMap = TibetanReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
}
TibetanOpenTypeLayoutEngine::~TibetanOpenTypeLayoutEngine()
{
// nothing to do
}
// Input: characters
// Output: characters, char indices, tags
// Returns: output character count
le_int32 TibetanOpenTypeLayoutEngine::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; // worst case is 3 for Khmer TODO check if 2 is enough
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;
}
// NOTE: assumes this allocates featureTags...
// (probably better than doing the worst case stuff here...)
le_int32 outCharCount = TibetanReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage);
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
*
* Developed at DIT - Government of Bhutan
*
* Contact person: Pema Geyleg - <pema_geyleg@druknet.bt>
*
* This file is a modification of the ICU file KhmerReordering.cpp
* by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan
* A first module for Dzongkha was developed by Karunakar under Panlocalisation funding.
* Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola
*
*/
#ifndef __TIBETANLAYOUTENGINE_H
#define __TIBETANLAYOUTENGINE_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 Dzongkha and Tibetan OpenType fonts
*
* @internal
*/
class TibetanOpenTypeLayoutEngine : public OpenTypeLayoutEngine
{
public:
/**
* This is the main constructor. It constructs an instance of TibetanOpenTypeLayoutEngine 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
* Tibetan 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
*/
TibetanOpenTypeLayoutEngine(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
*/
TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success);
/**
* The destructor, virtual for correct polymorphic invocation.
*
* @internal
*/
virtual ~TibetanOpenTypeLayoutEngine();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @internal ICU 3.6
*/
virtual UClassID getDynamicClassID() const;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @internal ICU 3.6
*/
static UClassID getStaticClassID();
protected:
/**
* This method does Tibetan OpenType character processing. It assigns the OpenType feature
* tags to the characters, and may generate output characters which have been reordered.
* It may also split some vowels, resulting in more output characters than input characters.
*
* 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-2010 - All Rights Reserved
*
* Developed at DIT - Government of Bhutan
*
* Contact person: Pema Geyleg - <pema_geyleg@druknet.bt>
*
* This file is a modification of the ICU file KhmerReordering.cpp
* by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan
* A first module for Dzongkha was developed by Karunakar under Panlocalisation funding.
* Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola
*
*/
//#include <stdio.h>
#include "LETypes.h"
#include "OpenTypeTables.h"
#include "TibetanReordering.h"
#include "LEGlyphStorage.h"
U_NAMESPACE_BEGIN
// Characters that get refered to by name...
enum
{
C_DOTTED_CIRCLE = 0x25CC,
C_PRE_NUMBER_MARK = 0x0F3F
};
enum
{
// simple classes, they are used in the statetable (in this file) to control the length of a syllable
// they are also used to know where a character should be placed (location in reference to the base character)
// and also to know if a character, when independtly displayed, should be displayed with a dotted-circle to
// indicate error in syllable construction
_xx = TibetanClassTable::CC_RESERVED,
_ba = TibetanClassTable::CC_BASE,
_sj = TibetanClassTable::CC_SUBJOINED | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW,
_tp = TibetanClassTable::CC_TSA_PHRU | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE,
_ac = TibetanClassTable::CC_A_CHUNG | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW,
_cs = TibetanClassTable::CC_COMP_SANSKRIT | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW,
_ha = TibetanClassTable::CC_HALANTA | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW,
_bv = TibetanClassTable::CC_BELOW_VOWEL | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW,
_av = TibetanClassTable::CC_ABOVE_VOWEL | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE,
_an = TibetanClassTable::CC_ANUSVARA | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE,
_cb = TibetanClassTable::CC_CANDRABINDU | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE,
_vs = TibetanClassTable::CC_VISARGA | TibetanClassTable::CF_DOTTED_CIRCLE| TibetanClassTable::CF_POS_AFTER,
_as = TibetanClassTable::CC_ABOVE_S_MARK | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE,
_bs = TibetanClassTable::CC_BELOW_S_MARK | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW,
_di = TibetanClassTable::CC_DIGIT | TibetanClassTable::CF_DIGIT,
_pd = TibetanClassTable::CC_PRE_DIGIT_MARK | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_PREDIGIT | TibetanClassTable::CF_POS_BEFORE ,
_bd = TibetanClassTable::CC_POST_BELOW_DIGIT_M | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_AFTER
};
// Character class tables
//_xx Non Combining characters
//_ba Base Consonants
//_sj Subjoined consonants
//_tp Tsa - phru
//_ac A-chung, Vowel Lengthening mark
//_cs Precomposed Sanskrit vowel + subjoined consonants
//_ha Halanta/Virama
//_bv Below vowel
//_av above vowel
//_an Anusvara
//_cb Candrabindu
//_vs Visaraga/Post mark
//_as Upper Stress marks
//_bs Lower Stress marks
//_di Digit
//_pd Number pre combining, Needs reordering
//_bd Other number combining marks
static const TibetanClassTable::CharClass tibetanCharClasses[] =
{
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
_xx, _ba, _xx, _xx, _ba, _ba, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0F00 - 0F0F 0
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _bd, _bd, _xx, _xx, _xx, _xx, _xx, _xx, // 0F10 - 0F1F 1
_di, _di, _di, _di, _di, _di, _di, _di, _di, _di, _xx, _xx, _xx, _xx, _xx, _xx, // 0F20 - 0F2F 2
_xx, _xx, _xx, _xx, _xx, _bs, _xx, _bs, _xx, _tp, _xx, _xx, _xx, _xx, _bd, _pd, // 0F30 - 0F3F 3
_ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _ba, _ba, _ba, _ba, _ba, _ba, _ba, // 0F40 - 0F4F 4
_ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, // 0F50 - 0F5F 5
_ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _xx, _xx, _xx, _xx, // 0F60 - 0F6F 6
_xx, _ac, _av, _cs, _bv, _bv, _cs, _cs, _cs, _cs, _av, _av, _av, _av, _an, _vs, // 0F70 - 0F7F 7
_av, _cs, _cb, _cb, _ha, _xx, _as, _as, _ba, _ba, _ba, _ba, _xx, _xx, _xx, _xx, // 0F80 - 0F8F 8
_sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _xx, _sj, _sj, _sj, _sj, _sj, _sj, _sj, // 0F90 - 0F9F 9
_sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, // 0FA0 - 0FAF a
_sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _xx, _sj, _sj, // 0FB0 - 0FBF b
_xx, _xx, _xx, _xx, _xx, _xx, _bs, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FC0 - 0FCF c
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx,// 0FD0 - 0FDF d
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FE0 - 0FEF e
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FF0 - 0FFF f
};
//
// Tibetan Class Tables
//
//
// The range of characters defined in the above table is defined here. For Tibetan 0F00 to 0FFF
// Even if the Tibetan range is bigger, most of the characters are not combinable, and therefore treated
// as _xx
static const TibetanClassTable tibetanClassTable = {0x0F00, 0x0FFF, tibetanCharClasses};
// Below we define how a character in the input string is either in the tibetanCharClasses table
// (in which case we get its type back), or an unknown object in which case we get _xx (CC_RESERVED) back
TibetanClassTable::CharClass TibetanClassTable::getCharClass(LEUnicode ch) const
{
if (ch < firstChar || ch > lastChar) {
return CC_RESERVED;
}
return classTable[ch - firstChar];
}
const TibetanClassTable *TibetanClassTable::getTibetanClassTable()
{
return &tibetanClassTable;
}
class TibetanReorderingOutput : public UMemory {
private:
le_int32 fSyllableCount;
le_int32 fOutIndex;
LEUnicode *fOutChars;
LEGlyphStorage &fGlyphStorage;
public:
TibetanReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage)
: fSyllableCount(0), fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage)
{
// nothing else to do...
}
~TibetanReorderingOutput()
{
// nothing to do here...
}
void reset()
{
fSyllableCount += 1;
}
void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask featureMask)
{
LEErrorCode success = LE_NO_ERROR;
fOutChars[fOutIndex] = ch;
fGlyphStorage.setCharIndex(fOutIndex, charIndex, success);
fGlyphStorage.setAuxData(fOutIndex, featureMask, success);
fOutIndex += 1;
}
le_int32 getOutputIndex()
{
return fOutIndex;
}
};
//TODO remove unused flags
#define ccmpFeatureTag LE_CCMP_FEATURE_TAG
#define blwfFeatureTag LE_BLWF_FEATURE_TAG
#define pstfFeatureTag LE_PSTF_FEATURE_TAG
#define presFeatureTag LE_PRES_FEATURE_TAG
#define blwsFeatureTag LE_BLWS_FEATURE_TAG
#define abvsFeatureTag LE_ABVS_FEATURE_TAG
#define pstsFeatureTag LE_PSTS_FEATURE_TAG
#define blwmFeatureTag LE_BLWM_FEATURE_TAG
#define abvmFeatureTag LE_ABVM_FEATURE_TAG
#define distFeatureTag LE_DIST_FEATURE_TAG
#define prefFeatureTag LE_PREF_FEATURE_TAG
#define abvfFeatureTag LE_ABVF_FEATURE_TAG
#define cligFeatureTag LE_CLIG_FEATURE_TAG
#define mkmkFeatureTag LE_MKMK_FEATURE_TAG
// Shaping features
#define prefFeatureMask 0x80000000UL
#define blwfFeatureMask 0x40000000UL
#define abvfFeatureMask 0x20000000UL
#define pstfFeatureMask 0x10000000UL
#define presFeatureMask 0x08000000UL
#define blwsFeatureMask 0x04000000UL
#define abvsFeatureMask 0x02000000UL
#define pstsFeatureMask 0x01000000UL
#define cligFeatureMask 0x00800000UL
#define ccmpFeatureMask 0x00040000UL
// Positioning features
#define distFeatureMask 0x00400000UL
#define blwmFeatureMask 0x00200000UL
#define abvmFeatureMask 0x00100000UL
#define mkmkFeatureMask 0x00080000UL
#define tagPref (ccmpFeatureMask | prefFeatureMask | presFeatureMask | cligFeatureMask | distFeatureMask)
#define tagAbvf (ccmpFeatureMask | abvfFeatureMask | abvsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | mkmkFeatureMask)
#define tagPstf (ccmpFeatureMask | blwfFeatureMask | blwsFeatureMask | prefFeatureMask | presFeatureMask | pstfFeatureMask | pstsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask)
#define tagBlwf (ccmpFeatureMask | blwfFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask | mkmkFeatureMask)
#define tagDefault (ccmpFeatureMask | prefFeatureMask | blwfFeatureMask | presFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | blwmFeatureMask | mkmkFeatureMask)
// These are in the order in which the features need to be applied
// for correct processing
static const FeatureMap featureMap[] =
{
// Shaping features
{ccmpFeatureTag, ccmpFeatureMask},
{prefFeatureTag, prefFeatureMask},
{blwfFeatureTag, blwfFeatureMask},
{abvfFeatureTag, abvfFeatureMask},
{pstfFeatureTag, pstfFeatureMask},
{presFeatureTag, presFeatureMask},
{blwsFeatureTag, blwsFeatureMask},
{abvsFeatureTag, abvsFeatureMask},
{pstsFeatureTag, pstsFeatureMask},
{cligFeatureTag, cligFeatureMask},
// Positioning features
{distFeatureTag, distFeatureMask},
{blwmFeatureTag, blwmFeatureMask},
{abvmFeatureTag, abvmFeatureMask},
{mkmkFeatureTag, mkmkFeatureMask},
};
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
// The stateTable is used to calculate the end (the length) of a well
// formed Tibetan Syllable.
//
// Each horizontal line is ordered exactly the same way as the values in TibetanClassTable
// CharClassValues in TibetanReordering.h This coincidence of values allows the
// follow up of the table.
//
// Each line corresponds to a state, which does not necessarily need to be a type
// of component... for example, state 2 is a base, with is always a first character
// in the syllable, but the state could be produced a consonant of any type when
// it is the first character that is analysed (in ground state).
//
static const le_int8 tibetanStateTable[][TibetanClassTable::CC_COUNT] =
{
//Dzongkha state table
//xx ba sj tp ac cs ha bv av an cb vs as bs di pd bd
{ 1, 2, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, 20, 21, 21,}, // 0 - ground state
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 1 - exit state (or sign to the right of the syllable)
{-1, -1, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 2 - Base consonant
{-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 3 - Tsa phru after base
{-1, -1, 4, 6, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 4 - Subjoined consonant after base
{-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 5 - Subjoined consonant after tsa phru
{-1, -1, -1, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 6 - Tsa phru after subjoined consonant
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, // 7 - Pre Composed Sanskrit
{-1, -1, -1, -1, -1, -1, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 8 - A-chung
{-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, -1, 19, 19, -1, -1, -1,}, // 9 - Halanta
{-1, -1, -1, -1, -1, -1, -1, 11, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 10 - below vowel 1
{-1, -1, -1, -1, -1, -1, -1, 12, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 11 - below vowel 2
{-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 12 - below vowel 3
{-1, -1, -1, -1, -1, -1, -1, -1, 14, 17, 17, 18, 19, 19, -1, -1, -1,}, // 13 - Anusvara before vowel
{-1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 17, 18, 19, 19, -1, -1, -1,}, // 14 - above vowel 1
{-1, -1, -1, -1, -1, -1, -1, -1, 16, 17, 17, 18, 19, 19, -1, -1, -1,}, // 15 - above vowel 2
{-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 17, 18, 19, 19, -1, -1, -1,}, // 16 - above vowel 3
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 19, -1, -1, -1,}, // 17 - Anusvara or Candrabindu after vowel
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, // 18 - Visarga
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 19 - strss mark
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 21,}, // 20 - digit
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 21 - digit mark
};
const FeatureMap *TibetanReordering::getFeatureMap(le_int32 &count)
{
count = featureMapCount;
return featureMap;
}
// Given an input string of characters and a location in which to start looking
// calculate, using the state table, which one is the last character of the syllable
// that starts in the starting position.
le_int32 TibetanReordering::findSyllable(const TibetanClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount)
{
le_int32 cursor = prev;
le_int8 state = 0;
while (cursor < charCount) {
TibetanClassTable::CharClass charClass = (classTable->getCharClass(chars[cursor]) & TibetanClassTable::CF_CLASS_MASK);
state = tibetanStateTable[state][charClass];
if (state < 0) {
break;
}
cursor += 1;
}
return cursor;
}
// This is the real reordering function as applied to the Tibetan language
le_int32 TibetanReordering::reorder(const LEUnicode *chars, le_int32 charCount, le_int32,
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{
const TibetanClassTable *classTable = TibetanClassTable::getTibetanClassTable();
TibetanReorderingOutput output(outChars, glyphStorage);
TibetanClassTable::CharClass charClass;
le_int32 i, prev = 0;
// This loop only exits when we reach the end of a run, which may contain
// several syllables.
while (prev < charCount) {
le_int32 syllable = findSyllable(classTable, chars, prev, charCount);
output.reset();
// shall we add a dotted circle?
// If in the position in which the base should be (first char in the string) there is
// a character that has the Dotted circle flag (a character that cannot be a base)
// then write a dotted circle
if (classTable->getCharClass(chars[prev]) & TibetanClassTable::CF_DOTTED_CIRCLE) {
output.writeChar(C_DOTTED_CIRCLE, prev, tagDefault);
}
// copy the rest to output, inverting the pre-number mark if present after a digit.
for (i = prev; i < syllable; i += 1) {
charClass = classTable->getCharClass(chars[i]);
if ((TibetanClassTable::CF_DIGIT & charClass)
&& ( classTable->getCharClass(chars[i+1]) & TibetanClassTable::CF_PREDIGIT))
{
output.writeChar(C_PRE_NUMBER_MARK, i, tagPref);
output.writeChar(chars[i], i+1 , tagPref);
i += 1;
} else {
switch (charClass & TibetanClassTable::CF_POS_MASK) {
// If the present character is a number, and the next character is a pre-number combining mark
// then the two characters are reordered
case TibetanClassTable::CF_POS_ABOVE :
output.writeChar(chars[i], i, tagAbvf);
break;
case TibetanClassTable::CF_POS_AFTER :
output.writeChar(chars[i], i, tagPstf);
break;
case TibetanClassTable::CF_POS_BELOW :
output.writeChar(chars[i], i, tagBlwf);
break;
default:
// default - any other characters
output.writeChar(chars[i], i, tagDefault);
break;
} // switch
} // if
} // for
prev = syllable; // move the pointer to the start of next syllable
}
return output.getOutputIndex();
}
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
*
* Developed at DIT - Government of Bhutan
*
* Contact person: Pema Geyleg - <pema_geyleg@druknet.bt>
*
* This file is a modification of the ICU file KhmerReordering.h
* by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan
* A first module for Dzongkha was developed by Karunakar under Panlocalisation funding.
* Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola
*
*/
#ifndef __TIBETANREORDERING_H
#define __TIBETANORDERING_H
/**
* \file
* \internal
*/
// #include "LETypes.h"
// #include "OpenTypeTables.h"
U_NAMESPACE_BEGIN
class LEGlyphStorage;
// Vocabulary
// Base -> A consonant in its full (not subscript) form. It is the
// center of the syllable, it can be souranded by subjoined consonants, vowels,
// signs... but there is only one base in a stack, it has to be coded as
// the first character of the syllable.Included here are also groups of base + subjoined
// which are represented by one single code point in unicode (e.g. 0F43) Also other characters that might take
// subjoined consonants or other combining characters.
// Subjoined -> Subjoined consonants and groups of subjoined consonants which have a single code-point
// to repersent the group (even if each subjoined consonant is represented independently
// by anothe code-point
// Tsa Phru --> Tsa Phru character, Bhutanese people will always place it right after the base, but sometimes, due to
// "normalization"
// is placed after all the subjoined consonants, and it is also permitted there.
// A Chung Vowel lengthening mark --> . 0F71 It is placed after the base and any subjoined consonants but before any vowels
// Precomposed Sanskrit vowels --> The are combinations of subjoined consonants + vowels that have been assigned
// a given code-point (in spite of each single part of them having also a code-point
// They are avoided, and users are encouraged to use the combination of code-points that
// represents the same sound instead of using this combined characters. This is included here
// for compatibility with possible texts that use them (they are not in the Dzongkha keyboard).
// Halanta -> The Halanta or Virama character 0F84 indicates that a consonant should not use its inheernt vowel,
// in spite of not having other vowels present. It is usually placed immediatly after a base consonant,
// but in some special cases it can also be placed after a subjoined consonant, so this is also
// permitted in this algorithm. (Halanta is always displayed in Tibetan not used as a connecting char)
//
// Subjoined vowels -> Dependent vowels (matras) placed below the base and below all subjoined consonants. There
// might be as much as three subjoined vowels in a given stack (only one in general text, but up
// to three for abreviations, they have to be permitted).
// Superscript vowels -> There are three superscript vowels, and they can be repeated or combined (up to three
// times. They can combine with subjoined vowels, and are always coded after these.
// Anusvara --> Nasalisation sign. Traditioinally placed in absence of vowels, but also after vowels. In some
// special cases it can be placed before a vowel, so this is also permitted
// Candrabindu -> Forms of the Anusvara with different glyphs (and different in identity) which can be placed
// without vowel or after the vowel, but never before. Cannot combine with Anusvara.
// Stress marks -> Marks placed above or below a syllable, affecting the whole syllable. They are combining
// marks, so they have to be attached to a specific stack. The are using to emphasise a syllable.
//
// Digits -> Digits are not considered as non-combining characters because there are a few characters which
// combine with them, so they have to be considered independently.
// Digit combining marks -> dependent marks that combine with digits.
//
// TODO
// There are a number of characters in the CJK block that are used in Tibetan script, two of these are symbols
// are used as bases for combining glyphs, and have not been encoded in Tibetan. As these characters are outside
// of the tibetan block, they have not been treated in this program.
struct TibetanClassTable // This list must include all types of components that can be used inside a syllable
{
enum CharClassValues // order is important here! This order must be the same that is found in each horizontal
// line in the statetable for Tibetan (file TibetanReordering.cpp). It assigns one number
// to each type of character that has to be considered when analysing the order in which
// characters can be placed
{
CC_RESERVED = 0, //Non Combining Characters
CC_BASE = 1, // Base Consonants, Base Consonants with Subjoined attached in code point, Sanskrit base marks
CC_SUBJOINED = 2, // Subjoined Consonats, combination of more than Subjoined Consonants in the code point
CC_TSA_PHRU = 3, // Tsa-Phru character 0F39
CC_A_CHUNG = 4, // Vowel Lenthening a-chung mark 0F71
CC_COMP_SANSKRIT = 5, // Precomposed Sanskrit vowels including Subjoined characters and vowels
CC_HALANTA = 6, // Halanta Character 0F84
CC_BELOW_VOWEL = 7, // Subjoined vowels
CC_ABOVE_VOWEL = 8, // Superscript vowels
CC_ANUSVARA = 9, // Tibetan sign Rjes Su Nga Ro 0F7E
CC_CANDRABINDU = 10, // Tibetan sign Sna Ldan and Nyi Zla Naa Da 0F82, 0F83
CC_VISARGA = 11, // Tibetan sign Rnam Bcad (0F7F)
CC_ABOVE_S_MARK = 12, // Stress Marks placed above the text
CC_BELOW_S_MARK = 13, // Stress Marks placed below the text
CC_DIGIT = 14, // Dzongkha Digits
CC_PRE_DIGIT_MARK = 15, // Mark placed before the digit
CC_POST_BELOW_DIGIT_M = 16, // Mark placed below or after the digit
CC_COUNT = 17 // This is the number of character classes
};
enum CharClassFlags
{
CF_CLASS_MASK = 0x0000FFFF,
CF_DOTTED_CIRCLE = 0x04000000, // add a dotted circle if a character with this flag is the first in a syllable
CF_DIGIT = 0x01000000, // flag to speed up comparaisson
CF_PREDIGIT = 0x02000000, // flag to detect pre-digit marks for reordering
// position flags
CF_POS_BEFORE = 0x00080000,
CF_POS_BELOW = 0x00040000,
CF_POS_ABOVE = 0x00020000,
CF_POS_AFTER = 0x00010000,
CF_POS_MASK = 0x000f0000
};
typedef le_uint32 CharClass;
typedef le_int32 ScriptFlags;
LEUnicode firstChar; // for Tibetan this will become xOF00
LEUnicode lastChar; // and this x0FFF
const CharClass *classTable;
CharClass getCharClass(LEUnicode ch) const;
static const TibetanClassTable *getTibetanClassTable();
};
class TibetanReordering /* not : public UObject because all methods are static */ {
public:
static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
LEUnicode *outChars, LEGlyphStorage &glyphStorage);
static const FeatureMap *getFeatureMap(le_int32 &count);
private:
// do not instantiate
TibetanReordering();
static le_int32 findSyllable(const TibetanClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount);
};
U_NAMESPACE_END
#endif
......@@ -3,9 +3,7 @@
*
* 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.
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
......@@ -23,36 +21,63 @@
*
*/
/*
*
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
*
/* @test @(#)TestOldHangul.java
* @summary Verify Old Hangul display
* @bug 6886358
* @ignore Requires a special font installed.
*/
#include "LETypes.h"
#include "OpenTypeTables.h"
#include "HebrewShaping.h"
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
const LETag ligaFeatureTag = 0x6C696761; // 'liga'
const LETag emptyTag = 0x00000000; // ''
const LETag hebrewTags[] =
{
ligaFeatureTag, emptyTag
};
public class TestOldHangul {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestOldHangul().run();
}
});
}
public static boolean AUTOMATIC_TEST=true; // true; run test automatically, else manually at button push
void HebrewShaping::shape(const LEUnicode * /*chars*/, le_int32 /*offset*/, le_int32 charCount, le_int32 /*charMax*/,
le_bool rightToLeft, const LETag **tags)
{
private void run() {
Font ourFont = null;
final String fontName = "UnBatangOdal.ttf"; // download from http://chem.skku.ac.kr/~wkpark/project/font/GSUB/UnbatangOdal/ and place in {user.home}/fonts/
try {
ourFont = Font.createFont(Font.TRUETYPE_FONT, new java.io.File(new java.io.File(System.getProperty("user.home"),"fonts"), fontName));
ourFont = ourFont.deriveFont((float)48.0);
} catch(Throwable t) {
t.printStackTrace();
System.err.println("Fail: " + t);
return;
}
JFrame frame = new JFrame(System.getProperty("java.version"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
final JTextArea label = new JTextArea("(empty)");
label.setSize(400, 300);
label.setBorder(new LineBorder(Color.black));
label.setFont(ourFont);
final String str = "\u110A\u119E\u11B7\u0020\u1112\u119E\u11AB\uAE00\u0020\u1100\u119E\u11F9\u0020\u112B\u119E\u11BC\n";
le_int32 count, out = 0, dir = 1;
if(AUTOMATIC_TEST) { /* run the test automatically (else, manually) */
label.setText(str);
} else {
JButton button = new JButton("Old Hangul");
button.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
label.setText(str);
}
});
panel.add(button);
}
panel.add(label);
if (rightToLeft) {
out = charCount - 1;
dir = -1;
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
for (count = 0; count < charCount; count += 1, out += dir) {
tags[out] = hebrewTags;
}
}
/*
* 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.
*
* 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.
*
*/
/* @test @(#)TestTibetan.java
* @summary verify tibetan output
* @bug 6886358
* @ignore Requires a special font installed
*/
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
public class TestTibetan {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestTibetan().run();
}
});
}
public static boolean AUTOMATIC_TEST=true; // true; run test automatically, else manually at button push
private void run() {
Font ourFont = null;
try {
//For best results: Font from: http://download.savannah.gnu.org/releases/free-tibetan/jomolhari/
// place in $(user.home)/fonts/
ourFont = Font.createFont(Font.TRUETYPE_FONT, new java.io.File(new java.io.File(System.getProperty("user.home"),"fonts"), "Jomolhari-alpha3c-0605331.ttf"));
//ourFont = new Font("serif",Font.PLAIN, 24);
ourFont = ourFont.deriveFont((float)24.0);
} catch(Throwable t) {
t.printStackTrace();
System.err.println("Fail: " + t);
return;
}
JFrame frame = new JFrame(System.getProperty("java.version"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
final JTextArea label = new JTextArea("(empty)");
label.setSize(400, 300);
label.setBorder(new LineBorder(Color.black));
label.setFont(ourFont);
final String str = "\u0F04\u0F05\u0F0D\u0F0D\u0020\u0F4F\u0F72\u0F53\u0F0B\u0F4F\u0F72\u0F53\u0F0B\u0F42\u0FB1\u0F72\u0F0B\u0F51\u0F54\u0F60\u0F0B\u0F62\u0FA9\u0F63"; // TinTin.
if(AUTOMATIC_TEST) { /* run the test automatically (else, manually) */
label.setText(str);
} else {
JButton button = new JButton("Set Char x0DDD");
button.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) {
label.setText(str);
}
});
panel.add(button);
}
panel.add(label);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册