ICU-9868 morx support (contributed)
X-SVN-Rev: 33130
This commit is contained in:
parent
bd47a9bba6
commit
3509164083
@ -1,6 +1,6 @@
|
||||
/*
|
||||
/**
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and Others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,6 +24,11 @@ struct ContextualGlyphInsertionHeader : MorphStateTableHeader
|
||||
{
|
||||
};
|
||||
|
||||
struct ContextualGlyphInsertionHeader2 : MorphStateTableHeader2
|
||||
{
|
||||
le_uint32 insertionTableOffset;
|
||||
};
|
||||
|
||||
enum ContextualGlyphInsertionFlags
|
||||
{
|
||||
cgiSetMark = 0x8000,
|
||||
@ -36,11 +41,17 @@ enum ContextualGlyphInsertionFlags
|
||||
cgiMarkedInsertCountMask = 0x001F
|
||||
};
|
||||
|
||||
struct LigatureSubstitutionStateEntry : StateEntry
|
||||
struct ContextualGlyphInsertionStateEntry : StateEntry
|
||||
{
|
||||
ByteOffset currentInsertionListOffset;
|
||||
ByteOffset markedInsertionListOffset;
|
||||
};
|
||||
|
||||
struct ContextualGlyphInsertionStateEntry2 : StateEntry2
|
||||
{
|
||||
le_uint16 currentInsertionListIndex;
|
||||
le_uint16 markedInsertionListIndex;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
143
icu4c/source/layout/ContextualGlyphInsertionProc2.cpp
Normal file
143
icu4c/source/layout/ContextualGlyphInsertionProc2.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphInsertionProc2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
|
||||
|
||||
ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: StateTableProcessor2(morphSubtableHeader)
|
||||
{
|
||||
contextualGlyphHeader = (const ContextualGlyphInsertionHeader2 *) morphSubtableHeader;
|
||||
le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
|
||||
insertionTable = ((le_uint16 *) ((char *)&stateTableHeader->stHeader + insertionTableOffset));
|
||||
entryTable = (const ContextualGlyphInsertionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
|
||||
}
|
||||
|
||||
ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void ContextualGlyphInsertionProcessor2::beginStateTable()
|
||||
{
|
||||
markGlyph = 0;
|
||||
}
|
||||
|
||||
le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
|
||||
{
|
||||
const ContextualGlyphInsertionStateEntry2 *entry = &entryTable[index];
|
||||
le_uint16 newState = SWAPW(entry->newStateIndex);
|
||||
le_uint16 flags = SWAPW(entry->flags);
|
||||
le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
|
||||
le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
|
||||
int i = 0;
|
||||
|
||||
if (markIndex > 0) {
|
||||
le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
|
||||
if (!(flags & cgiMarkedIsKashidaLike)) {
|
||||
// extra glyph(s) will be added directly before/after the specified marked glyph
|
||||
if (!(flags & cgiMarkInsertBefore)) {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
|
||||
for (i = 0; i < count; i++, markIndex++) {
|
||||
insertGlyphs[i] = insertionTable[markIndex];
|
||||
}
|
||||
insertGlyphs[i] = glyphStorage[markGlyph];
|
||||
glyphStorage.applyInsertions();
|
||||
} else {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
|
||||
insertGlyphs[0] = glyphStorage[markGlyph];
|
||||
for (i = 1; i < count + 1; i++, markIndex++) {
|
||||
insertGlyphs[i] = insertionTable[markIndex];
|
||||
}
|
||||
glyphStorage.applyInsertions();
|
||||
}
|
||||
} else {
|
||||
// inserted as a split-vowel-like insertion
|
||||
// extra glyph(s) will be inserted some distance away from the marked glyph
|
||||
if (!(flags & cgiMarkInsertBefore)) {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
|
||||
for (i = 0; i < count; i++, markIndex++) {
|
||||
insertGlyphs[i] = insertionTable[markIndex];
|
||||
}
|
||||
insertGlyphs[i] = glyphStorage[markGlyph];
|
||||
glyphStorage.applyInsertions();
|
||||
} else {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
|
||||
insertGlyphs[0] = glyphStorage[markGlyph];
|
||||
for (i = 1; i < count + 1; i++, markIndex++) {
|
||||
insertGlyphs[i] = insertionTable[markIndex];
|
||||
}
|
||||
glyphStorage.applyInsertions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currIndex > 0) {
|
||||
le_int16 count = flags & cgiCurrentInsertCountMask;
|
||||
if (!(flags & cgiCurrentIsKashidaLike)) {
|
||||
// extra glyph(s) will be added directly before/after the specified current glyph
|
||||
if (!(flags & cgiCurrentInsertBefore)) {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
|
||||
for (i = 0; i < count; i++, currIndex++) {
|
||||
insertGlyphs[i] = insertionTable[currIndex];
|
||||
}
|
||||
insertGlyphs[i] = glyphStorage[currGlyph];
|
||||
glyphStorage.applyInsertions();
|
||||
} else {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
|
||||
insertGlyphs[0] = glyphStorage[currGlyph];
|
||||
for (i = 1; i < count + 1; i++, currIndex++) {
|
||||
insertGlyphs[i] = insertionTable[currIndex];
|
||||
}
|
||||
glyphStorage.applyInsertions();
|
||||
}
|
||||
} else {
|
||||
// inserted as a split-vowel-like insertion
|
||||
// extra glyph(s) will be inserted some distance away from the current glyph
|
||||
if (!(flags & cgiCurrentInsertBefore)) {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
|
||||
for (i = 0; i < count; i++, currIndex++) {
|
||||
insertGlyphs[i] = insertionTable[currIndex];
|
||||
}
|
||||
insertGlyphs[i] = glyphStorage[currGlyph];
|
||||
glyphStorage.applyInsertions();
|
||||
} else {
|
||||
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
|
||||
insertGlyphs[0] = glyphStorage[currGlyph];
|
||||
for (i = 1; i < count + 1; i++, currIndex++) {
|
||||
insertGlyphs[i] = insertionTable[currIndex];
|
||||
}
|
||||
glyphStorage.applyInsertions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & cgiSetMark) {
|
||||
markGlyph = currGlyph;
|
||||
}
|
||||
|
||||
if (!(flags & cgiDontAdvance)) {
|
||||
currGlyph += dir;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
void ContextualGlyphInsertionProcessor2::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
64
icu4c/source/layout/ContextualGlyphInsertionProc2.h
Normal file
64
icu4c/source/layout/ContextualGlyphInsertionProc2.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
|
||||
#define __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphInsertionProc2.h"
|
||||
#include "ContextualGlyphInsertion.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
virtual ~ContextualGlyphInsertionProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
ContextualGlyphInsertionProcessor2();
|
||||
|
||||
protected:
|
||||
le_int32 markGlyph;
|
||||
const le_uint16* insertionTable;
|
||||
const ContextualGlyphInsertionStateEntry2 *entryTable;
|
||||
const ContextualGlyphInsertionHeader2 *contextualGlyphHeader;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
134
icu4c/source/layout/ContextualGlyphSubstProc2.cpp
Normal file
134
icu4c/source/layout/ContextualGlyphSubstProc2.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphSubstProc2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
#include <stdio.h>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
|
||||
|
||||
ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: StateTableProcessor2(morphSubtableHeader)
|
||||
{
|
||||
contextualGlyphHeader = (const ContextualGlyphHeader2 *) morphSubtableHeader;
|
||||
le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
|
||||
perGlyphTable = ((le_uint32 *) ((char *)&stateTableHeader->stHeader + perGlyphTableOffset));
|
||||
entryTable = (const ContextualGlyphStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
|
||||
}
|
||||
|
||||
ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void ContextualGlyphSubstitutionProcessor2::beginStateTable()
|
||||
{
|
||||
markGlyph = 0;
|
||||
}
|
||||
|
||||
le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
|
||||
{
|
||||
const ContextualGlyphStateEntry2 *entry = &entryTable[index];
|
||||
le_uint16 newState = SWAPW(entry->newStateIndex);
|
||||
le_uint16 flags = SWAPW(entry->flags);
|
||||
le_int16 markIndex = SWAPW(entry->markIndex);
|
||||
le_int16 currIndex = SWAPW(entry->currIndex);
|
||||
|
||||
if (markIndex != -1) {
|
||||
le_uint32 offset = SWAPL(perGlyphTable[markIndex]);
|
||||
LEGlyphID mGlyph = glyphStorage[markGlyph];
|
||||
TTGlyphID newGlyph = lookup(offset, mGlyph);
|
||||
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (currIndex != -1) {
|
||||
le_uint32 offset = SWAPL(perGlyphTable[currIndex]);
|
||||
LEGlyphID thisGlyph = glyphStorage[currGlyph];
|
||||
TTGlyphID newGlyph = lookup(offset, thisGlyph);
|
||||
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (flags & cgsSetMark) {
|
||||
markGlyph = currGlyph;
|
||||
}
|
||||
|
||||
if (!(flags & cgsDontAdvance)) {
|
||||
currGlyph += dir;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid)
|
||||
{
|
||||
LookupTable *lookupTable = ((LookupTable *) ((char *)perGlyphTable + offset));
|
||||
le_int16 format = SWAPW(lookupTable->format);
|
||||
TTGlyphID newGlyph = 0xFFFF;
|
||||
|
||||
switch (format) {
|
||||
case ltfSimpleArray: {
|
||||
#ifdef TEST_FORMAT
|
||||
// Disabled pending for design review
|
||||
SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) lookupTable;
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
|
||||
newGlyph = SWAPW(lookupTable0->valueArray[glyphCode]);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ltfSegmentSingle: {
|
||||
#ifdef TEST_FORMAT
|
||||
// Disabled pending for design review
|
||||
SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
|
||||
const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
|
||||
if (segment != NULL) {
|
||||
newGlyph = SWAPW(segment->value);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ltfSegmentArray: {
|
||||
printf("Context Lookup Table Format4: specific interpretation needed!\n");
|
||||
break;
|
||||
}
|
||||
case ltfSingleTable: {
|
||||
#ifdef TEST_FORMAT
|
||||
// Disabled pending for design review
|
||||
SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) lookupTable;
|
||||
const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
|
||||
if (segment != NULL) {
|
||||
newGlyph = SWAPW(segment->value);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ltfTrimmedArray: {
|
||||
TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) lookupTable;
|
||||
TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
|
||||
TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount);
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
|
||||
if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
|
||||
newGlyph = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return newGlyph;
|
||||
}
|
||||
|
||||
void ContextualGlyphSubstitutionProcessor2::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
67
icu4c/source/layout/ContextualGlyphSubstProc2.h
Normal file
67
icu4c/source/layout/ContextualGlyphSubstProc2.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
|
||||
#define __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "ContextualGlyphSubstitution.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
virtual ~ContextualGlyphSubstitutionProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
ContextualGlyphSubstitutionProcessor2();
|
||||
TTGlyphID lookup(le_uint32 offset, LEGlyphID gid);
|
||||
|
||||
protected:
|
||||
const le_uint32* perGlyphTable;
|
||||
const ContextualGlyphStateEntry2 *entryTable;
|
||||
|
||||
le_int16 perGlyphTableFormat;
|
||||
le_int32 markGlyph;
|
||||
|
||||
const ContextualGlyphHeader2 *contextualGlyphHeader;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,6 +24,11 @@ struct ContextualGlyphSubstitutionHeader : MorphStateTableHeader
|
||||
ByteOffset substitutionTableOffset;
|
||||
};
|
||||
|
||||
struct ContextualGlyphHeader2 : MorphStateTableHeader2
|
||||
{
|
||||
le_uint32 perGlyphTableOffset; // no more substitution tables
|
||||
};
|
||||
|
||||
enum ContextualGlyphSubstitutionFlags
|
||||
{
|
||||
cgsSetMark = 0x8000,
|
||||
@ -37,5 +42,11 @@ struct ContextualGlyphSubstitutionStateEntry : StateEntry
|
||||
WordOffset currOffset;
|
||||
};
|
||||
|
||||
struct ContextualGlyphStateEntry2 : StateEntry2
|
||||
{
|
||||
le_uint16 markIndex;
|
||||
le_uint16 currIndex;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
66
icu4c/source/layout/GXLayoutEngine2.cpp
Normal file
66
icu4c/source/layout/GXLayoutEngine2.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "GXLayoutEngine2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "MorphTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2)
|
||||
|
||||
GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success)
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
|
||||
{
|
||||
// nothing else to do?
|
||||
}
|
||||
|
||||
GXLayoutEngine2::~GXLayoutEngine2()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// apply 'morx' table
|
||||
le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, 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;
|
||||
}
|
||||
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fMorphTable->process(glyphStorage, fTypoFlags);
|
||||
return count;
|
||||
}
|
||||
|
||||
// apply positional tables
|
||||
void GXLayoutEngine2::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;
|
||||
}
|
||||
|
||||
// FIXME: no positional processing yet...
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
125
icu4c/source/layout/GXLayoutEngine2.h
Normal file
125
icu4c/source/layout/GXLayoutEngine2.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GXLAYOUTENGINE2_H
|
||||
#define __GXLAYOUTENGINE2_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
|
||||
#include "MorphTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEFontInstance;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements layout for QuickDraw GX or Apple Advanced Typograyph (AAT)
|
||||
* fonts. A font is a GX or AAT font if it contains a 'mort' table. See Apple's
|
||||
* TrueType Reference Manual (http://fonts.apple.com/TTRefMan/index.html) for details.
|
||||
* Information about 'mort' tables is in the chapter titled "Font Files."
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class GXLayoutEngine2 : public LayoutEngine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the main constructor. It constructs an instance of GXLayoutEngine for
|
||||
* a particular font, script and language. It takes the 'mort' table as a parameter since
|
||||
* LayoutEngine::layoutEngineFactory has to read the 'mort' table to know that it has a
|
||||
* GX font.
|
||||
*
|
||||
* Note: GX and AAT fonts don't contain any script and language specific tables, so
|
||||
* the script and language are ignored.
|
||||
*
|
||||
* @param fontInstance - the font
|
||||
* @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
|
||||
*/
|
||||
GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* The destructor, virtual for correct polymorphic invocation.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual ~GXLayoutEngine2();
|
||||
|
||||
/**
|
||||
* 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:
|
||||
|
||||
/**
|
||||
* The address of the 'mort' table
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
const MorphTableHeader2 *fMorphTable;
|
||||
|
||||
/**
|
||||
* This method does GX layout using the font's 'mort' table. It converts the
|
||||
* input character codes to glyph indices using mapCharsToGlyphs, and then
|
||||
* applies the 'mort' table.
|
||||
*
|
||||
* 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 text is in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the glyph index array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
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 adjusts the glyph positions using the font's
|
||||
* 'kern', 'trak', 'bsln', 'opbd' and 'just' tables.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param glyphStorage - the object holding the glyph storage. The positions will be updated as needed.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param success - 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
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and Others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,6 +24,10 @@ struct IndicRearrangementSubtableHeader : MorphStateTableHeader
|
||||
{
|
||||
};
|
||||
|
||||
struct IndicRearrangementSubtableHeader2 : MorphStateTableHeader2
|
||||
{
|
||||
};
|
||||
|
||||
enum IndicRearrangementFlags
|
||||
{
|
||||
irfMarkFirst = 0x8000,
|
||||
@ -60,6 +64,10 @@ struct IndicRearrangementStateEntry : StateEntry
|
||||
{
|
||||
};
|
||||
|
||||
struct IndicRearrangementStateEntry2 : StateEntry2
|
||||
{
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
398
icu4c/source/layout/IndicRearrangementProcessor2.cpp
Normal file
398
icu4c/source/layout/IndicRearrangementProcessor2.cpp
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "IndicRearrangementProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
|
||||
|
||||
IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: StateTableProcessor2(morphSubtableHeader)
|
||||
{
|
||||
indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader2 *) morphSubtableHeader;
|
||||
entryTable = (const IndicRearrangementStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
|
||||
}
|
||||
|
||||
IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor2::beginStateTable()
|
||||
{
|
||||
firstGlyph = 0;
|
||||
lastGlyph = 0;
|
||||
}
|
||||
|
||||
le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
|
||||
{
|
||||
const IndicRearrangementStateEntry2 *entry = &entryTable[index];
|
||||
le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
|
||||
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
|
||||
|
||||
if (flags & irfMarkFirst) {
|
||||
firstGlyph = currGlyph;
|
||||
}
|
||||
|
||||
if (flags & irfMarkLast) {
|
||||
lastGlyph = currGlyph;
|
||||
}
|
||||
|
||||
doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
|
||||
|
||||
if (!(flags & irfDontAdvance)) {
|
||||
currGlyph += dir;
|
||||
}
|
||||
|
||||
return newState; // index to new state
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor2::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
|
||||
{
|
||||
LEGlyphID a, b, c, d;
|
||||
le_int32 ia, ib, ic, id, ix, x;
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
case irvNoAction:
|
||||
break;
|
||||
|
||||
case irvxA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
x = firstGlyph + 1;
|
||||
|
||||
while (x <= lastGlyph) {
|
||||
glyphStorage[x - 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 1, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph] = a;
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDx:
|
||||
d = glyphStorage[lastGlyph];
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 1;
|
||||
|
||||
while (x >= firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
break;
|
||||
|
||||
case irvDxA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvxAB:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvxBA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDx:
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= firstGlyph) {
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
break;
|
||||
|
||||
case irvDCx:
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= firstGlyph) {
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
break;
|
||||
|
||||
case irvCDxA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x > firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x > firstGlyph) {
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDxAB:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x < lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDxBA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x < lastGlyph) {
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDxAB:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvCDxBA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxAB:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDCxBA:
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
63
icu4c/source/layout/IndicRearrangementProcessor2.h
Normal file
63
icu4c/source/layout/IndicRearrangementProcessor2.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INDICREARRANGEMENTPROCESSOR2_H
|
||||
#define __INDICREARRANGEMENTPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "IndicRearrangement.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class IndicRearrangementProcessor2 : public StateTableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
|
||||
|
||||
IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
virtual ~IndicRearrangementProcessor2();
|
||||
|
||||
/**
|
||||
* 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:
|
||||
le_int32 firstGlyph;
|
||||
le_int32 lastGlyph;
|
||||
|
||||
const IndicRearrangementStateEntry2 *entryTable;
|
||||
const IndicRearrangementSubtableHeader2 *indicRearrangementSubtableHeader;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2012 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -454,7 +454,7 @@ enum LEFeatureTags {
|
||||
LE_CALT_FEATURE_TAG = 0x63616C74UL, /**< 'calt' */
|
||||
LE_CASE_FEATURE_TAG = 0x63617365UL, /**< 'case' */
|
||||
LE_CCMP_FEATURE_TAG = 0x63636D70UL, /**< 'ccmp' */
|
||||
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
|
||||
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
|
||||
LE_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */
|
||||
LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */
|
||||
LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */
|
||||
@ -518,7 +518,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_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */
|
||||
LE_RTBD_FEATURE_TAG = 0x72746264UL, /**< 'rtbd' */
|
||||
LE_RTLA_FEATURE_TAG = 0x72746C61UL, /**< 'rtla' */
|
||||
LE_RUBY_FEATURE_TAG = 0x72756279UL, /**< 'ruby' */
|
||||
@ -569,6 +569,64 @@ enum LEFeatureTags {
|
||||
LE_ZERO_FEATURE_TAG = 0x7A65726FUL /**< 'zero' */
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
enum LEFeatureENUMs {
|
||||
LE_Kerning_FEATURE_ENUM = 0, /**< Requests Kerning. Formerly LayoutEngine::kTypoFlagKern */
|
||||
LE_Ligatures_FEATURE_ENUM = 1, /**< Requests Ligatures. Formerly LayoutEngine::kTypoFlagLiga */
|
||||
LE_CLIG_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_DLIG_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_HLIG_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_LIGA_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_RLIG_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SMCP_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_FRAC_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_AFRC_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_ZERO_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SWSH_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_CSWH_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SALT_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_NALT_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_RUBY_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SS01_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SS02_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SS03_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SS04_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SS05_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SS06_FEATURE_ENUM, /**< Feature specific enum */
|
||||
LE_SS07_FEATURE_ENUM, /**< Feature specific enum */
|
||||
|
||||
LE_CHAR_FILTER_FEATURE_ENUM = 31, /**< Apply CharSubstitutionFilter */
|
||||
LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM
|
||||
};
|
||||
|
||||
#define LE_Kerning_FEATURE_FLAG (1 << LE_Kerning_FEATURE_ENUM)
|
||||
#define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM)
|
||||
#define LE_CLIG_FEATURE_FLAG (1 << LE_CLIG_FEATURE_ENUM)
|
||||
#define LE_DLIG_FEATURE_FLAG (1 << LE_DLIG_FEATURE_ENUM)
|
||||
#define LE_HLIG_FEATURE_FLAG (1 << LE_HLIG_FEATURE_ENUM)
|
||||
#define LE_LIGA_FEATURE_FLAG (1 << LE_LIGA_FEATURE_ENUM)
|
||||
#define LE_RLIG_FEATURE_FLAG (1 << LE_RLIG_FEATURE_ENUM)
|
||||
#define LE_SMCP_FEATURE_FLAG (1 << LE_SMCP_FEATURE_ENUM)
|
||||
#define LE_FRAC_FEATURE_FLAG (1 << LE_FRAC_FEATURE_ENUM)
|
||||
#define LE_AFRC_FEATURE_FLAG (1 << LE_AFRC_FEATURE_ENUM)
|
||||
#define LE_ZERO_FEATURE_FLAG (1 << LE_ZERO_FEATURE_ENUM)
|
||||
#define LE_SWSH_FEATURE_FLAG (1 << LE_SWSH_FEATURE_ENUM)
|
||||
#define LE_CSWH_FEATURE_FLAG (1 << LE_CSWH_FEATURE_ENUM)
|
||||
#define LE_SALT_FEATURE_FLAG (1 << LE_SALT_FEATURE_ENUM)
|
||||
#define LE_NALT_FEATURE_FLAG (1 << LE_NALT_FEATURE_ENUM)
|
||||
#define LE_RUBY_FEATURE_FLAG (1 << LE_RUBY_FEATURE_ENUM)
|
||||
#define LE_SS01_FEATURE_FLAG (1 << LE_SS01_FEATURE_ENUM)
|
||||
#define LE_SS02_FEATURE_FLAG (1 << LE_SS02_FEATURE_ENUM)
|
||||
#define LE_SS03_FEATURE_FLAG (1 << LE_SS03_FEATURE_ENUM)
|
||||
#define LE_SS04_FEATURE_FLAG (1 << LE_SS04_FEATURE_ENUM)
|
||||
#define LE_SS05_FEATURE_FLAG (1 << LE_SS05_FEATURE_ENUM)
|
||||
#define LE_SS06_FEATURE_FLAG (1 << LE_SS06_FEATURE_ENUM)
|
||||
#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM)
|
||||
|
||||
#define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM)
|
||||
|
||||
/**
|
||||
* Error codes returned by the LayoutEngine.
|
||||
*
|
||||
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2011 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "LELanguages.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
#include "LayoutEngine.h"
|
||||
#include "ArabicLayoutEngine.h"
|
||||
@ -16,6 +17,8 @@
|
||||
#include "ThaiLayoutEngine.h"
|
||||
#include "TibetanLayoutEngine.h"
|
||||
#include "GXLayoutEngine.h"
|
||||
#include "GXLayoutEngine2.h"
|
||||
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "CharSubstitutionFilter.h"
|
||||
|
||||
@ -35,8 +38,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 le_int32 LayoutEngine::kTypoFlagKern = 0x1;
|
||||
const le_int32 LayoutEngine::kTypoFlagLiga = 0x2;
|
||||
/* TODO: remove these? */
|
||||
const le_int32 LayoutEngine::kTypoFlagKern = LE_Kerning_FEATURE_FLAG;
|
||||
const le_int32 LayoutEngine::kTypoFlagLiga = LE_Ligatures_FEATURE_FLAG;
|
||||
|
||||
const LEUnicode32 DefaultCharMapper::controlChars[] = {
|
||||
0x0009, 0x000A, 0x000D,
|
||||
@ -134,9 +138,9 @@ static const FeatureMap canonFeatureMap[] =
|
||||
|
||||
static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap);
|
||||
|
||||
LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
|
||||
le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
|
||||
le_int32 scriptCode,
|
||||
le_int32 languageCode,
|
||||
le_int32 typoFlags,
|
||||
LEErrorCode &success)
|
||||
: fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode),
|
||||
@ -144,7 +148,7 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fGlyphStorage = new LEGlyphStorage();
|
||||
if (fGlyphStorage == NULL) {
|
||||
@ -208,7 +212,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
|
||||
|
||||
if (canonGSUBTable->coversScript(scriptTag)) {
|
||||
CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
|
||||
if (substitutionFilter == NULL) {
|
||||
if (substitutionFilter == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
@ -398,7 +402,7 @@ void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter
|
||||
|
||||
for (p = 0; p < glyphCount; p += 1) {
|
||||
float next, xAdvance;
|
||||
|
||||
|
||||
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
|
||||
|
||||
xAdvance = next - prev;
|
||||
@ -440,7 +444,7 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
|
||||
|
||||
for (p = 0; p < charCount; p += 1, c += direction) {
|
||||
float next, xAdvance;
|
||||
|
||||
|
||||
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
|
||||
|
||||
xAdvance = next - prev;
|
||||
@ -495,7 +499,7 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_
|
||||
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);
|
||||
@ -507,17 +511,18 @@ void LayoutEngine::reset()
|
||||
{
|
||||
fGlyphStorage->reset();
|
||||
}
|
||||
|
||||
|
||||
LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
|
||||
{
|
||||
// 3 -> kerning and ligatures
|
||||
return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, 3, success);
|
||||
}
|
||||
|
||||
|
||||
LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
|
||||
{
|
||||
static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG;
|
||||
static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG;
|
||||
static const le_uint32 morxTableTag = LE_MORX_TABLE_TAG;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return NULL;
|
||||
@ -597,46 +602,63 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
|
||||
|
||||
if (morphTable != NULL) {
|
||||
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable, success);
|
||||
} else {
|
||||
switch (scriptCode) {
|
||||
case bengScriptCode:
|
||||
case devaScriptCode:
|
||||
case gujrScriptCode:
|
||||
case kndaScriptCode:
|
||||
case mlymScriptCode:
|
||||
case oryaScriptCode:
|
||||
case guruScriptCode:
|
||||
case tamlScriptCode:
|
||||
case teluScriptCode:
|
||||
case sinhScriptCode:
|
||||
{
|
||||
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
MorphTableHeader2 *table = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag);
|
||||
if (table != NULL) {
|
||||
le_uint32 version = SWAPL(table->version);
|
||||
switch (version) {
|
||||
case 0x10000: { // mort e.g.:Skia Regular
|
||||
const MorphTableHeader *mortTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
|
||||
if (mortTable != NULL) {
|
||||
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x20000: { // morx
|
||||
result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, table, typoFlags, success);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const MorphTableHeader *mortTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
|
||||
if (mortTable != NULL) { // mort
|
||||
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
|
||||
} else {
|
||||
switch (scriptCode) {
|
||||
case bengScriptCode:
|
||||
case devaScriptCode:
|
||||
case gujrScriptCode:
|
||||
case kndaScriptCode:
|
||||
case mlymScriptCode:
|
||||
case oryaScriptCode:
|
||||
case guruScriptCode:
|
||||
case tamlScriptCode:
|
||||
case teluScriptCode:
|
||||
case sinhScriptCode:
|
||||
{
|
||||
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case arabScriptCode:
|
||||
//case hebrScriptCode:
|
||||
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
case arabScriptCode:
|
||||
//case hebrScriptCode:
|
||||
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
|
||||
//case hebrScriptCode:
|
||||
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
|
||||
//case hebrScriptCode:
|
||||
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
|
||||
|
||||
case thaiScriptCode:
|
||||
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
case thaiScriptCode:
|
||||
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
|
||||
case hangScriptCode:
|
||||
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
case hangScriptCode:
|
||||
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
default:
|
||||
result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2011 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*/
|
||||
|
||||
#ifndef __LAYOUTENGINE_H
|
||||
@ -64,10 +64,10 @@ class LEGlyphStorage;
|
||||
class U_LAYOUT_API LayoutEngine : public UObject {
|
||||
public:
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/** @internal Flag to request kerning. */
|
||||
/** @internal Flag to request kerning. Use LE_Kerning_FEATURE_FLAG instead. */
|
||||
static const le_int32 kTypoFlagKern;
|
||||
/** @internal Flag to request ligatures. */
|
||||
static const le_int32 kTypoFlagLiga;
|
||||
/** @internal Flag to request ligatures. Use LE_Ligatures_FEATURE_FLAG instead. */
|
||||
static const le_int32 kTypoFlagLiga;
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
protected:
|
||||
|
116
icu4c/source/layout/LigatureSubstProc2.cpp
Normal file
116
icu4c/source/layout/LigatureSubstProc2.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp and Others. 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "LigatureSubstProc2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m))))
|
||||
#define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m))
|
||||
#define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
|
||||
|
||||
LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: StateTableProcessor2(morphSubtableHeader)
|
||||
{
|
||||
ligatureSubstitutionHeader = (const LigatureSubstitutionHeader2 *) morphSubtableHeader;
|
||||
ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
|
||||
componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
|
||||
ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
|
||||
|
||||
entryTable = (const LigatureSubstitutionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
|
||||
}
|
||||
|
||||
LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void LigatureSubstitutionProcessor2::beginStateTable()
|
||||
{
|
||||
m = -1;
|
||||
}
|
||||
|
||||
le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
|
||||
{
|
||||
const LigatureSubstitutionStateEntry2 *entry = &entryTable[index];
|
||||
le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
|
||||
le_uint16 flags = SWAPW(entry->entryFlags);
|
||||
le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
|
||||
|
||||
if (flags & lsfSetComponent) {
|
||||
if (++m >= nComponents) {
|
||||
m = 0;
|
||||
}
|
||||
componentStack[m] = currGlyph;
|
||||
}
|
||||
|
||||
ByteOffset actionOffset = flags & lsfPerformAction;
|
||||
|
||||
if (actionOffset != 0) {
|
||||
const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + ligActionOffset) + ligActionIndex;
|
||||
const TTGlyphID *ligatureTable = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + ligatureOffset);
|
||||
LigatureActionEntry action;
|
||||
le_int32 offset, i = 0;
|
||||
le_int32 stack[nComponents];
|
||||
le_int16 mm = -1;
|
||||
|
||||
const le_uint16 *componentTable = (const le_uint16 *)((char *) &ligatureSubstitutionHeader->stHeader + componentOffset);
|
||||
|
||||
do {
|
||||
le_uint32 componentGlyph = componentStack[m--]; // pop off
|
||||
|
||||
action = SWAPL(*ap++);
|
||||
|
||||
if (m < 0) {
|
||||
m = nComponents - 1;
|
||||
}
|
||||
|
||||
offset = action & lafComponentOffsetMask;
|
||||
if (offset != 0) {
|
||||
|
||||
i += SWAPW(componentTable[LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask))]);
|
||||
|
||||
if (action & (lafLast | lafStore)) {
|
||||
TTGlyphID ligatureGlyph = SWAPW(ligatureTable[i]);
|
||||
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
|
||||
stack[++mm] = componentGlyph;
|
||||
i = 0;
|
||||
} else {
|
||||
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
|
||||
}
|
||||
}
|
||||
} while (!(action & lafLast));
|
||||
|
||||
while (mm >= 0) {
|
||||
if (++m >= nComponents) {
|
||||
m = 0;
|
||||
}
|
||||
|
||||
componentStack[m] = stack[mm--];
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & lsfDontAdvance)) {
|
||||
currGlyph += dir;
|
||||
}
|
||||
|
||||
return nextStateIndex;
|
||||
}
|
||||
|
||||
void LigatureSubstitutionProcessor2::endStateTable()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
71
icu4c/source/layout/LigatureSubstProc2.h
Normal file
71
icu4c/source/layout/LigatureSubstProc2.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LIGATURESUBSTITUTIONPROCESSOR2_H
|
||||
#define __LIGATURESUBSTITUTIONPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "LigatureSubstitution.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
#define nComponents 16
|
||||
|
||||
class LigatureSubstitutionProcessor2 : public StateTableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
virtual ~LigatureSubstitutionProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
LigatureSubstitutionProcessor2();
|
||||
|
||||
protected:
|
||||
le_uint32 ligActionOffset;
|
||||
le_uint32 componentOffset;
|
||||
le_uint32 ligatureOffset;
|
||||
|
||||
const LigatureSubstitutionStateEntry2 *entryTable;
|
||||
|
||||
le_int32 componentStack[nComponents];
|
||||
le_int16 m;
|
||||
|
||||
const LigatureSubstitutionHeader2 *ligatureSubstitutionHeader;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and Others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -27,17 +27,32 @@ struct LigatureSubstitutionHeader : MorphStateTableHeader
|
||||
ByteOffset ligatureTableOffset;
|
||||
};
|
||||
|
||||
struct LigatureSubstitutionHeader2 : MorphStateTableHeader2
|
||||
{
|
||||
le_uint32 ligActionOffset;
|
||||
le_uint32 componentOffset;
|
||||
le_uint32 ligatureOffset;
|
||||
};
|
||||
|
||||
enum LigatureSubstitutionFlags
|
||||
{
|
||||
lsfSetComponent = 0x8000,
|
||||
lsfDontAdvance = 0x4000,
|
||||
lsfActionOffsetMask = 0x3FFF
|
||||
lsfActionOffsetMask = 0x3FFF, // N/A in morx
|
||||
lsfPerformAction = 0x2000
|
||||
};
|
||||
|
||||
struct LigatureSubstitutionStateEntry : StateEntry
|
||||
{
|
||||
};
|
||||
|
||||
struct LigatureSubstitutionStateEntry2
|
||||
{
|
||||
le_uint16 nextStateIndex;
|
||||
le_uint16 entryFlags;
|
||||
le_uint16 ligActionIndex;
|
||||
};
|
||||
|
||||
typedef le_uint32 LigatureActionEntry;
|
||||
|
||||
enum LigatureActionFlags
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2012 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -99,6 +99,10 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt
|
||||
}
|
||||
|
||||
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
|
||||
if (lookupTable == NULL) {
|
||||
success = LE_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
|
||||
GlyphIterator tempIterator(*glyphIterator, lookupFlags);
|
||||
le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#******************************************************************************
|
||||
#
|
||||
# Copyright (C) 1999-2011, International Business Machines
|
||||
# Copyright (C) 1999-2013, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#
|
||||
#******************************************************************************
|
||||
@ -130,7 +130,21 @@ TibetanLayoutEngine.o \
|
||||
TibetanReordering.o \
|
||||
HangulLayoutEngine.o \
|
||||
KernTable.o \
|
||||
loengine.o
|
||||
loengine.o \
|
||||
ContextualGlyphInsertionProc2.o \
|
||||
ContextualGlyphSubstProc2.o \
|
||||
GXLayoutEngine2.o \
|
||||
IndicRearrangementProcessor2.o \
|
||||
LigatureSubstProc2.o \
|
||||
MorphTables2.o \
|
||||
NonContextualGlyphSubstProc2.o \
|
||||
SegmentArrayProcessor2.o \
|
||||
SegmentSingleProcessor2.o \
|
||||
SimpleArrayProcessor2.o \
|
||||
SingleTableProcessor2.o \
|
||||
StateTableProcessor2.o \
|
||||
SubtableProcessor2.o \
|
||||
TrimmedArrayProcessor2.o
|
||||
|
||||
## Header files to install
|
||||
HEADERS= $(srcdir)/LayoutEngine.h $(srcdir)/LE*.h $(srcdir)/loengine.h
|
||||
@ -237,4 +251,3 @@ ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,5 +24,10 @@ struct MorphStateTableHeader : MorphSubtableHeader
|
||||
StateTableHeader stHeader;
|
||||
};
|
||||
|
||||
struct MorphStateTableHeader2 : MorphSubtableHeader2
|
||||
{
|
||||
StateTableHeader2 stHeader;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -51,6 +51,7 @@ struct MorphTableHeader
|
||||
};
|
||||
|
||||
typedef le_int16 SubtableCoverage;
|
||||
typedef le_uint32 SubtableCoverage2;
|
||||
|
||||
enum SubtableCoverageFlags
|
||||
{
|
||||
@ -80,6 +81,302 @@ struct MorphSubtableHeader
|
||||
void process(LEGlyphStorage &glyphStorage) const;
|
||||
};
|
||||
|
||||
enum SubtableCoverageFlags2
|
||||
{
|
||||
scfVertical2 = 0x80000000,
|
||||
scfReverse2 = 0x40000000,
|
||||
scfIgnoreVt2 = 0x20000000,
|
||||
scfReserved2 = 0x1FFFFF00,
|
||||
scfTypeMask2 = 0x000000FF
|
||||
};
|
||||
|
||||
struct MorphSubtableHeader2
|
||||
{
|
||||
le_uint32 length;
|
||||
SubtableCoverage2 coverage;
|
||||
FeatureFlags subtableFeatures;
|
||||
|
||||
void process(LEGlyphStorage &glyphStorage) const;
|
||||
};
|
||||
|
||||
struct ChainHeader2
|
||||
{
|
||||
FeatureFlags defaultFlags;
|
||||
le_uint32 chainLength;
|
||||
le_uint32 nFeatureEntries;
|
||||
le_uint32 nSubtables;
|
||||
FeatureTableEntry featureTable[ANY_NUMBER];
|
||||
};
|
||||
|
||||
struct MorphTableHeader2
|
||||
{
|
||||
le_int32 version;
|
||||
le_uint32 nChains;
|
||||
ChainHeader2 chains[ANY_NUMBER];
|
||||
|
||||
void process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* AAT Font Features
|
||||
* source: https://developer.apple.com/fonts/registry/
|
||||
* (plus addition from ATS/SFNTLayoutTypes.h)
|
||||
*/
|
||||
|
||||
enum {
|
||||
|
||||
allTypographicFeaturesType = 0,
|
||||
|
||||
allTypeFeaturesOnSelector = 0,
|
||||
allTypeFeaturesOffSelector = 1,
|
||||
|
||||
ligaturesType = 1,
|
||||
|
||||
requiredLigaturesOnSelector = 0,
|
||||
requiredLigaturesOffSelector = 1,
|
||||
commonLigaturesOnSelector = 2,
|
||||
commonLigaturesOffSelector = 3,
|
||||
rareLigaturesOnSelector = 4,
|
||||
rareLigaturesOffSelector = 5,
|
||||
logosOnSelector = 6,
|
||||
logosOffSelector = 7,
|
||||
rebusPicturesOnSelector = 8,
|
||||
rebusPicturesOffSelector = 9,
|
||||
diphthongLigaturesOnSelector = 10,
|
||||
diphthongLigaturesOffSelector = 11,
|
||||
squaredLigaturesOnSelector = 12,
|
||||
squaredLigaturesOffSelector = 13,
|
||||
abbrevSquaredLigaturesOnSelector = 14,
|
||||
abbrevSquaredLigaturesOffSelector = 15,
|
||||
symbolLigaturesOnSelector = 16,
|
||||
symbolLigaturesOffSelector = 17,
|
||||
contextualLigaturesOnSelector = 18,
|
||||
contextualLigaturesOffSelector = 19,
|
||||
historicalLigaturesOnSelector = 20,
|
||||
historicalLigaturesOffSelector = 21,
|
||||
|
||||
cursiveConnectionType = 2,
|
||||
|
||||
unconnectedSelector = 0,
|
||||
partiallyConnectedSelector = 1,
|
||||
cursiveSelector = 2,
|
||||
|
||||
letterCaseType = 3,
|
||||
|
||||
upperAndLowerCaseSelector = 0,
|
||||
allCapsSelector = 1,
|
||||
allLowerCaseSelector = 2,
|
||||
smallCapsSelector = 3,
|
||||
initialCapsSelector = 4,
|
||||
initialCapsAndSmallCapsSelector = 5,
|
||||
|
||||
verticalSubstitutionType = 4,
|
||||
|
||||
substituteVerticalFormsOnSelector = 0,
|
||||
substituteVerticalFormsOffSelector = 1,
|
||||
|
||||
linguisticRearrangementType = 5,
|
||||
|
||||
linguisticRearrangementOnSelector = 0,
|
||||
linguisticRearrangementOffSelector = 1,
|
||||
|
||||
numberSpacingType = 6,
|
||||
|
||||
monospacedNumbersSelector = 0,
|
||||
proportionalNumbersSelector = 1,
|
||||
|
||||
/*
|
||||
appleReserved1Type = 7,
|
||||
*/
|
||||
|
||||
smartSwashType = 8,
|
||||
|
||||
wordInitialSwashesOnSelector = 0,
|
||||
wordInitialSwashesOffSelector = 1,
|
||||
wordFinalSwashesOnSelector = 2,
|
||||
wordFinalSwashesOffSelector = 3,
|
||||
lineInitialSwashesOnSelector = 4,
|
||||
lineInitialSwashesOffSelector = 5,
|
||||
lineFinalSwashesOnSelector = 6,
|
||||
lineFinalSwashesOffSelector = 7,
|
||||
nonFinalSwashesOnSelector = 8,
|
||||
nonFinalSwashesOffSelector = 9,
|
||||
|
||||
diacriticsType = 9,
|
||||
|
||||
showDiacriticsSelector = 0,
|
||||
hideDiacriticsSelector = 1,
|
||||
decomposeDiacriticsSelector = 2,
|
||||
|
||||
verticalPositionType = 10,
|
||||
|
||||
normalPositionSelector = 0,
|
||||
superiorsSelector = 1,
|
||||
inferiorsSelector = 2,
|
||||
ordinalsSelector = 3,
|
||||
|
||||
fractionsType = 11,
|
||||
|
||||
noFractionsSelector = 0,
|
||||
verticalFractionsSelector = 1,
|
||||
diagonalFractionsSelector = 2,
|
||||
|
||||
/*
|
||||
appleReserved2Type = 12,
|
||||
*/
|
||||
|
||||
overlappingCharactersType = 13,
|
||||
|
||||
preventOverlapOnSelector = 0,
|
||||
preventOverlapOffSelector = 1,
|
||||
|
||||
typographicExtrasType = 14,
|
||||
|
||||
hyphensToEmDashOnSelector = 0,
|
||||
hyphensToEmDashOffSelector = 1,
|
||||
hyphenToEnDashOnSelector = 2,
|
||||
hyphenToEnDashOffSelector = 3,
|
||||
unslashedZeroOnSelector = 4,
|
||||
slashedZeroOffSelector = 4,
|
||||
unslashedZeroOffSelector = 5,
|
||||
slashedZeroOnSelector = 5,
|
||||
formInterrobangOnSelector = 6,
|
||||
formInterrobangOffSelector = 7,
|
||||
smartQuotesOnSelector = 8,
|
||||
smartQuotesOffSelector = 9,
|
||||
periodsToEllipsisOnSelector = 10,
|
||||
periodsToEllipsisOffSelector = 11,
|
||||
|
||||
mathematicalExtrasType = 15,
|
||||
|
||||
hyphenToMinusOnSelector = 0,
|
||||
hyphenToMinusOffSelector = 1,
|
||||
asteriskToMultiplyOnSelector = 2,
|
||||
asteriskToMultiplyOffSelector = 3,
|
||||
slashToDivideOnSelector = 4,
|
||||
slashToDivideOffSelector = 5,
|
||||
inequalityLigaturesOnSelector = 6,
|
||||
inequalityLigaturesOffSelector = 7,
|
||||
exponentsOnSelector = 8,
|
||||
exponentsOffSelector = 9,
|
||||
|
||||
ornamentSetsType = 16,
|
||||
|
||||
noOrnamentsSelector = 0,
|
||||
dingbatsSelector = 1,
|
||||
piCharactersSelector = 2,
|
||||
fleuronsSelector = 3,
|
||||
decorativeBordersSelector = 4,
|
||||
internationalSymbolsSelector = 5,
|
||||
mathSymbolsSelector = 6,
|
||||
|
||||
characterAlternativesType = 17,
|
||||
|
||||
noAlternatesSelector = 0,
|
||||
|
||||
designComplexityType = 18,
|
||||
|
||||
designLevel1Selector = 0,
|
||||
designLevel2Selector = 1,
|
||||
designLevel3Selector = 2,
|
||||
designLevel4Selector = 3,
|
||||
designLevel5Selector = 4,
|
||||
designLevel6Selector = 5,
|
||||
designLevel7Selector = 6,
|
||||
|
||||
styleOptionsType = 19,
|
||||
|
||||
noStyleOptionsSelector = 0,
|
||||
displayTextSelector = 1,
|
||||
engravedTextSelector = 2,
|
||||
illuminatedCapsSelector = 3,
|
||||
titlingCapsSelector = 4,
|
||||
tallCapsSelector = 5,
|
||||
|
||||
characterShapeType = 20,
|
||||
|
||||
traditionalCharactersSelector = 0,
|
||||
simplifiedCharactersSelector = 1,
|
||||
jis1978CharactersSelector = 2,
|
||||
jis1983CharactersSelector = 3,
|
||||
jis1990CharactersSelector = 4,
|
||||
traditionalAltOneSelector = 5,
|
||||
traditionalAltTwoSelector = 6,
|
||||
traditionalAltThreeSelector = 7,
|
||||
traditionalAltFourSelector = 8,
|
||||
traditionalAltFiveSelector = 9,
|
||||
expertCharactersSelector = 10,
|
||||
|
||||
numberCaseType = 21,
|
||||
|
||||
lowerCaseNumbersSelector = 0,
|
||||
upperCaseNumbersSelector = 1,
|
||||
|
||||
textSpacingType = 22,
|
||||
|
||||
proportionalTextSelector = 0,
|
||||
monospacedTextSelector = 1,
|
||||
halfWidthTextSelector = 2,
|
||||
normallySpacedTextSelector = 3,
|
||||
|
||||
transliterationType = 23,
|
||||
|
||||
noTransliterationSelector = 0,
|
||||
hanjaToHangulSelector = 1,
|
||||
hiraganaToKatakanaSelector = 2,
|
||||
katakanaToHiraganaSelector = 3,
|
||||
kanaToRomanizationSelector = 4,
|
||||
romanizationToHiraganaSelector = 5,
|
||||
romanizationToKatakanaSelector = 6,
|
||||
hanjaToHangulAltOneSelector = 7,
|
||||
hanjaToHangulAltTwoSelector = 8,
|
||||
hanjaToHangulAltThreeSelector = 9,
|
||||
|
||||
annotationType = 24,
|
||||
|
||||
noAnnotationSelector = 0,
|
||||
boxAnnotationSelector = 1,
|
||||
roundedBoxAnnotationSelector = 2,
|
||||
circleAnnotationSelector = 3,
|
||||
invertedCircleAnnotationSelector = 4,
|
||||
parenthesisAnnotationSelector = 5,
|
||||
periodAnnotationSelector = 6,
|
||||
romanNumeralAnnotationSelector = 7,
|
||||
diamondAnnotationSelector = 8,
|
||||
|
||||
kanaSpacingType = 25,
|
||||
|
||||
fullWidthKanaSelector = 0,
|
||||
proportionalKanaSelector = 1,
|
||||
|
||||
ideographicSpacingType = 26,
|
||||
|
||||
fullWidthIdeographsSelector = 0,
|
||||
proportionalIdeographsSelector = 1,
|
||||
|
||||
cjkRomanSpacingType = 103,
|
||||
|
||||
halfWidthCJKRomanSelector = 0,
|
||||
proportionalCJKRomanSelector = 1,
|
||||
defaultCJKRomanSelector = 2,
|
||||
fullWidthCJKRomanSelector = 3,
|
||||
|
||||
rubyKanaType = 28,
|
||||
|
||||
rubyKanaOnSelector = 2,
|
||||
rubyKanaOffSelector = 3,
|
||||
|
||||
/* The following types are provided for compatibility; note that
|
||||
their use is deprecated. */
|
||||
|
||||
adobeCharacterSpacingType = 100, /* prefer 22 */
|
||||
adobeKanaSpacingType = 101, /* prefer 25 */
|
||||
adobeKanjiSpacingType = 102, /* prefer 26 */
|
||||
adobeSquareLigatures = 104, /* prefer 1 */
|
||||
|
||||
lastFeatureType = -1
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
204
icu4c/source/layout/MorphTables2.cpp
Normal file
204
icu4c/source/layout/MorphTables2.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* (C) Copyright IBM Corp. and others 1998 - 2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutTables.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "IndicRearrangementProcessor2.h"
|
||||
#include "ContextualGlyphSubstProc2.h"
|
||||
#include "LigatureSubstProc2.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
#include "ContextualGlyphInsertionProc2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const
|
||||
{
|
||||
const ChainHeader2 *chainHeader = chains;
|
||||
le_uint32 chainCount = SWAPL(this->nChains);
|
||||
le_uint32 chain;
|
||||
|
||||
for (chain = 0; chain < chainCount; chain++) {
|
||||
FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
|
||||
le_uint32 chainLength = SWAPL(chainHeader->chainLength);
|
||||
le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
|
||||
le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
|
||||
const MorphSubtableHeader2 *subtableHeader =
|
||||
(const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries];
|
||||
le_uint32 subtable;
|
||||
|
||||
if (typoFlags != 0) {
|
||||
le_uint32 featureEntry;
|
||||
|
||||
// Feature subtables
|
||||
for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
|
||||
FeatureTableEntry featureTableEntry = chains->featureTable[featureEntry];
|
||||
le_int16 featureType = SWAPW(featureTableEntry.featureType);
|
||||
le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
|
||||
le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
|
||||
le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags);
|
||||
switch (featureType) {
|
||||
case ligaturesType:
|
||||
if ((typoFlags & LE_Ligatures_FEATURE_ENUM ) && (featureSetting ^ 0x1)){
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
} else {
|
||||
if (((typoFlags & LE_RLIG_FEATURE_FLAG) && featureSetting == requiredLigaturesOnSelector) ||
|
||||
((typoFlags & LE_CLIG_FEATURE_FLAG) && featureSetting == contextualLigaturesOnSelector) ||
|
||||
((typoFlags & LE_HLIG_FEATURE_FLAG) && featureSetting == historicalLigaturesOnSelector) ||
|
||||
((typoFlags & LE_LIGA_FEATURE_FLAG) && featureSetting == commonLigaturesOnSelector)) {
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case letterCaseType:
|
||||
if ((typoFlags & LE_SMCP_FEATURE_FLAG) && featureSetting == smallCapsSelector) {
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
}
|
||||
break;
|
||||
case verticalSubstitutionType:
|
||||
break;
|
||||
case linguisticRearrangementType:
|
||||
break;
|
||||
case numberSpacingType:
|
||||
break;
|
||||
case smartSwashType:
|
||||
if ((typoFlags & LE_SWSH_FEATURE_FLAG) && (featureSetting ^ 0x1)){
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
}
|
||||
break;
|
||||
case diacriticsType:
|
||||
break;
|
||||
case verticalPositionType:
|
||||
break;
|
||||
case fractionsType:
|
||||
if (((typoFlags & LE_FRAC_FEATURE_FLAG) && featureSetting == diagonalFractionsSelector) ||
|
||||
((typoFlags & LE_AFRC_FEATURE_FLAG) && featureSetting == verticalFractionsSelector)) {
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
} else {
|
||||
flag &= disableFlags;
|
||||
}
|
||||
break;
|
||||
case typographicExtrasType:
|
||||
if ((typoFlags & LE_ZERO_FEATURE_FLAG) && featureSetting == slashedZeroOnSelector) {
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
}
|
||||
break;
|
||||
case mathematicalExtrasType:
|
||||
break;
|
||||
case ornamentSetsType:
|
||||
break;
|
||||
case characterAlternativesType:
|
||||
break;
|
||||
case designComplexityType:
|
||||
if (((typoFlags & LE_SS01_FEATURE_FLAG) && featureSetting == designLevel1Selector) ||
|
||||
((typoFlags & LE_SS02_FEATURE_FLAG) && featureSetting == designLevel2Selector) ||
|
||||
((typoFlags & LE_SS03_FEATURE_FLAG) && featureSetting == designLevel3Selector) ||
|
||||
((typoFlags & LE_SS04_FEATURE_FLAG) && featureSetting == designLevel4Selector) ||
|
||||
((typoFlags & LE_SS05_FEATURE_FLAG) && featureSetting == designLevel5Selector) ||
|
||||
((typoFlags & LE_SS06_FEATURE_FLAG) && featureSetting == designLevel6Selector) ||
|
||||
((typoFlags & LE_SS07_FEATURE_FLAG) && featureSetting == designLevel7Selector)) {
|
||||
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
}
|
||||
break;
|
||||
case styleOptionsType:
|
||||
break;
|
||||
case characterShapeType:
|
||||
break;
|
||||
case numberCaseType:
|
||||
break;
|
||||
case textSpacingType:
|
||||
break;
|
||||
case transliterationType:
|
||||
break;
|
||||
case annotationType:
|
||||
if ((typoFlags & LE_NALT_FEATURE_FLAG) && featureSetting == circleAnnotationSelector) {
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
}
|
||||
break;
|
||||
case kanaSpacingType:
|
||||
break;
|
||||
case ideographicSpacingType:
|
||||
break;
|
||||
case rubyKanaType:
|
||||
if ((typoFlags & LE_RUBY_FEATURE_FLAG) && featureSetting == rubyKanaOnSelector) {
|
||||
flag &= disableFlags;
|
||||
flag |= enableFlags;
|
||||
}
|
||||
break;
|
||||
case cjkRomanSpacingType:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (subtable = 0; subtable < nSubtables; subtable++) {
|
||||
le_uint32 length = SWAPL(subtableHeader->length);
|
||||
le_uint32 coverage = SWAPL(subtableHeader->coverage);
|
||||
FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
|
||||
// should check coverage more carefully...
|
||||
if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) {
|
||||
subtableHeader->process(glyphStorage);
|
||||
}
|
||||
subtableHeader = (const MorphSubtableHeader2 *) ((char *)subtableHeader + length);
|
||||
}
|
||||
chainHeader = (const ChainHeader2 *)((char *)chainHeader + chainLength);
|
||||
}
|
||||
}
|
||||
|
||||
void MorphSubtableHeader2::process(LEGlyphStorage &glyphStorage) const
|
||||
{
|
||||
SubtableProcessor2 *processor = NULL;
|
||||
|
||||
switch (SWAPL(coverage) & scfTypeMask2)
|
||||
{
|
||||
case mstIndicRearrangement:
|
||||
processor = new IndicRearrangementProcessor2(this);
|
||||
break;
|
||||
|
||||
case mstContextualGlyphSubstitution:
|
||||
processor = new ContextualGlyphSubstitutionProcessor2(this);
|
||||
break;
|
||||
|
||||
case mstLigatureSubstitution:
|
||||
processor = new LigatureSubstitutionProcessor2(this);
|
||||
break;
|
||||
|
||||
case mstReservedUnused:
|
||||
break;
|
||||
|
||||
case mstNonContextualGlyphSubstitution:
|
||||
processor = NonContextualGlyphSubstitutionProcessor2::createInstance(this);
|
||||
break;
|
||||
|
||||
|
||||
case mstContextualGlyphInsertion:
|
||||
processor = new ContextualGlyphInsertionProcessor2(this);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (processor != NULL) {
|
||||
processor->process(glyphStorage);
|
||||
delete processor;
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
@ -1,7 +1,5 @@
|
||||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -25,6 +23,11 @@ struct NonContextualGlyphSubstitutionHeader : MorphSubtableHeader
|
||||
LookupTable table;
|
||||
};
|
||||
|
||||
struct NonContextualGlyphSubstitutionHeader2 : MorphSubtableHeader2
|
||||
{
|
||||
LookupTable table;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
60
icu4c/source/layout/NonContextualGlyphSubstProc2.cpp
Normal file
60
icu4c/source/layout/NonContextualGlyphSubstProc2.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
#include "SimpleArrayProcessor2.h"
|
||||
#include "SegmentSingleProcessor2.h"
|
||||
#include "SegmentArrayProcessor2.h"
|
||||
#include "SingleTableProcessor2.h"
|
||||
#include "TrimmedArrayProcessor2.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: SubtableProcessor2(morphSubtableHeader)
|
||||
{
|
||||
}
|
||||
|
||||
NonContextualGlyphSubstitutionProcessor2::~NonContextualGlyphSubstitutionProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
SubtableProcessor2 *NonContextualGlyphSubstitutionProcessor2::createInstance(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
{
|
||||
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
|
||||
|
||||
switch (SWAPW(header->table.format))
|
||||
{
|
||||
case ltfSimpleArray:
|
||||
return new SimpleArrayProcessor2(morphSubtableHeader);
|
||||
|
||||
case ltfSegmentSingle:
|
||||
return new SegmentSingleProcessor2(morphSubtableHeader);
|
||||
|
||||
case ltfSegmentArray:
|
||||
return new SegmentArrayProcessor2(morphSubtableHeader);
|
||||
|
||||
case ltfSingleTable:
|
||||
return new SingleTableProcessor2(morphSubtableHeader);
|
||||
|
||||
case ltfTrimmedArray:
|
||||
return new TrimmedArrayProcessor2(morphSubtableHeader);
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
43
icu4c/source/layout/NonContextualGlyphSubstProc2.h
Normal file
43
icu4c/source/layout/NonContextualGlyphSubstProc2.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NONCONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
|
||||
#define __NONCONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class NonContextualGlyphSubstitutionProcessor2 : public SubtableProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphStorage &glyphStorage) = 0;
|
||||
|
||||
static SubtableProcessor2 *createInstance(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
protected:
|
||||
NonContextualGlyphSubstitutionProcessor2();
|
||||
NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
virtual ~NonContextualGlyphSubstitutionProcessor2();
|
||||
|
||||
private:
|
||||
NonContextualGlyphSubstitutionProcessor2(const NonContextualGlyphSubstitutionProcessor2 &other); // forbid copying of this class
|
||||
NonContextualGlyphSubstitutionProcessor2 &operator=(const NonContextualGlyphSubstitutionProcessor2 &other); // forbid copying of this class
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2012 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -39,11 +39,27 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine)
|
||||
#define loclFeatureTag LE_LOCL_FEATURE_TAG
|
||||
#define caltFeatureTag LE_CALT_FEATURE_TAG
|
||||
|
||||
// 'dlig' not used at the moment
|
||||
#define dligFeatureTag 0x646C6967
|
||||
#define dligFeatureTag LE_DLIG_FEATURE_TAG
|
||||
#define rligFeatureTag LE_RLIG_FEATURE_TAG
|
||||
#define paltFeatureTag LE_PALT_FEATURE_TAG
|
||||
|
||||
// 'palt'
|
||||
#define paltFeatureTag 0x70616C74
|
||||
#define hligFeatureTag LE_HLIG_FEATURE_TAG
|
||||
#define smcpFeatureTag LE_SMCP_FEATURE_TAG
|
||||
#define fracFeatureTag LE_FRAC_FEATURE_TAG
|
||||
#define afrcFeatureTag LE_AFRC_FEATURE_TAG
|
||||
#define zeroFeatureTag LE_ZERO_FEATURE_TAG
|
||||
#define swshFeatureTag LE_SWSH_FEATURE_TAG
|
||||
#define cswhFeatureTag LE_CSWH_FEATURE_TAG
|
||||
#define saltFeatureTag LE_SALT_FEATURE_TAG
|
||||
#define naltFeatureTag LE_NALT_FEATURE_TAG
|
||||
#define rubyFeatureTag LE_RUBY_FEATURE_TAG
|
||||
#define ss01FeatureTag LE_SS01_FEATURE_TAG
|
||||
#define ss02FeatureTag LE_SS02_FEATURE_TAG
|
||||
#define ss03FeatureTag LE_SS03_FEATURE_TAG
|
||||
#define ss04FeatureTag LE_SS04_FEATURE_TAG
|
||||
#define ss05FeatureTag LE_SS05_FEATURE_TAG
|
||||
#define ss06FeatureTag LE_SS06_FEATURE_TAG
|
||||
#define ss07FeatureTag LE_SS07_FEATURE_TAG
|
||||
|
||||
#define ccmpFeatureMask 0x80000000UL
|
||||
#define ligaFeatureMask 0x40000000UL
|
||||
@ -55,10 +71,27 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine)
|
||||
#define loclFeatureMask 0x01000000UL
|
||||
#define caltFeatureMask 0x00800000UL
|
||||
|
||||
#define dligFeatureMask 0x00400000UL
|
||||
#define rligFeatureMask 0x00200000UL
|
||||
#define hligFeatureMask 0x00100000UL
|
||||
#define smcpFeatureMask 0x00080000UL
|
||||
#define fracFeatureMask 0x00040000UL
|
||||
#define afrcFeatureMask 0x00020000UL
|
||||
#define zeroFeatureMask 0x00010000UL
|
||||
#define swshFeatureMask 0x00008000UL
|
||||
#define cswhFeatureMask 0x00004000UL
|
||||
#define saltFeatureMask 0x00002000UL
|
||||
#define naltFeatureMask 0x00001000UL
|
||||
#define rubyFeatureMask 0x00000800UL
|
||||
#define ss01FeatureMask 0x00000400UL
|
||||
#define ss02FeatureMask 0x00000200UL
|
||||
#define ss03FeatureMask 0x00000100UL
|
||||
#define ss04FeatureMask 0x00000080UL
|
||||
#define ss05FeatureMask 0x00000040UL
|
||||
#define ss06FeatureMask 0x00000020UL
|
||||
#define ss07FeatureMask 0x00000010UL
|
||||
|
||||
#define minimalFeatures (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask | loclFeatureMask | caltFeatureMask)
|
||||
#define ligaFeatures (ligaFeatureMask | cligFeatureMask | minimalFeatures)
|
||||
#define kernFeatures (kernFeatureMask | paltFeatureMask | minimalFeatures)
|
||||
#define kernAndLigaFeatures (ligaFeatures | kernFeatures)
|
||||
|
||||
static const FeatureMap featureMap[] =
|
||||
{
|
||||
@ -70,7 +103,24 @@ static const FeatureMap featureMap[] =
|
||||
{markFeatureTag, markFeatureMask},
|
||||
{mkmkFeatureTag, mkmkFeatureMask},
|
||||
{loclFeatureTag, loclFeatureMask},
|
||||
{caltFeatureTag, caltFeatureMask}
|
||||
{caltFeatureTag, caltFeatureMask},
|
||||
{hligFeatureTag, hligFeatureMask},
|
||||
{smcpFeatureTag, smcpFeatureMask},
|
||||
{fracFeatureTag, fracFeatureMask},
|
||||
{afrcFeatureTag, afrcFeatureMask},
|
||||
{zeroFeatureTag, zeroFeatureMask},
|
||||
{swshFeatureTag, swshFeatureMask},
|
||||
{cswhFeatureTag, cswhFeatureMask},
|
||||
{saltFeatureTag, saltFeatureMask},
|
||||
{naltFeatureTag, naltFeatureMask},
|
||||
{rubyFeatureTag, rubyFeatureMask},
|
||||
{ss01FeatureTag, ss01FeatureMask},
|
||||
{ss02FeatureTag, ss02FeatureMask},
|
||||
{ss03FeatureTag, ss03FeatureMask},
|
||||
{ss04FeatureTag, ss04FeatureMask},
|
||||
{ss05FeatureTag, ss05FeatureMask},
|
||||
{ss06FeatureTag, ss06FeatureMask},
|
||||
{ss07FeatureTag, ss07FeatureMask}
|
||||
};
|
||||
|
||||
static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
|
||||
@ -85,17 +135,65 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, l
|
||||
static const le_uint32 gposTableTag = LE_GPOS_TABLE_TAG;
|
||||
const GlyphPositioningTableHeader *gposTable = (const GlyphPositioningTableHeader *) getFontTable(gposTableTag);
|
||||
|
||||
// todo: switch to more flags and bitfield rather than list of feature tags?
|
||||
switch (typoFlags & ~0x80000000L) {
|
||||
case 0: break; // default
|
||||
case 1: fFeatureMask = kernFeatures; break;
|
||||
case 2: fFeatureMask = ligaFeatures; break;
|
||||
case 3: fFeatureMask = kernAndLigaFeatures; break;
|
||||
default: break;
|
||||
switch (typoFlags & (LE_SS01_FEATURE_FLAG
|
||||
| LE_SS02_FEATURE_FLAG
|
||||
| LE_SS03_FEATURE_FLAG
|
||||
| LE_SS04_FEATURE_FLAG
|
||||
| LE_SS05_FEATURE_FLAG
|
||||
| LE_SS06_FEATURE_FLAG
|
||||
| LE_SS07_FEATURE_FLAG)) {
|
||||
case LE_SS01_FEATURE_FLAG:
|
||||
fFeatureMask |= ss01FeatureMask;
|
||||
break;
|
||||
case LE_SS02_FEATURE_FLAG:
|
||||
fFeatureMask |= ss02FeatureMask;
|
||||
break;
|
||||
case LE_SS03_FEATURE_FLAG:
|
||||
fFeatureMask |= ss03FeatureMask;
|
||||
break;
|
||||
case LE_SS04_FEATURE_FLAG:
|
||||
fFeatureMask |= ss04FeatureMask;
|
||||
break;
|
||||
case LE_SS05_FEATURE_FLAG:
|
||||
fFeatureMask |= ss05FeatureMask;
|
||||
break;
|
||||
case LE_SS06_FEATURE_FLAG:
|
||||
fFeatureMask |= ss06FeatureMask;
|
||||
break;
|
||||
case LE_SS07_FEATURE_FLAG:
|
||||
fFeatureMask |= ss07FeatureMask;
|
||||
break;
|
||||
}
|
||||
|
||||
if (typoFlags & 0x80000000L) {
|
||||
fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
|
||||
if (typoFlags & LE_Kerning_FEATURE_FLAG) {
|
||||
fFeatureMask |= (kernFeatureMask | paltFeatureMask);
|
||||
// Convenience.
|
||||
}
|
||||
if (typoFlags & LE_Ligatures_FEATURE_FLAG) {
|
||||
fFeatureMask |= (ligaFeatureMask | cligFeatureMask);
|
||||
// Convenience TODO: should add: .. dligFeatureMask | rligFeatureMask ?
|
||||
}
|
||||
if (typoFlags & LE_CLIG_FEATURE_FLAG) fFeatureMask |= cligFeatureMask;
|
||||
if (typoFlags & LE_DLIG_FEATURE_FLAG) fFeatureMask |= dligFeatureMask;
|
||||
if (typoFlags & LE_HLIG_FEATURE_FLAG) fFeatureMask |= hligFeatureMask;
|
||||
if (typoFlags & LE_LIGA_FEATURE_FLAG) fFeatureMask |= ligaFeatureMask;
|
||||
if (typoFlags & LE_RLIG_FEATURE_FLAG) fFeatureMask |= rligFeatureMask;
|
||||
if (typoFlags & LE_SMCP_FEATURE_FLAG) fFeatureMask |= smcpFeatureMask;
|
||||
if (typoFlags & LE_FRAC_FEATURE_FLAG) fFeatureMask |= fracFeatureMask;
|
||||
if (typoFlags & LE_AFRC_FEATURE_FLAG) fFeatureMask |= afrcFeatureMask;
|
||||
if (typoFlags & LE_ZERO_FEATURE_FLAG) fFeatureMask |= zeroFeatureMask;
|
||||
if (typoFlags & LE_SWSH_FEATURE_FLAG) fFeatureMask |= swshFeatureMask;
|
||||
if (typoFlags & LE_CSWH_FEATURE_FLAG) fFeatureMask |= cswhFeatureMask;
|
||||
if (typoFlags & LE_SALT_FEATURE_FLAG) fFeatureMask |= saltFeatureMask;
|
||||
if (typoFlags & LE_RUBY_FEATURE_FLAG) fFeatureMask |= rubyFeatureMask;
|
||||
if (typoFlags & LE_NALT_FEATURE_FLAG) {
|
||||
// Mutually exclusive with ALL other features. http://www.microsoft.com/typography/otspec/features_ko.htm
|
||||
fFeatureMask = naltFeatureMask;
|
||||
}
|
||||
|
||||
if (typoFlags & LE_CHAR_FILTER_FEATURE_FLAG) {
|
||||
// This isn't a font feature, but requests a Char Substitution Filter
|
||||
fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
|
||||
}
|
||||
|
||||
setScriptAndLanguageTags();
|
||||
|
60
icu4c/source/layout/SegmentArrayProcessor2.cpp
Normal file
60
icu4c/source/layout/SegmentArrayProcessor2.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
#include "SegmentArrayProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SegmentArrayProcessor2)
|
||||
|
||||
SegmentArrayProcessor2::SegmentArrayProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
SegmentArrayProcessor2::SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
|
||||
{
|
||||
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
|
||||
|
||||
segmentArrayLookupTable = (const SegmentArrayLookupTable *) &header->table;
|
||||
}
|
||||
|
||||
SegmentArrayProcessor2::~SegmentArrayProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
const LookupSegment *segments = segmentArrayLookupTable->segments;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
LEGlyphID thisGlyph = glyphStorage[glyph];
|
||||
const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, thisGlyph);
|
||||
|
||||
if (lookupSegment != NULL) {
|
||||
TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
|
||||
le_int16 offset = SWAPW(lookupSegment->value);
|
||||
|
||||
if (offset != 0) {
|
||||
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset);
|
||||
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
|
||||
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
58
icu4c/source/layout/SegmentArrayProcessor2.h
Normal file
58
icu4c/source/layout/SegmentArrayProcessor2.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SEGMENTARRAYPROCESSOR_H
|
||||
#define __SEGMENTARRAYPROCESSOR_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SegmentArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
virtual ~SegmentArrayProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
SegmentArrayProcessor2();
|
||||
|
||||
protected:
|
||||
const SegmentArrayLookupTable *segmentArrayLookupTable;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
54
icu4c/source/layout/SegmentSingleProcessor2.cpp
Normal file
54
icu4c/source/layout/SegmentSingleProcessor2.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
#include "SegmentSingleProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SegmentSingleProcessor2)
|
||||
|
||||
SegmentSingleProcessor2::SegmentSingleProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
SegmentSingleProcessor2::SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
|
||||
{
|
||||
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
|
||||
|
||||
segmentSingleLookupTable = (const SegmentSingleLookupTable *) &header->table;
|
||||
}
|
||||
|
||||
SegmentSingleProcessor2::~SegmentSingleProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
const LookupSegment *segments = segmentSingleLookupTable->segments;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
LEGlyphID thisGlyph = glyphStorage[glyph];
|
||||
const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph);
|
||||
|
||||
if (lookupSegment != NULL) {
|
||||
TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value);
|
||||
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
58
icu4c/source/layout/SegmentSingleProcessor2.h
Normal file
58
icu4c/source/layout/SegmentSingleProcessor2.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SEGMENTSINGLEPROCESSOR_H
|
||||
#define __SEGMENTSINGLEPROCESSOR_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SegmentSingleProcessor2 : public NonContextualGlyphSubstitutionProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
virtual ~SegmentSingleProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
SegmentSingleProcessor2();
|
||||
|
||||
protected:
|
||||
const SegmentSingleLookupTable *segmentSingleLookupTable;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
51
icu4c/source/layout/SimpleArrayProcessor2.cpp
Normal file
51
icu4c/source/layout/SimpleArrayProcessor2.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
#include "SimpleArrayProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleArrayProcessor2)
|
||||
|
||||
SimpleArrayProcessor2::SimpleArrayProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
SimpleArrayProcessor2::SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
|
||||
{
|
||||
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
|
||||
|
||||
simpleArrayLookupTable = (const SimpleArrayLookupTable *) &header->table;
|
||||
}
|
||||
|
||||
SimpleArrayProcessor2::~SimpleArrayProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleArrayProcessor2::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
LEGlyphID thisGlyph = glyphStorage[glyph];
|
||||
if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) {
|
||||
TTGlyphID newGlyph = SWAPW(simpleArrayLookupTable->valueArray[LE_GET_GLYPH(thisGlyph)]);
|
||||
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
58
icu4c/source/layout/SimpleArrayProcessor2.h
Normal file
58
icu4c/source/layout/SimpleArrayProcessor2.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SIMPLEARRAYPROCESSOR2_H
|
||||
#define __SIMPLEARRAYPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SimpleArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
virtual ~SimpleArrayProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
SimpleArrayProcessor2();
|
||||
|
||||
protected:
|
||||
const SimpleArrayLookupTable *simpleArrayLookupTable;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
51
icu4c/source/layout/SingleTableProcessor2.cpp
Normal file
51
icu4c/source/layout/SingleTableProcessor2.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
#include "SingleTableProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SingleTableProcessor2)
|
||||
|
||||
SingleTableProcessor2::SingleTableProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
SingleTableProcessor2::SingleTableProcessor2(const MorphSubtableHeader2 *moprhSubtableHeader)
|
||||
: NonContextualGlyphSubstitutionProcessor2(moprhSubtableHeader)
|
||||
{
|
||||
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) moprhSubtableHeader;
|
||||
|
||||
singleTableLookupTable = (const SingleTableLookupTable *) &header->table;
|
||||
}
|
||||
|
||||
SingleTableProcessor2::~SingleTableProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void SingleTableProcessor2::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
const LookupSingle *entries = singleTableLookupTable->entries;
|
||||
le_int32 glyph;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(entries, glyphStorage[glyph]);
|
||||
|
||||
if (lookupSingle != NULL) {
|
||||
glyphStorage[glyph] = SWAPW(lookupSingle->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
57
icu4c/source/layout/SingleTableProcessor2.h
Normal file
57
icu4c/source/layout/SingleTableProcessor2.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SINGLETABLEPROCESSOR2_H
|
||||
#define __SINGLETABLEPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SingleTableProcessor2 : public NonContextualGlyphSubstitutionProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SingleTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
virtual ~SingleTableProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
SingleTableProcessor2();
|
||||
|
||||
protected:
|
||||
const SingleTableLookupTable *singleTableLookupTable;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
167
icu4c/source/layout/StateTableProcessor2.cpp
Normal file
167
icu4c/source/layout/StateTableProcessor2.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "StateTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "StateTableProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
#include "LookupTables.h"
|
||||
#include <stdio.h>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
StateTableProcessor2::StateTableProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
StateTableProcessor2::StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: SubtableProcessor2(morphSubtableHeader)
|
||||
{
|
||||
stateTableHeader = (const MorphStateTableHeader2 *) morphSubtableHeader;
|
||||
nClasses = SWAPL(stateTableHeader->stHeader.nClasses);
|
||||
classTableOffset = SWAPL(stateTableHeader->stHeader.classTableOffset);
|
||||
stateArrayOffset = SWAPL(stateTableHeader->stHeader.stateArrayOffset);
|
||||
entryTableOffset = SWAPL(stateTableHeader->stHeader.entryTableOffset);
|
||||
|
||||
classTable = (LookupTable *) ((char *) &stateTableHeader->stHeader + classTableOffset);
|
||||
format = SWAPW(classTable->format);
|
||||
|
||||
stateArray = (const EntryTableIndex2 *) ((char *) &stateTableHeader->stHeader + stateArrayOffset);
|
||||
}
|
||||
|
||||
StateTableProcessor2::~StateTableProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
// Start at state 0
|
||||
// XXX: How do we know when to start at state 1?
|
||||
le_uint16 currentState = 0;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
le_int32 currGlyph = 0;
|
||||
if ((coverage & scfReverse2) != 0) { // process glyphs in descending order
|
||||
currGlyph = glyphCount - 1;
|
||||
dir = -1;
|
||||
} else {
|
||||
dir = 1;
|
||||
}
|
||||
|
||||
beginStateTable();
|
||||
switch (format) {
|
||||
case ltfSimpleArray: {
|
||||
printf("Lookup Table Format0 untested!\n");
|
||||
SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) classTable;
|
||||
while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
|
||||
LookupValue classCode = classCodeOOB;
|
||||
if (currGlyph == glyphCount || currGlyph == -1) {
|
||||
// XXX: How do we handle EOT vs. EOL?
|
||||
classCode = classCodeEOT;
|
||||
} else {
|
||||
LEGlyphID gid = glyphStorage[currGlyph];
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
|
||||
|
||||
if (glyphCode == 0xFFFF) {
|
||||
classCode = classCodeDEL;
|
||||
} else {
|
||||
classCode = SWAPW(lookupTable0->valueArray[gid]);
|
||||
}
|
||||
}
|
||||
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
|
||||
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ltfSegmentSingle: {
|
||||
SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) classTable;
|
||||
while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
|
||||
LookupValue classCode = classCodeOOB;
|
||||
if (currGlyph == glyphCount || currGlyph == -1) {
|
||||
// XXX: How do we handle EOT vs. EOL?
|
||||
classCode = classCodeEOT;
|
||||
} else {
|
||||
LEGlyphID gid = glyphStorage[currGlyph];
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
|
||||
|
||||
if (glyphCode == 0xFFFF) {
|
||||
classCode = classCodeDEL;
|
||||
} else {
|
||||
const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
|
||||
if (segment != NULL) {
|
||||
classCode = SWAPW(segment->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
|
||||
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ltfSegmentArray: {
|
||||
printf("Lookup Table Format4: specific interpretation needed!\n");
|
||||
break;
|
||||
}
|
||||
case ltfSingleTable: {
|
||||
SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) classTable;
|
||||
while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
|
||||
LookupValue classCode = classCodeOOB;
|
||||
if (currGlyph == glyphCount || currGlyph == -1) {
|
||||
// XXX: How do we handle EOT vs. EOL?
|
||||
classCode = classCodeEOT;
|
||||
} else {
|
||||
LEGlyphID gid = glyphStorage[currGlyph];
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
|
||||
|
||||
if (glyphCode == 0xFFFF) {
|
||||
classCode = classCodeDEL;
|
||||
} else {
|
||||
const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
|
||||
if (segment != NULL) {
|
||||
classCode = SWAPW(segment->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
|
||||
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ltfTrimmedArray: {
|
||||
TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) classTable;
|
||||
TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
|
||||
TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount);
|
||||
|
||||
while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
|
||||
LookupValue classCode = classCodeOOB;
|
||||
if (currGlyph == glyphCount || currGlyph == -1) {
|
||||
// XXX: How do we handle EOT vs. EOL?
|
||||
classCode = classCodeEOT;
|
||||
} else {
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
|
||||
if (glyphCode == 0xFFFF) {
|
||||
classCode = classCodeDEL;
|
||||
} else if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
|
||||
classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
|
||||
}
|
||||
}
|
||||
EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
|
||||
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
endStateTable();
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
59
icu4c/source/layout/StateTableProcessor2.h
Normal file
59
icu4c/source/layout/StateTableProcessor2.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __STATETABLEPROCESSOR2_H
|
||||
#define __STATETABLEPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "LookupTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class StateTableProcessor2 : public SubtableProcessor2
|
||||
{
|
||||
public:
|
||||
void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
virtual void beginStateTable() = 0;
|
||||
|
||||
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index) = 0;
|
||||
|
||||
virtual void endStateTable() = 0;
|
||||
|
||||
protected:
|
||||
StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
virtual ~StateTableProcessor2();
|
||||
|
||||
StateTableProcessor2();
|
||||
|
||||
le_int32 dir;
|
||||
le_uint16 format;
|
||||
le_uint32 nClasses;
|
||||
le_uint32 classTableOffset;
|
||||
le_uint32 stateArrayOffset;
|
||||
le_uint32 entryTableOffset;
|
||||
|
||||
const LookupTable *classTable;
|
||||
const EntryTableIndex2 *stateArray;
|
||||
const MorphStateTableHeader2 *stateTableHeader;
|
||||
|
||||
private:
|
||||
StateTableProcessor2(const StateTableProcessor2 &other); // forbid copying of this class
|
||||
StateTableProcessor2 &operator=(const StateTableProcessor2 &other); // forbid copying of this class
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -25,6 +25,14 @@ struct StateTableHeader
|
||||
ByteOffset entryTableOffset;
|
||||
};
|
||||
|
||||
struct StateTableHeader2
|
||||
{
|
||||
le_uint32 nClasses;
|
||||
le_uint32 classTableOffset;
|
||||
le_uint32 stateArrayOffset;
|
||||
le_uint32 entryTableOffset;
|
||||
};
|
||||
|
||||
enum ClassCodes
|
||||
{
|
||||
classCodeEOT = 0,
|
||||
@ -60,6 +68,14 @@ struct StateEntry
|
||||
le_int16 flags;
|
||||
};
|
||||
|
||||
typedef le_uint16 EntryTableIndex2;
|
||||
|
||||
struct StateEntry2 // same struct different interpretation
|
||||
{
|
||||
le_uint16 newStateIndex;
|
||||
le_uint16 flags;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
31
icu4c/source/layout/SubtableProcessor2.cpp
Normal file
31
icu4c/source/layout/SubtableProcessor2.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
SubtableProcessor2::SubtableProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
SubtableProcessor2::SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
{
|
||||
subtableHeader = morphSubtableHeader;
|
||||
|
||||
length = SWAPL(subtableHeader->length);
|
||||
coverage = SWAPL(subtableHeader->coverage);
|
||||
subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
|
||||
}
|
||||
|
||||
SubtableProcessor2::~SubtableProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
46
icu4c/source/layout/SubtableProcessor2.h
Normal file
46
icu4c/source/layout/SubtableProcessor2.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SUBTABLEPROCESSOR2_H
|
||||
#define __SUBTABLEPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SubtableProcessor2 : public UMemory {
|
||||
public:
|
||||
virtual void process(LEGlyphStorage &glyphStorage) = 0;
|
||||
virtual ~SubtableProcessor2();
|
||||
|
||||
protected:
|
||||
SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
SubtableProcessor2();
|
||||
|
||||
le_uint32 length;
|
||||
SubtableCoverage2 coverage;
|
||||
FeatureFlags subtableFeatures;
|
||||
|
||||
const MorphSubtableHeader2 *subtableHeader;
|
||||
|
||||
private:
|
||||
|
||||
SubtableProcessor2(const SubtableProcessor2 &other); // forbid copying of this class
|
||||
SubtableProcessor2 &operator=(const SubtableProcessor2 &other); // forbid copying of this class
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
55
icu4c/source/layout/TrimmedArrayProcessor2.cpp
Normal file
55
icu4c/source/layout/TrimmedArrayProcessor2.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
#include "TrimmedArrayProcessor2.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TrimmedArrayProcessor2)
|
||||
|
||||
TrimmedArrayProcessor2::TrimmedArrayProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
TrimmedArrayProcessor2::TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
|
||||
: NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
|
||||
{
|
||||
const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
|
||||
|
||||
trimmedArrayLookupTable = (const TrimmedArrayLookupTable *) &header->table;
|
||||
firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
|
||||
lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount);
|
||||
}
|
||||
|
||||
TrimmedArrayProcessor2::~TrimmedArrayProcessor2()
|
||||
{
|
||||
}
|
||||
|
||||
void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
LEGlyphID thisGlyph = glyphStorage[glyph];
|
||||
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph);
|
||||
|
||||
if ((ttGlyph > firstGlyph) && (ttGlyph < lastGlyph)) {
|
||||
TTGlyphID newGlyph = SWAPW(trimmedArrayLookupTable->valueArray[ttGlyph - firstGlyph]);
|
||||
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
60
icu4c/source/layout/TrimmedArrayProcessor2.h
Normal file
60
icu4c/source/layout/TrimmedArrayProcessor2.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TRIMMEDARRAYPROCESSOR2_H
|
||||
#define __TRIMMEDARRAYPROCESSOR2_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \internal
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "MorphTables.h"
|
||||
#include "SubtableProcessor2.h"
|
||||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc2.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class TrimmedArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
|
||||
|
||||
virtual ~TrimmedArrayProcessor2();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
private:
|
||||
TrimmedArrayProcessor2();
|
||||
|
||||
protected:
|
||||
TTGlyphID firstGlyph;
|
||||
TTGlyphID lastGlyph;
|
||||
const TrimmedArrayLookupTable *trimmedArrayLookupTable;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2008, International Business Machines
|
||||
* Copyright (C) 1999-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -413,7 +413,7 @@ static void checkFontVersion(PortableFontInstance *fontInstance, const char *tes
|
||||
const char *getSourceTestData() {
|
||||
const char *srcDataDir = NULL;
|
||||
#ifdef U_TOPSRCDIR
|
||||
srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
|
||||
srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
|
||||
#else
|
||||
srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
|
||||
FILE *f = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"rbbitst.txt", "r");
|
||||
@ -991,7 +991,7 @@ static const char *ctest_dataOutDir()
|
||||
*/
|
||||
#if defined (U_TOPBUILDDIR)
|
||||
{
|
||||
dataOutDir = U_TOPBUILDDIR "data"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
|
||||
dataOutDir = U_TOPBUILDDIR "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
|
||||
}
|
||||
#else
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user