mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-15 09:45:26 +00:00
ICU-2259 Add LEGlyphStorage, LEInsertionList.
X-SVN-Rev: 14933
This commit is contained in:
parent
515bf0c731
commit
9672384ada
59 changed files with 1718 additions and 1209 deletions
|
@ -1,14 +1,14 @@
|
|||
|
||||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
#include "ArabicLayoutEngine.h"
|
||||
|
@ -63,7 +63,7 @@ ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fon
|
|||
const GlyphSubstitutionTableHeader *gsubTable)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, gsubTable)
|
||||
{
|
||||
// fFeatureOrder = ArabicShaping::getFeatureOrder();
|
||||
/**/ fFeatureOrder = ArabicShaping::getFeatureOrder();
|
||||
}
|
||||
|
||||
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode)
|
||||
|
@ -81,7 +81,7 @@ ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
|
|||
// Output: characters, char indices, tags
|
||||
// Returns: output character count
|
||||
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&/*outChars*/, le_int32 *&/*charIndices*/, const LETag **&featureTags, LEErrorCode &success)
|
||||
LEUnicode *&/*outChars*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
|
@ -92,9 +92,10 @@ le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[]
|
|||
return 0;
|
||||
}
|
||||
|
||||
featureTags = LE_NEW_ARRAY(const LETag *, count);
|
||||
glyphStorage.adoptGlyphCount(count);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
if (featureTags == NULL) {
|
||||
if (LE_FAILURE(success)) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
@ -102,16 +103,12 @@ le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[]
|
|||
switch (fScriptCode) {
|
||||
case arabScriptCode:
|
||||
{
|
||||
GlyphShaper shaper(featureTags);
|
||||
|
||||
// NOTE: may not need seperate shaper if always use tags...
|
||||
// NOTE: shaper could allocate the feature tags...
|
||||
ArabicShaping::shape(chars, offset, count, max, rightToLeft, shaper);
|
||||
ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);
|
||||
break;
|
||||
}
|
||||
|
||||
case hebrScriptCode:
|
||||
HebrewShaping::shape(chars, offset, count, max, rightToLeft, featureTags);
|
||||
HebrewShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -119,45 +116,28 @@ le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[]
|
|||
}
|
||||
|
||||
void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success)
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || glyphs == NULL || positions == NULL || offset < 0 || count < 0) {
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGPOSTable != NULL) {
|
||||
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphs, glyphCount, positions, success);
|
||||
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
|
||||
} else if (fGDEFTable != NULL) {
|
||||
GDEFMarkFilter filter(fGDEFTable);
|
||||
|
||||
adjustMarkGlyphs(glyphs, glyphCount, FALSE, &filter, positions, success);
|
||||
adjustMarkGlyphs(glyphStorage, &filter, success);
|
||||
} else {
|
||||
GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) ArabicShaping::glyphDefinitionTable;
|
||||
GDEFMarkFilter filter(gdefTable);
|
||||
LEGlyphID *tempGlyphs;
|
||||
|
||||
// FIXME: we could avoid the memory allocation and copying here by
|
||||
// making a clone of the adjustMarkGlyphs method which took characters
|
||||
// directly...
|
||||
tempGlyphs = LE_NEW_ARRAY(LEGlyphID, count);
|
||||
|
||||
if (tempGlyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (le_int32 i = 0; i < count; i += 1) {
|
||||
tempGlyphs[i] = (LEGlyphID) chars[offset + i];
|
||||
}
|
||||
|
||||
adjustMarkGlyphs(tempGlyphs, count, reverse, &filter, positions, success);
|
||||
|
||||
LE_DELETE_ARRAY(tempGlyphs);
|
||||
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,21 +166,16 @@ UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
|
|||
}
|
||||
|
||||
// "glyphs", "indices" -> glyphs, indices
|
||||
le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphID tempGlyphs[], le_int32 tempCharIndices[], le_int32 tempGlyphCount,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tempGlyphs == NULL || tempCharIndices == NULL ||tempGlyphCount < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: we could avoid the memory allocation and copy if we
|
||||
// made a clone of mapCharsToGlyphs which took the fake glyphs
|
||||
// directly.
|
||||
le_int32 tempGlyphCount = tempGlyphStorage.getGlyphCount();
|
||||
LEUnicode *tempChars = LE_NEW_ARRAY(LEUnicode, tempGlyphCount);
|
||||
|
||||
if (tempChars == NULL) {
|
||||
|
@ -209,19 +184,19 @@ le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphID tempGl
|
|||
}
|
||||
|
||||
for (le_int32 i = 0; i < tempGlyphCount; i += 1) {
|
||||
tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphs[i]);
|
||||
tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphStorage[i]);
|
||||
}
|
||||
|
||||
charIndices = tempCharIndices;
|
||||
glyphStorage.adoptCharIndicesArray(tempGlyphStorage);
|
||||
|
||||
ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphs, charIndices, success);
|
||||
ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success);
|
||||
|
||||
LE_DELETE_ARRAY(tempChars);
|
||||
|
||||
return tempGlyphCount;
|
||||
}
|
||||
|
||||
void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
|
@ -232,68 +207,35 @@ void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[]
|
|||
return;
|
||||
}
|
||||
|
||||
le_int32 i, dir, out;
|
||||
|
||||
out = 0;
|
||||
dir = 1;
|
||||
le_int32 i, dir = 1, out = 0;
|
||||
|
||||
if (reverse) {
|
||||
out = count - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
glyphs = LE_NEW_ARRAY(LEGlyphID, count);
|
||||
glyphStorage.allocateGlyphArray(count, reverse, success);
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
charIndices = LE_NEW_ARRAY(le_int32, count);
|
||||
|
||||
if (charIndices == NULL) {
|
||||
LE_DELETE_ARRAY(glyphs);
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
glyphs[out] = (LEGlyphID) chars[offset + i];
|
||||
charIndices[out] = i;
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
glyphStorage[out] = (LEGlyphID) chars[offset + i];
|
||||
}
|
||||
}
|
||||
|
||||
void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success)
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || glyphs == NULL || positions == NULL || offset < 0 || count < 0 || glyphCount < 0) {
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
GDEFMarkFilter filter(fGDEFTable);
|
||||
|
||||
// FIXME: we could avoid the memory allocation and copying here by
|
||||
// making a clone of the adjustMarkGlyphs method which took characters
|
||||
// directly...
|
||||
LEGlyphID *tempGlyphs = LE_NEW_ARRAY(LEGlyphID, count);
|
||||
|
||||
if (tempGlyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (le_int32 i = 0; i < count; i += 1) {
|
||||
tempGlyphs[i] = (LEGlyphID) chars[offset + i];
|
||||
}
|
||||
|
||||
adjustMarkGlyphs(tempGlyphs, count, reverse, &filter, positions, success);
|
||||
|
||||
LE_DELETE_ARRAY(tempGlyphs);
|
||||
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
/*
|
||||
* @(#)ArabicLayoutEngine.h 1.3 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -112,7 +111,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, le_int32 *&charIndices, const LETag **&featureTags, LEErrorCode &success);
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method applies the GPOS table if it is present, otherwise it ensures that all vowel
|
||||
|
@ -131,7 +130,9 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success);
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
// static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -199,8 +200,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 glyphPostProcessing(LEGlyphID tempGlyphs[], le_int32 tempCharIndices[], le_int32 tempGlyphCount,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
virtual le_int32 glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method copies the input characters into the output glyph index array,
|
||||
|
@ -221,7 +221,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method ensures that all vowel and accent glyphs have a zero advance width by calling
|
||||
|
@ -239,7 +239,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success);
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* @(#)ArabicShaping.cpp 1.10 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "ArabicShaping.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -89,7 +89,7 @@ const LETag featureOrder[] =
|
|||
kernFeatureTag, markFeatureTag, mkmkFeatureTag, emptyTag
|
||||
};
|
||||
|
||||
const LETag GlyphShaper::tagArray[] =
|
||||
const LETag ArabicShaping::tagArray[] =
|
||||
{
|
||||
isolFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
|
||||
caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag,
|
||||
|
@ -104,15 +104,23 @@ const LETag GlyphShaper::tagArray[] =
|
|||
caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag
|
||||
};
|
||||
|
||||
#define TAGS_PER_GLYPH (sizeof GlyphShaper::tagArray / sizeof(LETag) / 4)
|
||||
#define TAGS_PER_GLYPH ((sizeof ArabicShaping::tagArray / sizeof ArabicShaping::tagArray[0]) / 4)
|
||||
|
||||
const LETag *ArabicShaping::getFeatureOrder()
|
||||
{
|
||||
return featureOrder;
|
||||
}
|
||||
|
||||
void ArabicShaping::adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
const LETag *glyphTags = (const LETag *) glyphStorage.getAuxData(outIndex, success);
|
||||
|
||||
glyphStorage.setAuxData(outIndex, (void *) &glyphTags[TAGS_PER_GLYPH * shapeOffset], success);
|
||||
}
|
||||
|
||||
void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
|
||||
le_bool rightToLeft, Shaper &shaper)
|
||||
le_bool rightToLeft, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
// iterate in logical order, store tags in visible order
|
||||
//
|
||||
|
@ -130,6 +138,7 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
|
|||
// shaper.shape(out, 1) (isolate to final)
|
||||
|
||||
ShapeType rightType = ST_NOSHAPE_NONE, leftType = ST_NOSHAPE_NONE;
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
le_int32 i;
|
||||
|
||||
for (i = offset - 1; i >= 0; i -= 1) {
|
||||
|
@ -164,7 +173,7 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
|
|||
LEUnicode c = chars[in];
|
||||
ShapeType t = getShapeType(c);
|
||||
|
||||
shaper.init(c, out, (t & (MASK_TRANSPARENT | MASK_NOSHAPE)) == 0);
|
||||
glyphStorage.setAuxData(out, (void *) tagArray, success);
|
||||
|
||||
if ((t & MASK_TRANSPARENT) != 0) {
|
||||
continue;
|
||||
|
@ -175,11 +184,11 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
|
|||
|
||||
if (rightCauses && curCauses) {
|
||||
if (rightShapes) {
|
||||
shaper.shape(erout, 2);
|
||||
adjustTags(erout, 2, glyphStorage);
|
||||
}
|
||||
|
||||
if (curShapes) {
|
||||
shaper.shape(out, 1);
|
||||
adjustTags(out, 1, glyphStorage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,83 +198,8 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
|
|||
}
|
||||
|
||||
if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) {
|
||||
shaper.shape(erout, 2);
|
||||
adjustTags(erout, 2, glyphStorage);
|
||||
}
|
||||
}
|
||||
|
||||
GlyphShaper::GlyphShaper(const LETag **outputTags)
|
||||
{
|
||||
charTags = outputTags;
|
||||
}
|
||||
|
||||
GlyphShaper::~GlyphShaper()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
void GlyphShaper::init(LEUnicode /*ch*/, le_int32 outIndex, le_bool /*isloate*/)
|
||||
{
|
||||
charTags[outIndex] = tagArray;
|
||||
}
|
||||
|
||||
void GlyphShaper::shape(le_int32 outIndex, le_int32 shapeOffset)
|
||||
{
|
||||
charTags[outIndex] = &charTags[outIndex][TAGS_PER_GLYPH * shapeOffset];
|
||||
}
|
||||
|
||||
CharShaper::CharShaper(LEUnicode *outputChars)
|
||||
{
|
||||
chars = outputChars;
|
||||
}
|
||||
|
||||
CharShaper::~CharShaper()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
void CharShaper::init(LEUnicode ch, le_int32 outIndex, le_bool isloate)
|
||||
{
|
||||
if (isloate) {
|
||||
chars[outIndex] = getToIsolateShape(ch);
|
||||
} else {
|
||||
chars[outIndex] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
void CharShaper::shape(le_int32 outIndex, le_int32 shapeOffset)
|
||||
{
|
||||
chars[outIndex] += (LEUnicode) shapeOffset;
|
||||
}
|
||||
|
||||
const LEUnicode CharShaper::isolateShapes[] =
|
||||
{
|
||||
0xfe80, 0xfe81, 0xfe83, 0xfe85, 0xfe87, 0xfe89, 0xfe8d, 0xfe8f, 0xfe93, 0xfe95,
|
||||
0xfe99, 0xfe9d, 0xfea1, 0xfea5, 0xfea9, 0xfeab, 0xfead, 0xfeaf, 0xfeb1, 0xfeb5,
|
||||
0xfeb9, 0xfebd, 0xfec1, 0xfec5, 0xfec9, 0xfecd, 0x063b, 0x063c, 0x063d, 0x063e,
|
||||
0x063f, 0x0640, 0xfed1, 0xfed5, 0xfed9, 0xfedd, 0xfee1, 0xfee5, 0xfee9, 0xfeed,
|
||||
0xfeef, 0xfef1, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 0x0650, 0x0651, 0x0652,
|
||||
0x0653, 0x0654, 0x0655, 0x0656, 0x0657, 0x0658, 0x0659, 0x065a, 0x065b, 0x065c,
|
||||
0x065d, 0x065e, 0x065f, 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666,
|
||||
0x0667, 0x0668, 0x0669, 0x066a, 0x066b, 0x066c, 0x066d, 0x066e, 0x066f, 0x0670,
|
||||
0xfb50, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0xfbdd, 0x0678, 0xfb66, 0xfb5e,
|
||||
0xfb52, 0x067c, 0x067d, 0xfb56, 0xfb62, 0xfb5a, 0x0681, 0x0682, 0xfb76, 0xfb72,
|
||||
0x0685, 0xfb7a, 0xfb7e, 0xfb88, 0x0689, 0x068a, 0x068b, 0xfb84, 0xfb82, 0xfb86,
|
||||
0x068f, 0x0690, 0xfb8c, 0x0692, 0x0693, 0x0694, 0x0695, 0x0696, 0x0697, 0xfb8a,
|
||||
0x0699, 0x069a, 0x069b, 0x069c, 0x069d, 0x069e, 0x069f, 0x06a0, 0x06a1, 0x06a2,
|
||||
0x06a3, 0xfb6a, 0x06a5, 0xfb6e, 0x06a7, 0x06a8, 0xfb8e, 0x06aa, 0x06ab, 0x06ac,
|
||||
0xfbd3, 0x06ae, 0xfb92, 0x06b0, 0xfb9a, 0x06b2, 0xfb96, 0x06b4, 0x06b5, 0x06b6,
|
||||
0x06b7, 0x06b8, 0x06b9, 0xfb9e, 0xfba0, 0x06bc, 0x06bd, 0xfbaa, 0x06bf, 0xfba4,
|
||||
0xfba6, 0x06c2, 0x06c3, 0x06c4, 0xfbe0, 0xfbd9, 0xfbd7, 0xfbdb, 0xfbe2, 0x06ca,
|
||||
0xfbde, 0xfbfc, 0x06cd, 0x06ce, 0x06cf, 0xfbe4, 0x06d1, 0xfbae, 0xfbb0
|
||||
};
|
||||
|
||||
LEUnicode CharShaper::getToIsolateShape(LEUnicode ch)
|
||||
{
|
||||
if (ch < 0x0621 || ch > 0x06d3) {
|
||||
return ch;
|
||||
}
|
||||
|
||||
return isolateShapes[ch - 0x0621];
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
* @(#)ArabicShaping.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
*
|
||||
|
@ -18,12 +17,7 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class Shaper /* not : public UObject because this is an interface/mixin class */ {
|
||||
public:
|
||||
virtual inline ~Shaper() {};
|
||||
virtual void init(LEUnicode ch, le_int32 outIndex, le_bool isloate) = 0;
|
||||
virtual void shape(le_int32 outIndex, le_int32 shapeOffset) = 0;
|
||||
};
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ArabicShaping /* not : public UObject because all methods are static */ {
|
||||
public:
|
||||
|
@ -51,7 +45,7 @@ public:
|
|||
typedef le_int32 ShapeType;
|
||||
|
||||
static void shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
|
||||
le_bool rightToLeft, Shaper &shaper);
|
||||
le_bool rightToLeft, LEGlyphStorage &glyphStorage);
|
||||
|
||||
static const LETag *getFeatureOrder();
|
||||
|
||||
|
@ -63,47 +57,13 @@ private:
|
|||
// forbid instantiation
|
||||
ArabicShaping();
|
||||
|
||||
static ShapeType getShapeType(LEUnicode c);
|
||||
|
||||
static const ShapeType shapeTypes[];
|
||||
};
|
||||
|
||||
class GlyphShaper : public UMemory, public Shaper
|
||||
{
|
||||
public:
|
||||
virtual void init(LEUnicode ch, le_int32 outIndex, le_bool isolate);
|
||||
virtual void shape(le_int32 outIndex, le_int32 shapeOffset);
|
||||
|
||||
GlyphShaper(const LETag **outputTags);
|
||||
~GlyphShaper();
|
||||
|
||||
private:
|
||||
const LETag **charTags;
|
||||
|
||||
static const LETag tagArray[];
|
||||
|
||||
GlyphShaper(const GlyphShaper &other); // forbid copying of this class
|
||||
GlyphShaper &operator=(const GlyphShaper &other); // forbid copying of this class
|
||||
};
|
||||
static ShapeType getShapeType(LEUnicode c);
|
||||
|
||||
class CharShaper : public UMemory, public Shaper
|
||||
{
|
||||
public:
|
||||
virtual void init(LEUnicode ch, le_int32 outIndex, le_bool isolate);
|
||||
virtual void shape(le_int32 outIndex, le_int32 shapeOffset);
|
||||
static const ShapeType shapeTypes[];
|
||||
|
||||
CharShaper(LEUnicode *outputChars);
|
||||
~CharShaper();
|
||||
|
||||
private:
|
||||
LEUnicode *chars;
|
||||
|
||||
static const LEUnicode isolateShapes[];
|
||||
|
||||
static LEUnicode getToIsolateShape(LEUnicode ch);
|
||||
|
||||
CharShaper(const CharShaper &other); // forbid copying of this class
|
||||
CharShaper &operator=(const CharShaper &other); // forbid copying of this class
|
||||
static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)ContextualGlyphSubstProc.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -12,6 +11,7 @@
|
|||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "ContextualGlyphSubstProc.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -36,7 +36,7 @@ void ContextualGlyphSubstitutionProcessor::beginStateTable()
|
|||
markGlyph = 0;
|
||||
}
|
||||
|
||||
ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphID *glyphs, le_int32 * /*charIndices*/, le_int32 &currGlyph, le_int32 /*glyphCount*/, EntryTableIndex index)
|
||||
ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
|
||||
{
|
||||
const ContextualGlyphSubstitutionStateEntry *entry = &entryTable[index];
|
||||
ByteOffset newState = SWAPW(entry->newStateOffset);
|
||||
|
@ -46,16 +46,18 @@ ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphID *gl
|
|||
|
||||
if (markOffset != 0) {
|
||||
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + markOffset * 2);
|
||||
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(glyphs[markGlyph])]);
|
||||
LEGlyphID mGlyph = glyphStorage[markGlyph];
|
||||
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(mGlyph)]);
|
||||
|
||||
glyphs[markGlyph] = LE_SET_GLYPH(glyphs[markGlyph], newGlyph);
|
||||
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (currOffset != 0) {
|
||||
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + currOffset * 2);
|
||||
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(glyphs[currGlyph])]);
|
||||
LEGlyphID thisGlyph = glyphStorage[currGlyph];
|
||||
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(thisGlyph)]);
|
||||
|
||||
glyphs[currGlyph] = LE_SET_GLYPH(glyphs[currGlyph], newGlyph);
|
||||
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
|
||||
if (flags & cgsSetMark) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)ContextualGlyphSubstProc.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,13 +20,14 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ContextualGlyphSubstitutionProcessor : public StateTableProcessor
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual ByteOffset processStateEntry(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 &currGlyph,
|
||||
le_int32 glyphCount, EntryTableIndex index);
|
||||
virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
|
||||
/*
|
||||
* @(#)GXLayoutEngine.cpp 1.5 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LayoutEngine.h"
|
||||
#include "GXLayoutEngine.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "MorphTables.h"
|
||||
|
||||
|
@ -28,7 +28,7 @@ GXLayoutEngine::~GXLayoutEngine()
|
|||
}
|
||||
|
||||
// apply 'mort' table
|
||||
le_int32 GXLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
le_int32 GXLayoutEngine::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;
|
||||
|
@ -39,13 +39,13 @@ le_int32 GXLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset,
|
|||
return 0;
|
||||
}
|
||||
|
||||
mapCharsToGlyphs(chars, offset, count, FALSE, rightToLeft, glyphs, charIndices, success);
|
||||
mapCharsToGlyphs(chars, offset, count, FALSE, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fMorphTable->process(glyphs, charIndices, count);
|
||||
fMorphTable->process(glyphStorage);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
/*
|
||||
* @(#)GXLayoutEngine.h 1.4 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -10,14 +9,15 @@
|
|||
#define __GXLAYOUTENGINE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphFilter.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
|
||||
|
@ -102,7 +102,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method adjusts the glyph positions using the font's
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -10,105 +9,40 @@
|
|||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositionAdjustments.h"
|
||||
#include "GlyphIterator.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "Lookups.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
const char InsertionList::fgClassID = 0;
|
||||
|
||||
InsertionList::InsertionList(le_bool rightToLeft)
|
||||
: head(NULL), tail(NULL), growAmount(0), append(rightToLeft)
|
||||
{
|
||||
tail = (InsertionRecord *) &head;
|
||||
}
|
||||
|
||||
InsertionList::~InsertionList()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void InsertionList::reset()
|
||||
{
|
||||
while (head != NULL) {
|
||||
InsertionRecord *record = head;
|
||||
|
||||
head = head->next;
|
||||
LE_DELETE_ARRAY(record);
|
||||
}
|
||||
|
||||
tail = (InsertionRecord *) &head;
|
||||
growAmount = 0;
|
||||
}
|
||||
|
||||
le_int32 InsertionList::getGrowAmount()
|
||||
{
|
||||
return growAmount;
|
||||
}
|
||||
|
||||
LEGlyphID *InsertionList::insert(le_int32 position, le_int32 count)
|
||||
{
|
||||
InsertionRecord *insertion = (InsertionRecord *) LE_NEW_ARRAY(char, sizeof(InsertionRecord) + (count - ANY_NUMBER) * sizeof (LEGlyphID));
|
||||
|
||||
insertion->position = position;
|
||||
insertion->count = count;
|
||||
|
||||
growAmount += count - 1;
|
||||
|
||||
if (append) {
|
||||
// insert on end of list...
|
||||
insertion->next = NULL;
|
||||
tail->next = insertion;
|
||||
tail = insertion;
|
||||
} else {
|
||||
// insert on front of list...
|
||||
insertion->next = head;
|
||||
head = insertion;
|
||||
}
|
||||
|
||||
return insertion->glyphs;
|
||||
}
|
||||
|
||||
le_bool InsertionList::applyInsertions(InsertionCallback *callback)
|
||||
{
|
||||
for (InsertionRecord *rec = head; rec != NULL; rec = rec->next) {
|
||||
if (callback->applyInsertion(rec->position, rec->count, rec->glyphs)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GlyphIterator::GlyphIterator(LEGlyphID *&theGlyphs, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_int32 *&theCharIndices, le_int32 theGlyphCount,
|
||||
le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, const LETag **&theGlyphTags,
|
||||
GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag,
|
||||
const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
|
||||
: direction(1), position(-1), nextLimit(theGlyphCount), prevLimit(-1),
|
||||
: direction(1), position(-1), nextLimit(-1), prevLimit(-1),
|
||||
cursiveFirstPosition(-1), cursiveLastPosition(-1), cursiveBaselineAdjustment(0),
|
||||
glyphsRef(&theGlyphs), glyphs(theGlyphs), glyphPositionAdjustments(theGlyphPositionAdjustments),
|
||||
charIndicesRef(&theCharIndices), charIndices(theCharIndices), glyphCount(theGlyphCount), insertionList(NULL), ownInsertionList(TRUE), srcIndex(-1), destIndex(-1),
|
||||
lookupFlags(theLookupFlags), featureTag(theFeatureTag), glyphTagsRef(&theGlyphTags), glyphTags(theGlyphTags),
|
||||
glyphClassDefinitionTable(NULL),
|
||||
markAttachClassDefinitionTable(NULL)
|
||||
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
|
||||
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureTag(theFeatureTag),
|
||||
glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
|
||||
|
||||
{
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
if (theGlyphDefinitionTableHeader != NULL) {
|
||||
glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
|
||||
markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
|
||||
}
|
||||
|
||||
nextLimit = glyphCount;
|
||||
|
||||
if (rightToLeft) {
|
||||
direction = -1;
|
||||
position = theGlyphCount;
|
||||
position = glyphCount;
|
||||
nextLimit = -1;
|
||||
prevLimit = theGlyphCount;
|
||||
prevLimit = glyphCount;
|
||||
}
|
||||
|
||||
insertionList = new InsertionList(rightToLeft);
|
||||
}
|
||||
|
||||
GlyphIterator::GlyphIterator(GlyphIterator &that)
|
||||
: InsertionCallback()
|
||||
: glyphStorage(that.glyphStorage)
|
||||
{
|
||||
direction = that.direction;
|
||||
position = that.position;
|
||||
|
@ -118,25 +52,17 @@ GlyphIterator::GlyphIterator(GlyphIterator &that)
|
|||
cursiveFirstPosition = that.cursiveFirstPosition;
|
||||
cursiveLastPosition = that.cursiveLastPosition;
|
||||
|
||||
glyphsRef = that.glyphsRef;
|
||||
glyphs = that.glyphs;
|
||||
glyphPositionAdjustments = that.glyphPositionAdjustments;
|
||||
charIndicesRef = that.charIndicesRef;
|
||||
charIndices = that.charIndices;
|
||||
glyphCount = that.glyphCount;
|
||||
insertionList = that.insertionList;
|
||||
ownInsertionList = FALSE;
|
||||
srcIndex = that.srcIndex;
|
||||
destIndex = that.destIndex;
|
||||
lookupFlags = that.lookupFlags;
|
||||
featureTag = that.featureTag;
|
||||
glyphTagsRef = that.glyphTagsRef;
|
||||
glyphTags = that.glyphTags;
|
||||
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
|
||||
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
|
||||
}
|
||||
|
||||
GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag)
|
||||
: glyphStorage(that.glyphStorage)
|
||||
{
|
||||
direction = that.direction;
|
||||
position = that.position;
|
||||
|
@ -146,25 +72,17 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag)
|
|||
cursiveFirstPosition = that.cursiveFirstPosition;
|
||||
cursiveLastPosition = that.cursiveLastPosition;
|
||||
|
||||
glyphsRef = that.glyphsRef;
|
||||
glyphs = that.glyphs;
|
||||
glyphPositionAdjustments = that.glyphPositionAdjustments;
|
||||
charIndicesRef = that.charIndicesRef;
|
||||
charIndices = that.charIndices;
|
||||
glyphCount = that.glyphCount;
|
||||
insertionList = that.insertionList;
|
||||
ownInsertionList = FALSE;
|
||||
srcIndex = that.srcIndex;
|
||||
destIndex = that.destIndex;
|
||||
lookupFlags = that.lookupFlags;
|
||||
featureTag = newFeatureTag;
|
||||
glyphTagsRef = that.glyphTagsRef;
|
||||
glyphTags = that.glyphTags;
|
||||
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
|
||||
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
|
||||
}
|
||||
|
||||
GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
|
||||
: glyphStorage(that.glyphStorage)
|
||||
{
|
||||
direction = that.direction;
|
||||
position = that.position;
|
||||
|
@ -175,33 +93,25 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
|
|||
cursiveFirstPosition = that.cursiveFirstPosition;
|
||||
cursiveLastPosition = that.cursiveLastPosition;
|
||||
|
||||
glyphsRef = that.glyphsRef;
|
||||
glyphs = that.glyphs;
|
||||
glyphPositionAdjustments = that.glyphPositionAdjustments;
|
||||
charIndicesRef = that.charIndicesRef;
|
||||
charIndices = that.charIndices;
|
||||
glyphCount = that.glyphCount;
|
||||
insertionList = that.insertionList;
|
||||
ownInsertionList = FALSE;
|
||||
srcIndex = that.srcIndex;
|
||||
destIndex = that.destIndex;
|
||||
lookupFlags = newLookupFlags;
|
||||
featureTag = that.featureTag;
|
||||
glyphTagsRef = that.glyphTagsRef;
|
||||
glyphTags = that.glyphTags;
|
||||
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
|
||||
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
|
||||
}
|
||||
|
||||
static LEGlyphStorage dummyGlyphStorage;
|
||||
|
||||
GlyphIterator::GlyphIterator()
|
||||
: glyphStorage(dummyGlyphStorage)
|
||||
{
|
||||
};
|
||||
|
||||
GlyphIterator::~GlyphIterator()
|
||||
{
|
||||
if (ownInsertionList) {
|
||||
delete insertionList;
|
||||
}
|
||||
// nothing to do, right?
|
||||
}
|
||||
|
||||
void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag)
|
||||
|
@ -213,36 +123,12 @@ void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag)
|
|||
|
||||
LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count)
|
||||
{
|
||||
return insertionList->insert(position, count);
|
||||
return glyphStorage.insertGlyphs(position, count);
|
||||
}
|
||||
|
||||
le_int32 GlyphIterator::applyInsertions()
|
||||
{
|
||||
le_int32 growAmount = insertionList->getGrowAmount();
|
||||
|
||||
if (growAmount == 0) {
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
le_int32 newGlyphCount = glyphCount + growAmount;
|
||||
|
||||
*glyphsRef = glyphs = (LEGlyphID *) LE_GROW_ARRAY(glyphs, newGlyphCount);
|
||||
*glyphTagsRef = glyphTags = (const LETag **) LE_GROW_ARRAY(glyphTags, newGlyphCount);
|
||||
*charIndicesRef = charIndices = (le_int32 *) LE_GROW_ARRAY(charIndices, newGlyphCount);
|
||||
|
||||
srcIndex = glyphCount - 1;
|
||||
destIndex = newGlyphCount - 1;
|
||||
|
||||
// If the current position is at the end of the array
|
||||
// update it to point to the end of the new array. The
|
||||
// insertion callback will handle all other cases.
|
||||
if (position == glyphCount) {
|
||||
position = newGlyphCount;
|
||||
}
|
||||
|
||||
insertionList->applyInsertions(this);
|
||||
|
||||
insertionList->reset();
|
||||
le_int32 newGlyphCount = glyphStorage.applyInsertions();
|
||||
|
||||
if (direction < 0) {
|
||||
prevLimit = newGlyphCount;
|
||||
|
@ -250,40 +136,7 @@ le_int32 GlyphIterator::applyInsertions()
|
|||
nextLimit = newGlyphCount;
|
||||
}
|
||||
|
||||
return glyphCount = newGlyphCount;
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
|
||||
{
|
||||
// if the current position is within the block we're shifting
|
||||
// it needs to be updated to the current glyph's
|
||||
// new location.
|
||||
if (position >= atPosition && position <= srcIndex) {
|
||||
position += destIndex - srcIndex;
|
||||
}
|
||||
|
||||
while (srcIndex > atPosition) {
|
||||
glyphs[destIndex] = glyphs[srcIndex];
|
||||
glyphTags[destIndex] = glyphTags[srcIndex];
|
||||
charIndices[destIndex] = charIndices[srcIndex];
|
||||
|
||||
destIndex -= 1;
|
||||
srcIndex -= 1;
|
||||
}
|
||||
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
glyphs[destIndex] = newGlyphs[i];
|
||||
glyphTags[destIndex] = glyphTags[atPosition];
|
||||
charIndices[destIndex] = charIndices[atPosition];
|
||||
|
||||
destIndex -= 1;
|
||||
}
|
||||
|
||||
// the source glyph we're pointing at
|
||||
// just got replaced by the insertion
|
||||
srcIndex -= 1;
|
||||
|
||||
return FALSE;
|
||||
return newGlyphCount;
|
||||
}
|
||||
|
||||
le_int32 GlyphIterator::getCurrStreamPosition() const
|
||||
|
@ -318,6 +171,8 @@ le_bool GlyphIterator::hasCursiveLastExitPoint() const
|
|||
|
||||
LEGlyphID GlyphIterator::getCurrGlyphID() const
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return 0xFFFF;
|
||||
|
@ -328,11 +183,13 @@ LEGlyphID GlyphIterator::getCurrGlyphID() const
|
|||
}
|
||||
}
|
||||
|
||||
return glyphs[position];
|
||||
return glyphStorage[position];
|
||||
}
|
||||
|
||||
LEGlyphID GlyphIterator::getCursiveLastGlyphID() const
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
if (direction < 0) {
|
||||
if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit) {
|
||||
return 0xFFFF;
|
||||
|
@ -343,7 +200,7 @@ LEGlyphID GlyphIterator::getCursiveLastGlyphID() const
|
|||
}
|
||||
}
|
||||
|
||||
return glyphs[cursiveLastPosition];
|
||||
return glyphStorage[cursiveLastPosition];
|
||||
}
|
||||
|
||||
void GlyphIterator::getCursiveLastExitPoint(LEPoint &exitPoint) const
|
||||
|
@ -394,7 +251,9 @@ void GlyphIterator::getCursiveLastPositionAdjustment(GlyphPositionAdjustment &ad
|
|||
|
||||
void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID)
|
||||
{
|
||||
glyphs[position] = LE_SET_GLYPH(glyphs[position], glyphID);
|
||||
LEGlyphID glyph = glyphStorage[position];
|
||||
|
||||
glyphStorage[position] = LE_SET_GLYPH(glyph, glyphID);
|
||||
}
|
||||
|
||||
void GlyphIterator::setCurrStreamPosition(le_int32 newPosition)
|
||||
|
@ -557,7 +416,7 @@ void GlyphIterator::adjustCursiveLastGlyphPositionAdjustment(float xPlacementAdj
|
|||
|
||||
le_bool GlyphIterator::filterGlyph(le_uint32 index) const
|
||||
{
|
||||
LEGlyphID glyphID = glyphs[index];
|
||||
LEGlyphID glyphID = glyphStorage[index];
|
||||
le_int32 glyphClass = gcdNoGlyphClass;
|
||||
|
||||
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
|
||||
|
@ -611,13 +470,12 @@ le_bool GlyphIterator::hasFeatureTag() const
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (glyphTags != NULL) {
|
||||
const LETag *tagList = glyphTags[position];
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
const LETag *tagList = (const LETag *) glyphStorage.getAuxData(position, success);
|
||||
|
||||
for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) {
|
||||
if (tagList[tag] == featureTag) {
|
||||
return TRUE;
|
||||
}
|
||||
for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) {
|
||||
if (tagList[tag] == featureTag) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,7 +545,7 @@ le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
|
|||
le_int32 posn;
|
||||
|
||||
for (posn = position; posn != markPosition; posn += direction) {
|
||||
if (glyphs[posn] == 0xFFFE) {
|
||||
if (glyphStorage[posn] == 0xFFFE) {
|
||||
component += 1;
|
||||
}
|
||||
}
|
||||
|
@ -704,7 +562,7 @@ le_bool GlyphIterator::findMark2Glyph()
|
|||
|
||||
do {
|
||||
newPosition -= direction;
|
||||
} while (newPosition != prevLimit && glyphs[newPosition] != 0xFFFE && filterGlyph(newPosition));
|
||||
} while (newPosition != prevLimit && glyphStorage[newPosition] != 0xFFFE && filterGlyph(newPosition));
|
||||
|
||||
position = newPosition;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -20,66 +19,11 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct InsertionRecord
|
||||
{
|
||||
InsertionRecord *next;
|
||||
le_int32 position;
|
||||
le_int32 count;
|
||||
LEGlyphID glyphs[ANY_NUMBER];
|
||||
};
|
||||
class LEGlyphStorage;
|
||||
|
||||
class InsertionCallback
|
||||
{
|
||||
class GlyphIterator : public UMemory {
|
||||
public:
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0;
|
||||
};
|
||||
|
||||
class InsertionList : public UObject
|
||||
{
|
||||
public:
|
||||
InsertionList(le_bool rightToLeft);
|
||||
~InsertionList();
|
||||
|
||||
LEGlyphID *insert(le_int32 position, le_int32 count);
|
||||
le_int32 getGrowAmount();
|
||||
|
||||
le_bool applyInsertions(InsertionCallback *callback);
|
||||
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The address of this static class variable serves as this class's ID
|
||||
* for ICU "poor man's RTTI".
|
||||
*/
|
||||
static const char fgClassID;
|
||||
|
||||
InsertionRecord *head;
|
||||
InsertionRecord *tail;
|
||||
|
||||
le_int32 growAmount;
|
||||
le_bool append;
|
||||
};
|
||||
|
||||
class GlyphIterator : public UMemory, protected InsertionCallback {
|
||||
public:
|
||||
GlyphIterator(LEGlyphID *&theGlyphs, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_int32 *&theCharIndices, le_int32 theGlyphCount,
|
||||
le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, const LETag **&theGlyphTags,
|
||||
GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag,
|
||||
const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader);
|
||||
|
||||
GlyphIterator(GlyphIterator &that);
|
||||
|
@ -132,9 +76,6 @@ public:
|
|||
LEGlyphID *insertGlyphs(le_int32 count);
|
||||
le_int32 applyInsertions();
|
||||
|
||||
protected:
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]);
|
||||
|
||||
private:
|
||||
GlyphIterator();
|
||||
le_bool filterGlyph(le_uint32 index) const;
|
||||
|
@ -150,20 +91,12 @@ private:
|
|||
le_int32 cursiveLastPosition;
|
||||
float cursiveBaselineAdjustment;
|
||||
LEPoint cursiveLastExitPoint;
|
||||
LEGlyphID **glyphsRef;
|
||||
LEGlyphID *glyphs;
|
||||
LEGlyphStorage &glyphStorage;
|
||||
GlyphPositionAdjustment *glyphPositionAdjustments;
|
||||
le_int32 **charIndicesRef;
|
||||
le_int32 *charIndices;
|
||||
le_int32 glyphCount;
|
||||
InsertionList *insertionList;
|
||||
le_bool ownInsertionList;
|
||||
le_int32 srcIndex;
|
||||
le_int32 destIndex;
|
||||
le_uint16 lookupFlags;
|
||||
LETag featureTag;
|
||||
const LETag ***glyphTagsRef;
|
||||
const LETag **glyphTags;
|
||||
const GlyphClassDefinitionTable *glyphClassDefinitionTable;
|
||||
const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)GlyphPositioningTables.cpp 1.7 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -13,20 +12,18 @@
|
|||
#include "GlyphPositionAdjustments.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
#include "GlyphPosnLookupProc.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void GlyphPositioningTableHeader::process(LEGlyphID *glyphs, GlyphPositionAdjustment *glyphPositionAdjustments,
|
||||
const LETag **glyphTags, le_int32 glyphCount, le_bool rightToLeft,
|
||||
void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustment *glyphPositionAdjustments, le_bool rightToLeft,
|
||||
LETag scriptTag, LETag languageTag,
|
||||
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
|
||||
const LEFontInstance *fontInstance, const LETag *featureOrder) const
|
||||
{
|
||||
GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureOrder);
|
||||
le_int32 *charIndices = NULL;
|
||||
|
||||
processor.process(glyphs, glyphPositionAdjustments, glyphTags, charIndices, glyphCount, rightToLeft,
|
||||
glyphDefinitionTableHeader, fontInstance);
|
||||
processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)GlyphPositioningTables.h 1.7 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -23,11 +22,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
struct GlyphPositioningTableHeader : public GlyphLookupTableHeader
|
||||
{
|
||||
void process(LEGlyphID *glyphs, GlyphPositionAdjustment *glyphPositionAdjustments,
|
||||
const LETag **glyphTags, le_int32 glyphCount,
|
||||
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
|
||||
void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustment *glyphPositionAdjustments,
|
||||
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
|
||||
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
|
||||
const LEFontInstance *fontInstance, const LETag *featureOrder) const;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)GlyphSubstitutionTables.cpp 1.9 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -14,18 +13,18 @@
|
|||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphSubstLookupProc.h"
|
||||
#include "ScriptAndLanguage.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphID *&glyphs, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
|
||||
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
|
||||
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag,
|
||||
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
|
||||
const LEGlyphFilter *filter, const LETag *featureOrder) const
|
||||
{
|
||||
GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureOrder);
|
||||
|
||||
return processor.process(glyphs, NULL, glyphTags, charIndices, glyphCount, rightToLeft, glyphDefinitionTableHeader, NULL);
|
||||
return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)GlyphSubstitutionTables.h 1.9 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -23,10 +22,11 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
|
||||
{
|
||||
le_int32 process(LEGlyphID *&glyphs, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
|
||||
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
|
||||
le_int32 process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag,
|
||||
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
|
||||
const LEGlyphFilter *filter = NULL, const LETag *featureOrder = NULL) const;
|
||||
};
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "HebrewShaping.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -20,10 +21,11 @@ const LETag hebrewTags[] =
|
|||
};
|
||||
|
||||
void HebrewShaping::shape(const LEUnicode * /*chars*/, le_int32 /*offset*/, le_int32 charCount, le_int32 /*charMax*/,
|
||||
le_bool rightToLeft, const LETag **tags)
|
||||
le_bool rightToLeft, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
|
||||
le_int32 count, out = 0, dir = 1;
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
if (rightToLeft) {
|
||||
out = charCount - 1;
|
||||
|
@ -31,7 +33,7 @@ void HebrewShaping::shape(const LEUnicode * /*chars*/, le_int32 /*offset*/, le_i
|
|||
}
|
||||
|
||||
for (count = 0; count < charCount; count += 1, out += dir) {
|
||||
tags[out] = hebrewTags;
|
||||
glyphStorage.setAuxData(out, (void *) hebrewTags, success);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -18,10 +18,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class HebrewShaping /* not : public UObject because all methods are static */ {
|
||||
public:
|
||||
static void shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
|
||||
le_bool rightToLeft, const LETag **tags);
|
||||
le_bool rightToLeft, LEGlyphStorage &glyphStorage);
|
||||
|
||||
static const le_uint8 glyphSubstitutionTable[];
|
||||
static const le_uint8 glyphDefinitionTable[];
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
/*
|
||||
* @(#)IndicLayoutEngine.cpp 1.3 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -17,6 +16,7 @@
|
|||
#include "GlyphPositioningTables.h"
|
||||
|
||||
#include "GDEFMarkFilter.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "IndicReordering.h"
|
||||
|
||||
|
@ -45,7 +45,7 @@ IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
|
|||
// Input: characters, tags
|
||||
// Output: glyphs, char indices
|
||||
le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
const LETag **&featureTags, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
|
@ -56,13 +56,13 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
|
|||
return 0;
|
||||
}
|
||||
|
||||
le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, featureTags, glyphs, charIndices, success);
|
||||
le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
IndicReordering::adjustMPres(fMPreFixups, glyphs, charIndices);
|
||||
IndicReordering::adjustMPres(fMPreFixups, glyphStorage);
|
||||
|
||||
return retCount;
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
|
|||
// Input: characters
|
||||
// Output: characters, char indices, tags
|
||||
// Returns: output character count
|
||||
le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/,
|
||||
LEUnicode *&outChars, le_int32 *&charIndices, const LETag **&featureTags, LEErrorCode &success)
|
||||
le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
|
@ -91,25 +91,20 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
|
|||
return 0;
|
||||
}
|
||||
|
||||
charIndices = LE_NEW_ARRAY(le_int32, worstCase);
|
||||
if (charIndices == NULL) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
featureTags = LE_NEW_ARRAY(const LETag *, worstCase);
|
||||
|
||||
if (featureTags == NULL) {
|
||||
LE_DELETE_ARRAY(charIndices);
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: assumes this allocates featureTags...
|
||||
// (probably better than doing the worst case stuff here...)
|
||||
return IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, charIndices, featureTags, &fMPreFixups);
|
||||
le_int32 outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups);
|
||||
|
||||
glyphStorage.adoptGlyphCount(outCharCount);
|
||||
return outCharCount;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
/*
|
||||
* @(#)IndicLayoutEngine.h 1.4 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -24,6 +23,7 @@
|
|||
U_NAMESPACE_BEGIN
|
||||
|
||||
class MPreFixups;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements OpenType layout for Indic OpenType fonts, as
|
||||
|
@ -121,7 +121,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, le_int32 *&charIndices, const LETag **&featureTags, LEErrorCode &success);
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method does character to glyph mapping, applies the GSUB table and applies
|
||||
|
@ -153,7 +153,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
const LETag **&featureTags, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)IndicRearrangementProcessor.cpp 1.7 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -12,6 +11,7 @@
|
|||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "IndicRearrangementProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -35,8 +35,7 @@ void IndicRearrangementProcessor::beginStateTable()
|
|||
lastGlyph = 0;
|
||||
}
|
||||
|
||||
ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 &currGlyph,
|
||||
le_int32 /*glyphCount*/, EntryTableIndex index)
|
||||
ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
|
||||
{
|
||||
const IndicRearrangementStateEntry *entry = &entryTable[index];
|
||||
ByteOffset newState = SWAPW(entry->newStateOffset);
|
||||
|
@ -50,7 +49,7 @@ ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphID *glyphs, le_
|
|||
lastGlyph = currGlyph;
|
||||
}
|
||||
|
||||
doRearrangementAction(glyphs, charIndices, (IndicRearrangementVerb) (flags & irfVerbMask));
|
||||
doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
|
||||
|
||||
if (!(flags & irfDontAdvance)) {
|
||||
// XXX: Should handle reverse too...
|
||||
|
@ -64,10 +63,11 @@ void IndicRearrangementProcessor::endStateTable()
|
|||
{
|
||||
}
|
||||
|
||||
void IndicRearrangementProcessor::doRearrangementAction(LEGlyphID *glyphs, le_int32 *charIndices, IndicRearrangementVerb verb) const
|
||||
void IndicRearrangementProcessor::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
|
||||
{
|
||||
LEGlyphID a, b, c, d;
|
||||
le_int32 ia, ib, ic, id, x;
|
||||
le_int32 ia, ib, ic, id, ix, x;
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
|
@ -75,300 +75,319 @@ void IndicRearrangementProcessor::doRearrangementAction(LEGlyphID *glyphs, le_in
|
|||
break;
|
||||
|
||||
case irvxA:
|
||||
a = glyphs[firstGlyph];
|
||||
ia = charIndices[firstGlyph];
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
x = firstGlyph + 1;
|
||||
|
||||
while (x <= lastGlyph) {
|
||||
glyphs[x - 1] = glyphs[x];
|
||||
charIndices[x - 1] = charIndices[x];
|
||||
glyphStorage[x - 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 1, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphs[lastGlyph] = a;
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDx:
|
||||
d = glyphs[lastGlyph];
|
||||
id = charIndices[lastGlyph];
|
||||
d = glyphStorage[lastGlyph];
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 1;
|
||||
|
||||
while (x >= firstGlyph) {
|
||||
glyphs[x + 1] = glyphs[x];
|
||||
charIndices[x + 1] = charIndices[x];
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphs[firstGlyph] = d;
|
||||
charIndices[firstGlyph] = id;
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
break;
|
||||
|
||||
case irvDxA:
|
||||
a = glyphs[firstGlyph];
|
||||
ia = charIndices[firstGlyph];
|
||||
a = glyphStorage[firstGlyph];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
glyphs[firstGlyph] = glyphs[lastGlyph];
|
||||
glyphs[lastGlyph] = a;
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
charIndices[firstGlyph] = charIndices[lastGlyph];
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvxAB:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= lastGlyph) {
|
||||
glyphs[x - 2] = glyphs[x];
|
||||
charIndices[x - 2] = charIndices[x];
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphs[lastGlyph - 1] = a;
|
||||
glyphs[lastGlyph] = b;
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
charIndices[lastGlyph - 1] = ia;
|
||||
charIndices[lastGlyph] = ib;
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvxBA:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
x = firstGlyph + 2;
|
||||
|
||||
while (x <= lastGlyph) {
|
||||
glyphs[x - 2] = glyphs[x];
|
||||
charIndices[x - 2] = charIndices[x];
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphs[lastGlyph - 1] = b;
|
||||
glyphs[lastGlyph] = a;
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
charIndices[lastGlyph - 1] = ib;
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDx:
|
||||
c = glyphs[lastGlyph - 1];
|
||||
d = glyphs[lastGlyph];
|
||||
ic = charIndices[lastGlyph - 1];
|
||||
id = charIndices[lastGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= firstGlyph) {
|
||||
glyphs[x + 2] = glyphs[x];
|
||||
charIndices[x + 2] = charIndices[x];
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphs[firstGlyph] = c;
|
||||
glyphs[firstGlyph + 1] = d;
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
|
||||
charIndices[firstGlyph] = ic;
|
||||
charIndices[firstGlyph + 1] = id;
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
break;
|
||||
|
||||
case irvDCx:
|
||||
c = glyphs[lastGlyph - 1];
|
||||
d = glyphs[lastGlyph];
|
||||
ic = charIndices[lastGlyph - 1];
|
||||
id = charIndices[lastGlyph];
|
||||
c = glyphStorage[lastGlyph - 1];
|
||||
d = glyphStorage[lastGlyph];
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
x = lastGlyph - 2;
|
||||
|
||||
while (x >= firstGlyph) {
|
||||
glyphs[x + 2] = glyphs[x];
|
||||
charIndices[x + 2] = charIndices[x];
|
||||
glyphStorage[x + 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 2, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphs[firstGlyph] = d;
|
||||
glyphs[firstGlyph + 1] = c;
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
|
||||
charIndices[firstGlyph] = id;
|
||||
charIndices[firstGlyph + 1] = ic;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
break;
|
||||
|
||||
case irvCDxA:
|
||||
a = glyphs[firstGlyph];
|
||||
c = glyphs[lastGlyph - 1];
|
||||
d = glyphs[lastGlyph];
|
||||
ia = charIndices[firstGlyph];
|
||||
ic = charIndices[lastGlyph - 1];
|
||||
id = charIndices[lastGlyph];
|
||||
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) {
|
||||
glyphs[x + 1] = glyphs[x];
|
||||
charIndices[x + 1] = charIndices[x];
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphs[firstGlyph] = c;
|
||||
glyphs[firstGlyph + 1] = d;
|
||||
glyphs[lastGlyph] = a;
|
||||
glyphStorage[firstGlyph] = c;
|
||||
glyphStorage[firstGlyph + 1] = d;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
charIndices[firstGlyph] = ic;
|
||||
charIndices[firstGlyph + 1] = id;
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxA:
|
||||
a = glyphs[firstGlyph];
|
||||
c = glyphs[lastGlyph - 1];
|
||||
d = glyphs[lastGlyph];
|
||||
ia = charIndices[firstGlyph];
|
||||
ic = charIndices[lastGlyph - 1];
|
||||
id = charIndices[lastGlyph];
|
||||
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) {
|
||||
glyphs[x + 1] = glyphs[x];
|
||||
charIndices[x + 1] = charIndices[x];
|
||||
glyphStorage[x + 1] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x + 1, ix, success);
|
||||
x -= 1;
|
||||
}
|
||||
|
||||
glyphs[firstGlyph] = d;
|
||||
glyphs[firstGlyph + 1] = c;
|
||||
glyphs[lastGlyph] = a;
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[firstGlyph + 1] = c;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
charIndices[firstGlyph] = id;
|
||||
charIndices[firstGlyph + 1] = ic;
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDxAB:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
d = glyphs[lastGlyph];
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
id = charIndices[lastGlyph];
|
||||
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) {
|
||||
glyphs[x - 2] = glyphs[x];
|
||||
charIndices[x - 2] = charIndices[x];
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphs[firstGlyph] = d;
|
||||
glyphs[lastGlyph - 1] = a;
|
||||
glyphs[lastGlyph] = b;
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
charIndices[firstGlyph] = id;
|
||||
charIndices[lastGlyph - 1] = ia;
|
||||
charIndices[lastGlyph] = ib;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDxBA:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
d = glyphs[lastGlyph];
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
id = charIndices[lastGlyph];
|
||||
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) {
|
||||
glyphs[x - 2] = glyphs[x];
|
||||
charIndices[x - 2] = charIndices[x];
|
||||
glyphStorage[x - 2] = glyphStorage[x];
|
||||
ix = glyphStorage.getCharIndex(x, success);
|
||||
glyphStorage.setCharIndex(x - 2, ix, success);
|
||||
x += 1;
|
||||
}
|
||||
|
||||
glyphs[firstGlyph] = d;
|
||||
glyphs[lastGlyph - 1] = b;
|
||||
glyphs[lastGlyph] = a;
|
||||
glyphStorage[firstGlyph] = d;
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
charIndices[firstGlyph] = id;
|
||||
charIndices[lastGlyph - 1] = ib;
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvCDxAB:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphs[firstGlyph] = glyphs[lastGlyph - 1];
|
||||
glyphs[firstGlyph + 1] = glyphs[lastGlyph];
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphs[lastGlyph - 1] = a;
|
||||
glyphs[lastGlyph] = b;
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
charIndices[firstGlyph] = charIndices[lastGlyph - 1];
|
||||
charIndices[firstGlyph + 1] = charIndices[lastGlyph];
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
charIndices[lastGlyph - 1] = ia;
|
||||
charIndices[lastGlyph] = ib;
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvCDxBA:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphs[firstGlyph] = glyphs[lastGlyph - 1];
|
||||
glyphs[firstGlyph + 1] = glyphs[lastGlyph];
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
|
||||
|
||||
glyphs[lastGlyph - 1] = b;
|
||||
glyphs[lastGlyph] = a;
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
charIndices[firstGlyph] = charIndices[lastGlyph - 1];
|
||||
charIndices[firstGlyph + 1] = charIndices[lastGlyph];
|
||||
glyphStorage.setCharIndex(firstGlyph, ic, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, id, success);
|
||||
|
||||
charIndices[lastGlyph - 1] = ib;
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
case irvDCxAB:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphs[firstGlyph] = glyphs[lastGlyph];
|
||||
glyphs[firstGlyph + 1] = glyphs[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphs[lastGlyph - 1] = a;
|
||||
glyphs[lastGlyph] = b;
|
||||
glyphStorage[lastGlyph - 1] = a;
|
||||
glyphStorage[lastGlyph] = b;
|
||||
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
charIndices[firstGlyph] = charIndices[lastGlyph];
|
||||
charIndices[firstGlyph + 1] = charIndices[lastGlyph - 1];
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
charIndices[lastGlyph - 1] = ia;
|
||||
charIndices[lastGlyph] = ib;
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ib, success);
|
||||
break;
|
||||
|
||||
case irvDCxBA:
|
||||
a = glyphs[firstGlyph];
|
||||
b = glyphs[firstGlyph + 1];
|
||||
a = glyphStorage[firstGlyph];
|
||||
b = glyphStorage[firstGlyph + 1];
|
||||
|
||||
glyphs[firstGlyph] = glyphs[lastGlyph];
|
||||
glyphs[firstGlyph + 1] = glyphs[lastGlyph - 1];
|
||||
glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
|
||||
glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
|
||||
|
||||
glyphs[lastGlyph - 1] = b;
|
||||
glyphs[lastGlyph] = a;
|
||||
glyphStorage[lastGlyph - 1] = b;
|
||||
glyphStorage[lastGlyph] = a;
|
||||
|
||||
ia = charIndices[firstGlyph];
|
||||
ib = charIndices[firstGlyph + 1];
|
||||
ia = glyphStorage.getCharIndex(firstGlyph, success);
|
||||
ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
|
||||
ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
|
||||
id = glyphStorage.getCharIndex(lastGlyph, success);
|
||||
|
||||
charIndices[firstGlyph] = charIndices[lastGlyph];
|
||||
charIndices[firstGlyph + 1] = charIndices[lastGlyph - 1];
|
||||
glyphStorage.setCharIndex(firstGlyph, id, success);
|
||||
glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
|
||||
|
||||
charIndices[lastGlyph - 1] = ib;
|
||||
charIndices[lastGlyph] = ia;
|
||||
glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
|
||||
glyphStorage.setCharIndex(lastGlyph, ia, success);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)IndicRearrangementProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,17 +20,18 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class IndicRearrangementProcessor : public StateTableProcessor
|
||||
{
|
||||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual ByteOffset processStateEntry(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 &currGlyph,
|
||||
le_int32 glyphCount, EntryTableIndex index);
|
||||
virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
void doRearrangementAction(LEGlyphID *glyphs, le_int32 *charIndices, IndicRearrangementVerb verb) const;
|
||||
void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
|
||||
|
||||
IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader);
|
||||
virtual ~IndicRearrangementProcessor();
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "IndicReordering.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "MPreFixups.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -13,10 +16,9 @@ U_NAMESPACE_BEGIN
|
|||
class ReorderingOutput : public UMemory {
|
||||
private:
|
||||
le_int32 fOutIndex;
|
||||
LEUnicode *fOutChars;
|
||||
|
||||
LEUnicode *fOutChars;
|
||||
le_int32 *fCharIndices;
|
||||
const LETag **fCharTags;
|
||||
LEGlyphStorage &fGlyphStorage;
|
||||
|
||||
LEUnicode fMpre;
|
||||
LEUnicode fMbelow;
|
||||
|
@ -70,8 +72,8 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
ReorderingOutput(LEUnicode *outChars, le_int32 *charIndices, const LETag **charTags, MPreFixups *mpreFixups)
|
||||
: fOutIndex(0), fOutChars(outChars), fCharIndices(charIndices), fCharTags(charTags),
|
||||
ReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage, MPreFixups *mpreFixups)
|
||||
: fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage),
|
||||
fMpre(0), fMbelow(0), fMabove(0), fMpost(0), fLengthMark(0), fMatraIndex(0), fMatraTags(NULL),
|
||||
fMPreOutIndex(-1), fMPreFixups(mpreFixups),
|
||||
fVMabove(0), fVMpost(0), fVMIndex(0), fVMTags(NULL),
|
||||
|
@ -239,9 +241,12 @@ public:
|
|||
|
||||
void writeChar(LEUnicode ch, le_uint32 charIndex, const LETag *charTags)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
fOutChars[fOutIndex] = ch;
|
||||
fCharIndices[fOutIndex] = charIndex;
|
||||
fCharTags[fOutIndex] = charTags;
|
||||
|
||||
fGlyphStorage.setCharIndex(fOutIndex, charIndex, success);
|
||||
fGlyphStorage.setAuxData(fOutIndex, (void *) charTags, success);
|
||||
|
||||
fOutIndex += 1;
|
||||
}
|
||||
|
@ -337,7 +342,7 @@ le_int32 IndicReordering::findSyllable(const IndicClassTable *classTable, const
|
|||
}
|
||||
|
||||
le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le_int32 scriptCode,
|
||||
LEUnicode *outChars, le_int32 *charIndices, const LETag **charTags,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage,
|
||||
MPreFixups **outMPreFixups)
|
||||
{
|
||||
MPreFixups *mpreFixups = NULL;
|
||||
|
@ -347,7 +352,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
|
|||
mpreFixups = new MPreFixups(charCount);
|
||||
}
|
||||
|
||||
ReorderingOutput output(outChars, charIndices, charTags, mpreFixups);
|
||||
ReorderingOutput output(outChars, glyphStorage, mpreFixups);
|
||||
le_int32 i, prev = 0;
|
||||
|
||||
while (prev < charCount) {
|
||||
|
@ -604,10 +609,10 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
|
|||
return output.getOutputIndex();
|
||||
}
|
||||
|
||||
void IndicReordering::adjustMPres(MPreFixups *mpreFixups, LEGlyphID *glyphs, le_int32 *charIndices)
|
||||
void IndicReordering::adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
if (mpreFixups != NULL) {
|
||||
mpreFixups->apply(glyphs, charIndices);
|
||||
mpreFixups->apply(glyphStorage);
|
||||
|
||||
delete mpreFixups;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INDICREORDERING_H
|
||||
|
@ -24,7 +26,8 @@ enum
|
|||
|
||||
typedef LEUnicode SplitMatra[3];
|
||||
|
||||
class MPreFixups;
|
||||
class MPreFixups;
|
||||
class LEGlyphStorage;
|
||||
|
||||
struct IndicClassTable
|
||||
{
|
||||
|
@ -130,10 +133,10 @@ public:
|
|||
static le_int32 getWorstCaseExpansion(le_int32 scriptCode);
|
||||
|
||||
static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
|
||||
LEUnicode *outChars, le_int32 *charIndices, const LETag **charTags,
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage,
|
||||
MPreFixups **outMPreFixups);
|
||||
|
||||
static void adjustMPres(MPreFixups *mpreFixups, LEGlyphID *glyphs, le_int32 *charIndices);
|
||||
static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage);
|
||||
|
||||
static const LETag *getFeatureOrder();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2003, International Business Machines
|
||||
* Copyright (C) 1999-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include "LETypes.h"
|
||||
#include "LEScripts.h"
|
||||
#include "LEFontInstance.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -36,7 +37,7 @@ const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int
|
|||
}
|
||||
|
||||
void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count,
|
||||
le_bool reverse, const LECharMapper *mapper, LEGlyphID glyphs[]) const
|
||||
le_bool reverse, const LECharMapper *mapper, LEGlyphStorage &glyphStorage) const
|
||||
{
|
||||
le_int32 i, out = 0, dir = 1;
|
||||
|
||||
|
@ -57,11 +58,11 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset,
|
|||
}
|
||||
}
|
||||
|
||||
glyphs[out] = mapCharToGlyph(code, mapper);
|
||||
glyphStorage[out] = mapCharToGlyph(code, mapper);
|
||||
|
||||
if (code >= 0x10000) {
|
||||
i += 1;
|
||||
glyphs[out += dir] = 0xFFFF;
|
||||
glyphStorage[out += dir] = 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
/*
|
||||
* @(#)LEFontInstance.h 1.3 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -43,6 +42,8 @@ public:
|
|||
virtual LEUnicode32 mapChar(LEUnicode32 ch) const = 0;
|
||||
};
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This is a virtual base class that serves as the interface between a LayoutEngine
|
||||
* and the platform font environment. It allows a LayoutEngine to access font tables, do
|
||||
|
@ -191,13 +192,13 @@ public:
|
|||
* @param count - the number of characters
|
||||
* @param reverse - if TRUE, store the glyph indices in reverse order.
|
||||
* @param mapper - the character mapper.
|
||||
* @param glyphs - the output glyph array
|
||||
* @param glyphStorage - the object which contains the output glyph array
|
||||
*
|
||||
* @see LECharMapper
|
||||
*
|
||||
* @draft ICU 2.6
|
||||
*/
|
||||
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, LEGlyphID glyphs[]) const;
|
||||
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, LEGlyphStorage &glyphStorage) const;
|
||||
|
||||
/**
|
||||
* This method maps a single character to a glyph index, using the
|
||||
|
|
586
icu4c/source/layout/LEGlyphStorage.cpp
Normal file
586
icu4c/source/layout/LEGlyphStorage.cpp
Normal file
|
@ -0,0 +1,586 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1998-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEInsertionList.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
const char LEGlyphStorage::fgClassID=0;
|
||||
|
||||
LEGlyphStorage::LEGlyphStorage()
|
||||
: fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
|
||||
fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
|
||||
{
|
||||
// nothing else to do!
|
||||
}
|
||||
|
||||
LEGlyphStorage::~LEGlyphStorage()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void LEGlyphStorage::reset()
|
||||
{
|
||||
fGlyphCount = 0;
|
||||
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
fPositions = NULL;
|
||||
}
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
fAuxData = NULL;
|
||||
}
|
||||
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
fInsertionList = NULL;
|
||||
}
|
||||
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
fCharIndices = NULL;
|
||||
}
|
||||
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
fGlyphs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This might get called more than once, for various reasons. Is
|
||||
// testing for pre-existing glyph and charIndices arrays good enough?
|
||||
void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialGlyphCount <= 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
fGlyphCount = initialGlyphCount;
|
||||
fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
fGlyphs = NULL;
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the charIndices array
|
||||
le_int32 i, count = fGlyphCount, dir = 1, out = 0;
|
||||
|
||||
if (rightToLeft) {
|
||||
out = fGlyphCount - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
fCharIndices[out] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (fInsertionList == NULL) {
|
||||
// FIXME: check this for failure?
|
||||
fInsertionList = new LEInsertionList(rightToLeft);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do we want to initialize the positions to [0, 0]?
|
||||
le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
// FIXME: do we want to initialize the aux data to NULL?
|
||||
le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fAuxData = LE_NEW_ARRAY(void *, fGlyphCount);
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 i;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (charIndices == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < fGlyphCount; i += 1) {
|
||||
charIndices[i] = fCharIndices[i] + indexBase;
|
||||
}
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (charIndices == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
|
||||
}
|
||||
|
||||
// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
|
||||
void LEGlyphStorage::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 i;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < fGlyphCount; i += 1) {
|
||||
glyphs[i] = fGlyphs[i] | extraBits;
|
||||
}
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
|
||||
}
|
||||
|
||||
LEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
return fGlyphs[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fGlyphs[glyphIndex] = glyphID;
|
||||
}
|
||||
|
||||
le_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fCharIndices[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fCharIndices[glyphIndex] = charIndex;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auxData == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
|
||||
}
|
||||
|
||||
void *LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fAuxData[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setAuxData(le_int32 glyphIndex, void *auxData, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fAuxData[glyphIndex] = auxData;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (positions == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
x = fPositions[glyphIndex * 2];
|
||||
y = fPositions[glyphIndex * 2 + 1];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fPositions[glyphIndex * 2] = x;
|
||||
fPositions[glyphIndex * 2 + 1] = y;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fPositions[glyphIndex * 2] += xAdjust;
|
||||
fPositions[glyphIndex * 2 + 1] += yAdjust;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
}
|
||||
|
||||
fGlyphs = from.fGlyphs;
|
||||
from.fGlyphs = NULL;
|
||||
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
}
|
||||
|
||||
fInsertionList = from.fInsertionList;
|
||||
from.fInsertionList = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
}
|
||||
|
||||
fCharIndices = from.fCharIndices;
|
||||
from.fCharIndices = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
}
|
||||
|
||||
fPositions = from.fPositions;
|
||||
from.fPositions = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
}
|
||||
|
||||
fAuxData = from.fAuxData;
|
||||
from.fAuxData = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
|
||||
{
|
||||
fGlyphCount = from.fGlyphCount;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
|
||||
{
|
||||
fGlyphCount = newGlyphCount;
|
||||
}
|
||||
|
||||
// FIXME: add error checking?
|
||||
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount)
|
||||
{
|
||||
return fInsertionList->insert(atIndex, insertCount);
|
||||
}
|
||||
|
||||
le_int32 LEGlyphStorage::applyInsertions()
|
||||
{
|
||||
le_int32 growAmount = fInsertionList->getGrowAmount();
|
||||
|
||||
if (growAmount == 0) {
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
le_int32 newGlyphCount = fGlyphCount + growAmount;
|
||||
|
||||
fGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
|
||||
fCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
fAuxData = (void **) LE_GROW_ARRAY(fAuxData, newGlyphCount);
|
||||
}
|
||||
|
||||
fSrcIndex = fGlyphCount - 1;
|
||||
fDestIndex = newGlyphCount - 1;
|
||||
|
||||
#if 0
|
||||
// If the current position is at the end of the array
|
||||
// update it to point to the end of the new array. The
|
||||
// insertion callback will handle all other cases.
|
||||
// FIXME: this is left over from GlyphIterator, but there's no easy
|
||||
// way to implement this here... it seems that GlyphIterator doesn't
|
||||
// really need it 'cause the insertions don't get applied until after a
|
||||
// complete pass over the glyphs, after which the iterator gets reset anyhow...
|
||||
// probably better to just document that for LEGlyphStorage and GlyphIterator...
|
||||
if (position == glyphCount) {
|
||||
position = newGlyphCount;
|
||||
}
|
||||
#endif
|
||||
|
||||
fInsertionList->applyInsertions(this);
|
||||
|
||||
fInsertionList->reset();
|
||||
|
||||
return fGlyphCount = newGlyphCount;
|
||||
}
|
||||
|
||||
le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
|
||||
{
|
||||
#if 0
|
||||
// if the current position is within the block we're shifting
|
||||
// it needs to be updated to the current glyph's
|
||||
// new location.
|
||||
// FIXME: this is left over from GlyphIterator, but there's no easy
|
||||
// way to implement this here... it seems that GlyphIterator doesn't
|
||||
// really need it 'cause the insertions don't get applied until after a
|
||||
// complete pass over the glyphs, after which the iterator gets reset anyhow...
|
||||
// probably better to just document that for LEGlyphStorage and GlyphIterator...
|
||||
if (position >= atPosition && position <= fSrcIndex) {
|
||||
position += fDestIndex - fSrcIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
le_int32 src = fSrcIndex, dest = fDestIndex;
|
||||
|
||||
while (src > atPosition) {
|
||||
fAuxData[dest--] = fAuxData[src--];
|
||||
}
|
||||
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
fAuxData[dest--] = fAuxData[atPosition];
|
||||
}
|
||||
}
|
||||
|
||||
while (fSrcIndex > atPosition) {
|
||||
fGlyphs[fDestIndex] = fGlyphs[fSrcIndex];
|
||||
fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
|
||||
|
||||
fDestIndex -= 1;
|
||||
fSrcIndex -= 1;
|
||||
}
|
||||
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
fGlyphs[fDestIndex] = newGlyphs[i];
|
||||
fCharIndices[fDestIndex] = fCharIndices[atPosition];
|
||||
|
||||
fDestIndex -= 1;
|
||||
}
|
||||
|
||||
// the source glyph we're pointing at
|
||||
// just got replaced by the insertion
|
||||
fSrcIndex -= 1;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
207
icu4c/source/layout/LEGlyphStorage.h
Normal file
207
icu4c/source/layout/LEGlyphStorage.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1998-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __LEGLYPHSTORAGE_H
|
||||
#define __LEGLYPHSTORAGE_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEInsertionList.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage : public UObject, protected LEInsertionCallback
|
||||
{
|
||||
private:
|
||||
le_int32 fGlyphCount;
|
||||
|
||||
LEGlyphID *fGlyphs;
|
||||
le_int32 *fCharIndices;
|
||||
float *fPositions;
|
||||
void **fAuxData;
|
||||
|
||||
LEInsertionList *fInsertionList;
|
||||
le_int32 fSrcIndex;
|
||||
le_int32 fDestIndex;
|
||||
|
||||
/**
|
||||
* The address of this static class variable serves as this class's ID
|
||||
* for ICU "poor man's RTTI".
|
||||
*/
|
||||
static const char fgClassID;
|
||||
|
||||
protected:
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]);
|
||||
|
||||
public:
|
||||
|
||||
// allocates glyphs, charIndices...
|
||||
// call allocatePositions() or allocateAuxData() to allocat those.
|
||||
LEGlyphStorage();
|
||||
~LEGlyphStorage();
|
||||
|
||||
/**
|
||||
* This method returns the number of glyphs in the glyph array. Note
|
||||
* that the number of glyphs will be greater than or equal to the number
|
||||
* of characters used to create the LayoutEngine.
|
||||
*
|
||||
* @return the number of glyphs in the glyph array
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
le_int32 getGlyphCount() const
|
||||
{
|
||||
return fGlyphCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* This method copies the glyph array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold all
|
||||
* the glyphs.
|
||||
*
|
||||
* @param glyphs - the destiniation glyph array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the glyph array into a caller supplied array,
|
||||
* ORing in extra bits. (This functionality is needed by the JDK,
|
||||
* which uses 32 bits pre glyph idex, with the high 16 bits encoding
|
||||
* the composite font slot number)
|
||||
*
|
||||
* @param glyphs - the destination (32 bit) glyph array
|
||||
* @param extraBits - this value will be ORed with each glyph index
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the character index array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold a
|
||||
* character index for each glyph.
|
||||
*
|
||||
* @param charIndices - the destiniation character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void getCharIndices(le_int32 charIndices[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the character index array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold a
|
||||
* character index for each glyph.
|
||||
*
|
||||
* @param charIndices - the destiniation character index array
|
||||
* @param indexBase - an offset which will be added to each index
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method copies the position array into a caller supplied array.
|
||||
* The caller must ensure that the array is large enough to hold an
|
||||
* X and Y position for each glyph, plus an extra X and Y for the
|
||||
* advance of the last glyph.
|
||||
*
|
||||
* @param glyphs - the destiniation position array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void getGlyphPositions(float positions[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This method returns the X and Y position of the glyph at
|
||||
* the given index.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param glyphIndex - the index of the glyph
|
||||
*
|
||||
* Output parameters:
|
||||
* @param x - the glyph's X position
|
||||
* @param y - the glyph's Y position
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const;
|
||||
|
||||
void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success);
|
||||
|
||||
// allocate the given data array, return the size? (it's just the glyph count,
|
||||
// so maybe we don't need to return it?)
|
||||
le_int32 allocatePositions(LEErrorCode &success);
|
||||
le_int32 allocateAuxData(LEErrorCode &success);
|
||||
|
||||
void getAuxData(void *auxData[], LEErrorCode &success) const;
|
||||
|
||||
LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
le_int32 getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
|
||||
void *getAuxData(le_int32 glyphIndex, LEErrorCode &success) const; // or "getAuxDatum"?
|
||||
void setAuxData(le_int32 glyphIndex, void *auxData, LEErrorCode &success); // or "setAuxDatum"?
|
||||
|
||||
LEGlyphID &operator[](le_int32 glyphIndex) const;
|
||||
|
||||
// return value is address of storage for new glyphs...
|
||||
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount);
|
||||
|
||||
// return value is new glyph count.
|
||||
le_int32 applyInsertions();
|
||||
|
||||
void setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success);
|
||||
void setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success);
|
||||
void setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success);
|
||||
void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success);
|
||||
|
||||
void adoptGlyphArray(LEGlyphStorage &from);
|
||||
void adoptCharIndicesArray(LEGlyphStorage &from);
|
||||
void adoptPositionArray(LEGlyphStorage &from);
|
||||
void adoptAuxDataArray(LEGlyphStorage &from);
|
||||
void adoptGlyphCount(LEGlyphStorage &from);
|
||||
void adoptGlyphCount(le_int32 newGlyphCount);
|
||||
|
||||
/**
|
||||
* This method frees the glyph, character index and position arrays
|
||||
* so that the LayoutEngine can be reused to layout a different
|
||||
* characer array. (This method is also called by the destructor)
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @darft ICU 3.0
|
||||
*/
|
||||
virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
|
||||
};
|
||||
|
||||
inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
|
||||
{
|
||||
return fGlyphs[glyphIndex];
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
88
icu4c/source/layout/LEInsertionList.cpp
Normal file
88
icu4c/source/layout/LEInsertionList.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1998-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEInsertionList.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#define ANY_NUMBER 1
|
||||
|
||||
struct InsertionRecord
|
||||
{
|
||||
InsertionRecord *next;
|
||||
le_int32 position;
|
||||
le_int32 count;
|
||||
LEGlyphID glyphs[ANY_NUMBER];
|
||||
};
|
||||
|
||||
const char LEInsertionList::fgClassID = 0;
|
||||
|
||||
LEInsertionList::LEInsertionList(le_bool rightToLeft)
|
||||
: head(NULL), tail(NULL), growAmount(0), append(rightToLeft)
|
||||
{
|
||||
tail = (InsertionRecord *) &head;
|
||||
}
|
||||
|
||||
LEInsertionList::~LEInsertionList()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void LEInsertionList::reset()
|
||||
{
|
||||
while (head != NULL) {
|
||||
InsertionRecord *record = head;
|
||||
|
||||
head = head->next;
|
||||
LE_DELETE_ARRAY(record);
|
||||
}
|
||||
|
||||
tail = (InsertionRecord *) &head;
|
||||
growAmount = 0;
|
||||
}
|
||||
|
||||
le_int32 LEInsertionList::getGrowAmount()
|
||||
{
|
||||
return growAmount;
|
||||
}
|
||||
|
||||
LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count)
|
||||
{
|
||||
InsertionRecord *insertion = (InsertionRecord *) LE_NEW_ARRAY(char, sizeof(InsertionRecord) + (count - ANY_NUMBER) * sizeof (LEGlyphID));
|
||||
|
||||
insertion->position = position;
|
||||
insertion->count = count;
|
||||
|
||||
growAmount += count - 1;
|
||||
|
||||
if (append) {
|
||||
// insert on end of list...
|
||||
insertion->next = NULL;
|
||||
tail->next = insertion;
|
||||
tail = insertion;
|
||||
} else {
|
||||
// insert on front of list...
|
||||
insertion->next = head;
|
||||
head = insertion;
|
||||
}
|
||||
|
||||
return insertion->glyphs;
|
||||
}
|
||||
|
||||
le_bool LEInsertionList::applyInsertions(LEInsertionCallback *callback)
|
||||
{
|
||||
for (InsertionRecord *rec = head; rec != NULL; rec = rec->next) {
|
||||
if (callback->applyInsertion(rec->position, rec->count, rec->glyphs)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
67
icu4c/source/layout/LEInsertionList.h
Normal file
67
icu4c/source/layout/LEInsertionList.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1998-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __LEINSERTIONLIST_H
|
||||
#define __LEINSERTIONLIST_H
|
||||
|
||||
#include "LETypes.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct InsertionRecord;
|
||||
|
||||
class LEInsertionCallback
|
||||
{
|
||||
public:
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0;
|
||||
};
|
||||
|
||||
class LEInsertionList : public UObject
|
||||
{
|
||||
public:
|
||||
LEInsertionList(le_bool rightToLeft);
|
||||
~LEInsertionList();
|
||||
|
||||
LEGlyphID *insert(le_int32 position, le_int32 count);
|
||||
le_int32 getGrowAmount();
|
||||
|
||||
le_bool applyInsertions(LEInsertionCallback *callback);
|
||||
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
*
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||
*
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The address of this static class variable serves as this class's ID
|
||||
* for ICU "poor man's RTTI".
|
||||
*/
|
||||
static const char fgClassID;
|
||||
|
||||
InsertionRecord *head;
|
||||
InsertionRecord *tail;
|
||||
|
||||
le_int32 growAmount;
|
||||
le_bool append;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
|||
#include "GXLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "OpenTypeUtilities.h"
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "MorphTables.h"
|
||||
|
@ -93,140 +95,51 @@ LEGlyphFilter::~LEGlyphFilter()
|
|||
const char LayoutEngine::fgClassID=0;
|
||||
|
||||
LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode)
|
||||
: fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
|
||||
fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode)
|
||||
: fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode)
|
||||
{
|
||||
// nothing else to do?
|
||||
fGlyphStorage = new LEGlyphStorage();
|
||||
}
|
||||
|
||||
le_int32 LayoutEngine::getGlyphCount() const
|
||||
{
|
||||
return fGlyphStorage->getGlyphCount();
|
||||
};
|
||||
|
||||
void LayoutEngine::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 i;
|
||||
|
||||
if LE_FAILURE(success) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (charIndices == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < fGlyphCount; i += 1) {
|
||||
charIndices[i] = fCharIndices[i] + indexBase;
|
||||
}
|
||||
fGlyphStorage->getCharIndices(charIndices, indexBase, success);
|
||||
}
|
||||
|
||||
void LayoutEngine::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
|
||||
{
|
||||
if LE_FAILURE(success) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (charIndices == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
|
||||
fGlyphStorage->getCharIndices(charIndices, success);
|
||||
}
|
||||
|
||||
// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
|
||||
void LayoutEngine::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 i;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < fGlyphCount; i += 1) {
|
||||
glyphs[i] = fGlyphs[i] | extraBits;
|
||||
}
|
||||
fGlyphStorage->getGlyphs(glyphs, extraBits, success);
|
||||
}
|
||||
|
||||
void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
|
||||
fGlyphStorage->getGlyphs(glyphs, success);
|
||||
}
|
||||
|
||||
|
||||
void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const
|
||||
{
|
||||
if LE_FAILURE(success) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (positions == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
|
||||
fGlyphStorage->getGlyphPositions(positions, success);
|
||||
}
|
||||
|
||||
void LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex > fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
x = fPositions[glyphIndex * 2];
|
||||
y = fPositions[glyphIndex * 2 + 1];
|
||||
fGlyphStorage->getGlyphPosition(glyphIndex, x, y, success);
|
||||
}
|
||||
|
||||
|
||||
le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
|
@ -237,106 +150,41 @@ le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, l
|
|||
return 0;
|
||||
}
|
||||
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphs, charIndices, success);
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
|
||||
|
||||
return count;
|
||||
return glyphStorage.getGlyphCount();
|
||||
}
|
||||
|
||||
// Input: glyphs
|
||||
// Output: positions
|
||||
void LayoutEngine::positionGlyphs(const LEGlyphID glyphs[], le_int32 glyphCount, float x, float y, float *&positions, LEErrorCode &success)
|
||||
void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphCount < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
glyphStorage.allocatePositions(success);
|
||||
|
||||
if (positions == NULL) {
|
||||
positions = LE_NEW_ARRAY(float, 2 * (glyphCount + 1));
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (positions == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
le_int32 i;
|
||||
le_int32 i, glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
for (i = 0; i < glyphCount; i += 1) {
|
||||
LEPoint advance;
|
||||
|
||||
positions[i * 2] = x;
|
||||
positions[i * 2 + 1] = y;
|
||||
glyphStorage.setPosition(i, x, y, success);
|
||||
|
||||
fFontInstance->getGlyphAdvance(glyphs[i], advance);
|
||||
fFontInstance->getGlyphAdvance(glyphStorage[i], advance);
|
||||
x += advance.fX;
|
||||
y += advance.fY;
|
||||
}
|
||||
|
||||
positions[glyphCount * 2] = x;
|
||||
positions[glyphCount * 2 + 1] = y;
|
||||
glyphStorage.setPosition(glyphCount, x, y, success);
|
||||
}
|
||||
|
||||
void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || glyphs == NULL || positions == NULL || offset < 0 || count < 0 || glyphCount < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// default is no adjustments
|
||||
return;
|
||||
}
|
||||
|
||||
void LayoutEngine::adjustMarkGlyphs(const LEGlyphID glyphs[], le_int32 glyphCount, le_bool reverse, LEGlyphFilter *markFilter,
|
||||
float positions[], LEErrorCode &success)
|
||||
{
|
||||
float xAdjust = 0;
|
||||
le_int32 g = 0, direction = 1;
|
||||
le_int32 p;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (positions == NULL || markFilter == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (reverse) {
|
||||
g = glyphCount - 1;
|
||||
direction = -1;
|
||||
}
|
||||
|
||||
for (p = 0; p < glyphCount; p += 1, g += direction) {
|
||||
float xAdvance = positions[(p + 1) * 2] - positions[p * 2];
|
||||
|
||||
positions[p * 2] += xAdjust;
|
||||
|
||||
if (markFilter->accept(glyphs[g])) {
|
||||
xAdjust -= xAdvance;
|
||||
}
|
||||
}
|
||||
|
||||
positions[glyphCount * 2] += xAdjust;
|
||||
}
|
||||
|
||||
const void *LayoutEngine::getFontTable(LETag tableTag) const
|
||||
{
|
||||
return fFontInstance->getFontTable(tableTag);
|
||||
}
|
||||
|
||||
void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
|
@ -347,38 +195,105 @@ void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le
|
|||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
glyphs = LE_NEW_ARRAY(LEGlyphID, count);
|
||||
// default is no adjustments
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success)
|
||||
{
|
||||
float xAdjust = 0;
|
||||
le_int32 p, glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (charIndices == NULL) {
|
||||
le_int32 i, dir = 1, out = 0;
|
||||
|
||||
if (reverse) {
|
||||
out = count - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
charIndices = LE_NEW_ARRAY(le_int32, count);
|
||||
|
||||
if (charIndices == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
charIndices[out] = i;
|
||||
}
|
||||
if (markFilter == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
float ignore, prev;
|
||||
|
||||
glyphStorage.getGlyphPosition(0, prev, ignore, success);
|
||||
|
||||
for (p = 0; p < glyphCount; p += 1) {
|
||||
float next, xAdvance;
|
||||
|
||||
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
|
||||
|
||||
xAdvance = next - prev;
|
||||
glyphStorage.adjustPosition(p, xAdjust, 0, success);
|
||||
|
||||
if (markFilter->accept(glyphStorage[p])) {
|
||||
xAdjust -= xAdvance;
|
||||
}
|
||||
|
||||
prev = next;
|
||||
}
|
||||
|
||||
glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success);
|
||||
}
|
||||
|
||||
void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success)
|
||||
{
|
||||
float xAdjust = 0;
|
||||
le_int32 c = 0, direction = 1, p;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (markFilter == NULL) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (reverse) {
|
||||
c = glyphCount - 1;
|
||||
direction = -1;
|
||||
}
|
||||
|
||||
float ignore, prev;
|
||||
|
||||
glyphStorage.getGlyphPosition(0, prev, ignore, success);
|
||||
|
||||
for (p = 0; p < charCount; p += 1, c += direction) {
|
||||
float next, xAdvance;
|
||||
|
||||
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
|
||||
|
||||
xAdvance = next - prev;
|
||||
glyphStorage.adjustPosition(p, xAdjust, 0, success);
|
||||
|
||||
if (markFilter->accept(chars[c])) {
|
||||
xAdjust -= xAdvance;
|
||||
}
|
||||
|
||||
prev = next;
|
||||
}
|
||||
|
||||
glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success);
|
||||
}
|
||||
|
||||
const void *LayoutEngine::getFontTable(LETag tableTag) const
|
||||
{
|
||||
return fFontInstance->getFontTable(tableTag);
|
||||
}
|
||||
|
||||
void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
glyphStorage.allocateGlyphArray(count, reverse, success);
|
||||
|
||||
DefaultCharMapper charMapper(TRUE, mirror);
|
||||
|
||||
fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, glyphs);
|
||||
fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, glyphStorage);
|
||||
}
|
||||
|
||||
// Input: characters, font?
|
||||
|
@ -396,31 +311,18 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_
|
|||
return 0;
|
||||
}
|
||||
|
||||
fGlyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, fGlyphs, fCharIndices, success);
|
||||
positionGlyphs(fGlyphs, fGlyphCount, x, y, fPositions, success);
|
||||
adjustGlyphPositions(chars, offset, count, rightToLeft, fGlyphs, fGlyphCount, fPositions, success);
|
||||
le_int32 glyphCount;
|
||||
|
||||
glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success);
|
||||
positionGlyphs(*fGlyphStorage, x, y, success);
|
||||
adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success);
|
||||
|
||||
return fGlyphCount;
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
void LayoutEngine::reset()
|
||||
{
|
||||
fGlyphCount = 0;
|
||||
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
fGlyphs = NULL;
|
||||
}
|
||||
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
fCharIndices = NULL;
|
||||
}
|
||||
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
fPositions = NULL;
|
||||
}
|
||||
fGlyphStorage->reset();
|
||||
}
|
||||
|
||||
LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
|
||||
|
|
|
@ -2,16 +2,14 @@
|
|||
/*
|
||||
* %W% %W%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LAYOUTENGINE_H
|
||||
#define __LAYOUTENGINE_H
|
||||
|
||||
#ifndef __LETYPES_H
|
||||
#include "LETypes.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -19,6 +17,7 @@ U_NAMESPACE_BEGIN
|
|||
|
||||
class LEFontInstance;
|
||||
class LEGlyphFilter;
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This is a virtual base class used to do complex text layout. The text must all
|
||||
|
@ -70,32 +69,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 fGlyphCount;
|
||||
|
||||
/**
|
||||
* The output glyph array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEGlyphID *fGlyphs;
|
||||
|
||||
/**
|
||||
* The character index array. One entry for each output glyph, giving the index
|
||||
* in the input character array of the character which corresponds to this glyph.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 *fCharIndices;
|
||||
|
||||
/**
|
||||
* The glyph position array. There are two entries for each glyph giving the
|
||||
* X and Y positions of the glyph. Thus, for glyph i, the X position is at index
|
||||
* 2i, and the Y position is at index 2i + 1. There are also two entries for the
|
||||
* X and Y position of the advance of the last glyph.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
float *fPositions;
|
||||
LEGlyphStorage *fGlyphStorage;
|
||||
|
||||
/**
|
||||
* The font instance for the text font.
|
||||
|
@ -174,7 +148,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method does basic glyph positioning. The default implementation positions
|
||||
|
@ -192,7 +166,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void positionGlyphs(const LEGlyphID glyphs[], le_int32 glyphCount, float x, float y, float *&positions, LEErrorCode &success);
|
||||
virtual void positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method does positioning adjustments like accent positioning and
|
||||
|
@ -218,7 +192,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success);
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method gets a table from the font associated with
|
||||
|
@ -261,7 +235,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This is a convenience method that forces the advance width of mark
|
||||
|
@ -278,7 +252,10 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
static void adjustMarkGlyphs(const LEGlyphID glyphs[], le_int32 glyphCount, le_bool reverse, LEGlyphFilter *markFilter, float positions[], LEErrorCode &success);
|
||||
static void adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);
|
||||
|
||||
static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -323,10 +300,7 @@ public:
|
|||
*
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
le_int32 getGlyphCount() const
|
||||
{
|
||||
return fGlyphCount;
|
||||
};
|
||||
le_int32 getGlyphCount() const;
|
||||
|
||||
/**
|
||||
* This method copies the glyph array into a caller supplied array.
|
||||
|
@ -385,7 +359,7 @@ public:
|
|||
* X and Y position for each glyph, plus an extra X and Y for the
|
||||
* advance of the last glyph.
|
||||
*
|
||||
* @param glyphs - the destiniation position array
|
||||
* @param positions - the destiniation position array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @stable ICU 2.8
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)GlyphSubstLookupProc.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -12,6 +11,7 @@
|
|||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "LigatureSubstProc.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -42,7 +42,7 @@ void LigatureSubstitutionProcessor::beginStateTable()
|
|||
m = -1;
|
||||
}
|
||||
|
||||
ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphID *glyphs, le_int32 * /*charIndices*/, le_int32 &currGlyph, le_int32 /*glyphCount*/, EntryTableIndex index)
|
||||
ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
|
||||
{
|
||||
const LigatureSubstitutionStateEntry *entry = &entryTable[index];
|
||||
ByteOffset newState = SWAPW(entry->newStateOffset);
|
||||
|
@ -78,17 +78,17 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphID *glyphs, l
|
|||
if (offset != 0) {
|
||||
const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask));
|
||||
|
||||
i += SWAPW(offsetTable[LE_GET_GLYPH(glyphs[componentGlyph])]);
|
||||
i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);
|
||||
|
||||
if (action & (lafLast | lafStore)) {
|
||||
const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i);
|
||||
TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset);
|
||||
|
||||
glyphs[componentGlyph] = LE_SET_GLYPH(glyphs[componentGlyph], ligatureGlyph);
|
||||
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
|
||||
stack[++mm] = componentGlyph;
|
||||
i = 0;
|
||||
} else {
|
||||
glyphs[componentGlyph] = LE_SET_GLYPH(glyphs[componentGlyph], 0xFFFF);
|
||||
glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
|
||||
}
|
||||
}
|
||||
} while (!(action & lafLast));
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)LigatureSubstProc.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,6 +20,8 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
#define nComponents 16
|
||||
|
||||
class LigatureSubstitutionProcessor : public StateTableProcessor
|
||||
|
@ -28,8 +29,7 @@ class LigatureSubstitutionProcessor : public StateTableProcessor
|
|||
public:
|
||||
virtual void beginStateTable();
|
||||
|
||||
virtual ByteOffset processStateEntry(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 &currGlyph,
|
||||
le_int32 glyphCount, EntryTableIndex index);
|
||||
virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
|
||||
|
||||
virtual void endStateTable();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
|||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositionAdjustments.h"
|
||||
#include "LookupProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -48,16 +49,18 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
|
|||
return 1;
|
||||
}
|
||||
|
||||
le_int32 LookupProcessor::process(LEGlyphID *&glyphs, GlyphPositionAdjustment *glyphPositionAdjustments, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
|
||||
le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustment *glyphPositionAdjustments,
|
||||
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
|
||||
const LEFontInstance *fontInstance) const
|
||||
{
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
if (lookupSelectArray == NULL) {
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
GlyphIterator glyphIterator(glyphs, glyphPositionAdjustments, charIndices, glyphCount,
|
||||
rightToLeft, 0, 0, glyphTags, glyphDefinitionTableHeader);
|
||||
GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
|
||||
rightToLeft, 0, 0, glyphDefinitionTableHeader);
|
||||
le_int32 newGlyphCount = glyphCount;
|
||||
|
||||
for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -24,12 +24,14 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class LookupProcessor : public UMemory {
|
||||
public:
|
||||
static const LETag notSelected;
|
||||
static const LETag defaultFeature;
|
||||
|
||||
le_int32 process(LEGlyphID *&glyphs, GlyphPositionAdjustment *glyphPositionAdjustments, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
|
||||
le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustment *glyphPositionAdjustments,
|
||||
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance) const;
|
||||
|
||||
le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corp. 2002-2003 - All Rights Reserved
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "MPreFixups.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -37,18 +40,18 @@ void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex)
|
|||
}
|
||||
}
|
||||
|
||||
void MPreFixups::apply(LEGlyphID *glyphs, le_int32 *charIndices)
|
||||
void MPreFixups::apply(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
for (le_int32 fixup = 0; fixup < fFixupCount; fixup += 1) {
|
||||
le_int32 baseIndex = fFixupData[fixup].fBaseIndex;
|
||||
le_int32 mpreIndex = fFixupData[fixup].fMPreIndex;
|
||||
le_int32 mpreLimit = mpreIndex + 1;
|
||||
|
||||
while (glyphs[baseIndex] == 0xFFFF || glyphs[baseIndex] == 0xFFFE) {
|
||||
while (glyphStorage[baseIndex] == 0xFFFF || glyphStorage[baseIndex] == 0xFFFE) {
|
||||
baseIndex -= 1;
|
||||
}
|
||||
|
||||
while (glyphs[mpreLimit] == 0xFFFF || glyphs[mpreLimit] == 0xFFFE) {
|
||||
while (glyphStorage[mpreLimit] == 0xFFFF || glyphStorage[mpreLimit] == 0xFFFE) {
|
||||
mpreLimit += 1;
|
||||
}
|
||||
|
||||
|
@ -56,6 +59,7 @@ void MPreFixups::apply(LEGlyphID *glyphs, le_int32 *charIndices)
|
|||
continue;
|
||||
}
|
||||
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
le_int32 mpreCount = mpreLimit - mpreIndex;
|
||||
le_int32 moveCount = baseIndex - mpreLimit;
|
||||
le_int32 mpreDest = baseIndex - mpreCount;
|
||||
|
@ -64,18 +68,21 @@ void MPreFixups::apply(LEGlyphID *glyphs, le_int32 *charIndices)
|
|||
le_int32 i;
|
||||
|
||||
for (i = 0; i < mpreCount; i += 1) {
|
||||
mpreSave[i] = glyphs[mpreIndex + i];
|
||||
indexSave[i] = charIndices[mpreIndex + i];
|
||||
mpreSave[i] = glyphStorage[mpreIndex + i];
|
||||
indexSave[i] = glyphStorage.getCharIndex(mpreIndex + i, success); //charIndices[mpreIndex + i];
|
||||
}
|
||||
|
||||
for (i = 0; i < moveCount; i += 1) {
|
||||
glyphs[mpreIndex + i] = glyphs[mpreLimit + i];
|
||||
charIndices[mpreIndex + i] = charIndices[mpreLimit + i];
|
||||
LEGlyphID glyph = glyphStorage[mpreLimit + i];
|
||||
le_int32 charIndex = glyphStorage.getCharIndex(mpreLimit + i, success);
|
||||
|
||||
glyphStorage[mpreIndex + i] = glyph;
|
||||
glyphStorage.setCharIndex(mpreIndex + i, charIndex, success);
|
||||
}
|
||||
|
||||
for (i = 0; i < mpreCount; i += 1) {
|
||||
glyphs[mpreDest + i] = mpreSave[i];
|
||||
charIndices[mpreDest + i] = indexSave[i];
|
||||
glyphStorage[mpreDest + i] = mpreSave[i];
|
||||
glyphStorage.setCharIndex(mpreDest, indexSave[i], success);
|
||||
}
|
||||
|
||||
LE_DELETE_ARRAY(indexSave);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corp. 2002-2003 - All Rights Reserved
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MPREFIXUPS_H
|
||||
|
@ -14,6 +16,8 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
// Might want to make this a private member...
|
||||
struct FixupData;
|
||||
|
||||
|
@ -25,7 +29,7 @@ public:
|
|||
|
||||
void add(le_int32 baseIndex, le_int32 mpreIndex);
|
||||
|
||||
void apply(LEGlyphID *glyphs, le_int32 *charIndices);
|
||||
void apply(LEGlyphStorage &glyphStorage);
|
||||
|
||||
private:
|
||||
FixupData *fFixupData;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* %W% %W%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998, 1999, 2000, 2001 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998 - 2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -15,11 +15,12 @@
|
|||
#include "LigatureSubstProc.h"
|
||||
#include "NonContextualGlyphSubstProc.h"
|
||||
//#include "ContextualGlyphInsertionProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void MorphTableHeader::process(LEGlyphID *glyphs, le_int32 *glyphIndices, le_int32 glyphCount) const
|
||||
void MorphTableHeader::process(LEGlyphStorage &glyphStorage) const
|
||||
{
|
||||
const ChainHeader *chainHeader = chains;
|
||||
le_uint32 chainCount = SWAPL(this->nChains);
|
||||
|
@ -41,7 +42,7 @@ void MorphTableHeader::process(LEGlyphID *glyphs, le_int32 *glyphIndices, le_int
|
|||
|
||||
// should check coverage more carefully...
|
||||
if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0) {
|
||||
subtableHeader->process(glyphs, glyphIndices, glyphCount);
|
||||
subtableHeader->process(glyphStorage);
|
||||
}
|
||||
|
||||
subtableHeader = (const MorphSubtableHeader *) ((char *)subtableHeader + length);
|
||||
|
@ -51,7 +52,7 @@ void MorphTableHeader::process(LEGlyphID *glyphs, le_int32 *glyphIndices, le_int
|
|||
}
|
||||
}
|
||||
|
||||
void MorphSubtableHeader::process(LEGlyphID *glyphs, le_int32 *glyphIndices, le_int32 glyphCount) const
|
||||
void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const
|
||||
{
|
||||
SubtableProcessor *processor = NULL;
|
||||
|
||||
|
@ -87,7 +88,7 @@ void MorphSubtableHeader::process(LEGlyphID *glyphs, le_int32 *glyphIndices, le_
|
|||
}
|
||||
|
||||
if (processor != NULL) {
|
||||
processor->process(glyphs, glyphIndices, glyphCount);
|
||||
processor->process(glyphStorage);
|
||||
delete processor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)MorphTables.h 1.5 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -18,6 +17,8 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
typedef le_uint32 FeatureFlags;
|
||||
|
||||
typedef le_int16 FeatureType;
|
||||
|
@ -46,7 +47,7 @@ struct MorphTableHeader
|
|||
le_uint32 nChains;
|
||||
ChainHeader chains[ANY_NUMBER];
|
||||
|
||||
void process(LEGlyphID *glyphs, le_int32 *glyphIndices, le_int32 glyphCount) const;
|
||||
void process(LEGlyphStorage &glyphStorage) const;
|
||||
};
|
||||
|
||||
typedef le_int16 SubtableCoverage;
|
||||
|
@ -76,7 +77,7 @@ struct MorphSubtableHeader
|
|||
SubtableCoverage coverage;
|
||||
FeatureFlags subtableFeatures;
|
||||
|
||||
void process(LEGlyphID *glyphs, le_int32 *glyphIndices, le_int32 glyphCount) const;
|
||||
void process(LEGlyphStorage &glyphStorage) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)NonContextualGlyphSubstProc.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -20,10 +19,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class NonContextualGlyphSubstitutionProcessor : public SubtableProcessor
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyphCount) = 0;
|
||||
virtual void process(LEGlyphStorage &glyphStorage) = 0;
|
||||
|
||||
static SubtableProcessor *createInstance(const MorphSubtableHeader *morphSubtableHeader);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* %W% %W%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
|||
#include "GlyphDefinitionTables.h"
|
||||
#include "GlyphPositioningTables.h"
|
||||
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "GDEFMarkFilter.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -26,7 +28,7 @@ const char OpenTypeLayoutEngine::fgClassID=0;
|
|||
|
||||
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
const GlyphSubstitutionTableHeader *gsubTable)
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureTags(NULL), fFeatureOrder(NULL),
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureOrder(NULL),
|
||||
fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
|
||||
{
|
||||
static le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG;
|
||||
|
@ -49,19 +51,10 @@ void OpenTypeLayoutEngine::reset()
|
|||
// will have been called already by
|
||||
// LayoutEngine::~LayoutEngine()
|
||||
LayoutEngine::reset();
|
||||
|
||||
// The double call could be avoided by
|
||||
// puting the following into a private
|
||||
// method that's called from here and
|
||||
// from our destructor
|
||||
if (fFeatureTags != NULL) {
|
||||
LE_DELETE_ARRAY(fFeatureTags);
|
||||
fFeatureTags = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode)
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureTags(NULL), fFeatureOrder(NULL),
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureOrder(NULL),
|
||||
fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
|
||||
{
|
||||
setScriptAndLanguageTags();
|
||||
|
@ -97,7 +90,7 @@ void OpenTypeLayoutEngine::setScriptAndLanguageTags()
|
|||
}
|
||||
|
||||
le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode /*chars*/[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/,
|
||||
LEUnicode *&/*outChars*/, le_int32 *&/*charIndices*/, const LETag **&/*featureTags*/, LEErrorCode &success)
|
||||
LEUnicode *&/*outChars*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
|
@ -114,7 +107,7 @@ le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode /*chars*/[],
|
|||
// Input: characters, tags
|
||||
// Output: glyphs, char indices
|
||||
le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
const LETag **&featureTags, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
|
@ -125,37 +118,37 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32
|
|||
return 0;
|
||||
}
|
||||
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphs, charIndices, success);
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fGSUBTable != NULL) {
|
||||
count = fGSUBTable->process(glyphs, featureTags, charIndices, count, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureOrder);
|
||||
count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureOrder);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
le_int32 OpenTypeLayoutEngine::glyphPostProcessing(LEGlyphID tempGlyphs[], le_int32 tempCharIndices[], le_int32 tempGlyphCount,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
le_int32 OpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphs = tempGlyphs;
|
||||
charIndices = tempCharIndices;
|
||||
glyphStorage.adoptGlyphArray(tempGlyphStorage);
|
||||
glyphStorage.adoptCharIndicesArray(tempGlyphStorage);
|
||||
glyphStorage.adoptAuxDataArray(tempGlyphStorage);
|
||||
glyphStorage.adoptGlyphCount(tempGlyphStorage);
|
||||
|
||||
return tempGlyphCount;
|
||||
return glyphStorage.getGlyphCount();
|
||||
}
|
||||
|
||||
le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
LEUnicode *outChars = NULL;
|
||||
LEGlyphID *fakeGlyphs = NULL;
|
||||
le_int32 *tempCharIndices = NULL;
|
||||
LEGlyphStorage fakeGlyphStorage;
|
||||
le_int32 outCharCount, outGlyphCount, fakeGlyphCount;
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
|
@ -167,46 +160,36 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o
|
|||
return 0;
|
||||
}
|
||||
|
||||
outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, tempCharIndices, fFeatureTags, success);
|
||||
outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, fakeGlyphStorage, success);
|
||||
|
||||
if (outChars != NULL) {
|
||||
fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fFeatureTags, fakeGlyphs, tempCharIndices, success);
|
||||
fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success);
|
||||
//adjustGlyphs(outChars, 0, outCharCount, rightToLeft, fakeGlyphs, fakeGlyphCount);
|
||||
} else {
|
||||
fakeGlyphCount = glyphProcessing(chars, offset, count, max, rightToLeft, fFeatureTags, fakeGlyphs, tempCharIndices, success);
|
||||
fakeGlyphCount = glyphProcessing(chars, offset, count, max, rightToLeft, fakeGlyphStorage, success);
|
||||
//adjustGlyphs(chars, offset, count, rightToLeft, fakeGlyphs, fakeGlyphCount);
|
||||
}
|
||||
|
||||
outGlyphCount = glyphPostProcessing(fakeGlyphs, tempCharIndices, fakeGlyphCount, glyphs, charIndices, success);
|
||||
|
||||
if (outChars != chars) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
}
|
||||
|
||||
if (fakeGlyphs != glyphs) {
|
||||
LE_DELETE_ARRAY(fakeGlyphs);
|
||||
}
|
||||
|
||||
if (tempCharIndices != charIndices) {
|
||||
LE_DELETE_ARRAY(tempCharIndices);
|
||||
}
|
||||
outGlyphCount = glyphPostProcessing(fakeGlyphStorage, glyphStorage, success);
|
||||
|
||||
return outGlyphCount;
|
||||
}
|
||||
|
||||
// apply GPOS table, if any
|
||||
void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success)
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chars == NULL || glyphs == NULL || positions == NULL || offset < 0 || count < 0) {
|
||||
if (chars == NULL || offset < 0 || count < 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
if (glyphCount > 0 && fGPOSTable != NULL) {
|
||||
GlyphPositionAdjustment *adjustments = new GlyphPositionAdjustment[glyphCount];
|
||||
le_int32 i;
|
||||
|
@ -216,6 +199,9 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
|
|||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Don't need to do this if we allocate
|
||||
// the adjustments array w/ new...
|
||||
for (i = 0; i < glyphCount; i += 1) {
|
||||
adjustments[i].setXPlacement(0);
|
||||
adjustments[i].setYPlacement(0);
|
||||
|
@ -225,8 +211,9 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
|
|||
|
||||
adjustments[i].setBaseOffset(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
fGPOSTable->process(glyphs, adjustments, fFeatureTags, glyphCount, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance, fFeatureOrder);
|
||||
fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance, fFeatureOrder);
|
||||
|
||||
float xAdjust = 0, yAdjust = 0;
|
||||
|
||||
|
@ -249,21 +236,24 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
|
|||
yPlacement += adjustments[base].getYPlacement();
|
||||
}
|
||||
|
||||
positions[i*2] += xAdjust + fFontInstance->xUnitsToPoints(xPlacement);
|
||||
positions[i*2+1] -= yAdjust + fFontInstance->yUnitsToPoints(yPlacement);
|
||||
xPlacement = fFontInstance->xUnitsToPoints(xPlacement);
|
||||
yPlacement = fFontInstance->yUnitsToPoints(yPlacement);
|
||||
glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success);
|
||||
|
||||
xAdjust += fFontInstance->xUnitsToPoints(xAdvance);
|
||||
yAdjust += fFontInstance->yUnitsToPoints(yAdvance);
|
||||
}
|
||||
|
||||
positions[glyphCount*2] += xAdjust;
|
||||
positions[glyphCount*2+1] -= yAdjust;
|
||||
glyphStorage.adjustPosition(glyphCount, xAdjust, -yAdjust, success);
|
||||
|
||||
delete[] adjustments;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Don't know why this is here...
|
||||
LE_DELETE_ARRAY(fFeatureTags);
|
||||
fFeatureTags = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -149,15 +149,6 @@ private:
|
|||
static const char fgClassID;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* An array of pointers to four byte feature tags.
|
||||
* Each pointer points to a list of tags, terminated
|
||||
* by a special empty tag.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
const LETag **fFeatureTags;
|
||||
|
||||
/**
|
||||
* A list of tags in the order in which the features in
|
||||
* the font should be applied, as opposed to using the
|
||||
|
@ -238,7 +229,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode /*chars*/[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/,
|
||||
LEUnicode *&/*outChars*/, le_int32 *&/*charIndices*/, const LETag **&/*featureTags*/, LEErrorCode &success);
|
||||
LEUnicode *&/*outChars*/, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method does character to glyph mapping, and applies the GSUB table. The
|
||||
|
@ -270,7 +261,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
const LETag **&featureTags, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method does any processing necessary to convert "fake"
|
||||
|
@ -297,8 +288,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 glyphPostProcessing(LEGlyphID tempGlyphs[], le_int32 tempCharIndices[], le_int32 tempGlyphCount,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
virtual le_int32 glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method applies the characterProcessing, glyphProcessing and glyphPostProcessing
|
||||
|
@ -322,7 +312,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
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 uses the GPOS table, if there is one, to adjust the glyph positions.
|
||||
|
@ -339,7 +329,7 @@ protected:
|
|||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success);
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method frees the feature tag array so that the
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SegmentArrayProcessor.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -11,6 +10,7 @@
|
|||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc.h"
|
||||
#include "SegmentArrayProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -33,23 +33,25 @@ SegmentArrayProcessor::~SegmentArrayProcessor()
|
|||
{
|
||||
}
|
||||
|
||||
void SegmentArrayProcessor::process(LEGlyphID *glyphs, le_int32 * /*charIndices*/, le_int32 glyphCount)
|
||||
void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
const LookupSegment *segments = segmentArrayLookupTable->segments;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, glyphs[glyph]);
|
||||
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(glyphs[glyph]) - firstGlyph]);
|
||||
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset);
|
||||
TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
|
||||
|
||||
glyphs[glyph] = LE_SET_GLYPH(glyphs[glyph], newGlyph);
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SegmentArrayProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,10 +20,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SegmentArrayProcessor : public NonContextualGlyphSubstitutionProcessor
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyph);
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SegmentArrayProcessor(const MorphSubtableHeader *morphSubtableHeader);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SegmentSingleProcessor.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -11,6 +10,7 @@
|
|||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc.h"
|
||||
#include "SegmentSingleProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -33,18 +33,20 @@ SegmentSingleProcessor::~SegmentSingleProcessor()
|
|||
{
|
||||
}
|
||||
|
||||
void SegmentSingleProcessor::process(LEGlyphID *glyphs, le_int32 * /*charIndices*/, le_int32 glyphCount)
|
||||
void SegmentSingleProcessor::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
const LookupSegment *segments = segmentSingleLookupTable->segments;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, glyphs[glyph]);
|
||||
LEGlyphID thisGlyph = glyphStorage[glyph];
|
||||
const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph);
|
||||
|
||||
if (lookupSegment != NULL) {
|
||||
TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(glyphs[glyph]) + SWAPW(lookupSegment->value);
|
||||
TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value);
|
||||
|
||||
glyphs[glyph] = LE_SET_GLYPH(glyphs[glyph], newGlyph);
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SegmentSingleProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,10 +20,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SegmentSingleProcessor : public NonContextualGlyphSubstitutionProcessor
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyphCount);
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SegmentSingleProcessor(const MorphSubtableHeader *morphSubtableHeader);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SimpleArrayProcessor.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -11,6 +10,7 @@
|
|||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc.h"
|
||||
#include "SimpleArrayProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -33,15 +33,17 @@ SimpleArrayProcessor::~SimpleArrayProcessor()
|
|||
{
|
||||
}
|
||||
|
||||
void SimpleArrayProcessor::process(LEGlyphID *glyphs, le_int32 * /*charIndices*/, le_int32 glyphCount)
|
||||
void SimpleArrayProcessor::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
if (glyphs[glyph] < 0xFFFF) {
|
||||
TTGlyphID newGlyph = SWAPW(simpleArrayLookupTable->valueArray[glyphs[glyph]]);
|
||||
LEGlyphID thisGlyph = glyphStorage[glyph];
|
||||
if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) {
|
||||
TTGlyphID newGlyph = SWAPW(simpleArrayLookupTable->valueArray[LE_GET_GLYPH(thisGlyph)]);
|
||||
|
||||
glyphs[glyph] = LE_SET_GLYPH(glyphs[glyph], newGlyph);
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SimpleArrayProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,10 +20,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SimpleArrayProcessor : public NonContextualGlyphSubstitutionProcessor
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyphCount);
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SimpleArrayProcessor(const MorphSubtableHeader *morphSubtableHeader);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SingleTableProcessor.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -11,6 +10,7 @@
|
|||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc.h"
|
||||
#include "SingleTableProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -33,16 +33,17 @@ SingleTableProcessor::~SingleTableProcessor()
|
|||
{
|
||||
}
|
||||
|
||||
void SingleTableProcessor::process(LEGlyphID *glyphs, le_int32 * /*charIndices*/, le_int32 glyphCount)
|
||||
void SingleTableProcessor::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, glyphs[glyph]);
|
||||
const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(entries, glyphStorage[glyph]);
|
||||
|
||||
if (lookupSingle != NULL) {
|
||||
glyphs[glyph] = SWAPW(lookupSingle->value);
|
||||
glyphStorage[glyph] = SWAPW(lookupSingle->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SingleTableProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,10 +20,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SingleTableProcessor : public NonContextualGlyphSubstitutionProcessor
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyphCount);
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
SingleTableProcessor(const MorphSubtableHeader *morphSubtableHeader);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)StateTableProcessor.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -11,6 +10,7 @@
|
|||
#include "MorphStateTables.h"
|
||||
#include "SubtableProcessor.h"
|
||||
#include "StateTableProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -38,7 +38,7 @@ StateTableProcessor::~StateTableProcessor()
|
|||
{
|
||||
}
|
||||
|
||||
void StateTableProcessor::process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyphCount)
|
||||
void StateTableProcessor::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
// Start at state 0
|
||||
// XXX: How do we know when to start at state 1?
|
||||
|
@ -46,6 +46,7 @@ void StateTableProcessor::process(LEGlyphID *glyphs, le_int32 *charIndices, le_i
|
|||
|
||||
// XXX: reverse?
|
||||
le_int32 currGlyph = 0;
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
beginStateTable();
|
||||
|
||||
|
@ -55,7 +56,7 @@ void StateTableProcessor::process(LEGlyphID *glyphs, le_int32 *charIndices, le_i
|
|||
// XXX: How do we handle EOT vs. EOL?
|
||||
classCode = classCodeEOT;
|
||||
} else {
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphs[currGlyph]);
|
||||
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
|
||||
|
||||
if (glyphCode == 0xFFFF) {
|
||||
classCode = classCodeDEL;
|
||||
|
@ -67,7 +68,7 @@ void StateTableProcessor::process(LEGlyphID *glyphs, le_int32 *charIndices, le_i
|
|||
const EntryTableIndex *stateArray = (const EntryTableIndex *) ((char *) &stateTableHeader->stHeader + currentState);
|
||||
EntryTableIndex entryTableIndex = stateArray[(le_uint8)classCode];
|
||||
|
||||
currentState = processStateEntry(glyphs, charIndices, currGlyph, glyphCount, entryTableIndex);
|
||||
currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
|
||||
}
|
||||
|
||||
endStateTable();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)StateTableProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -20,15 +19,16 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class StateTableProcessor : public SubtableProcessor
|
||||
{
|
||||
public:
|
||||
void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyph);
|
||||
void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
virtual void beginStateTable() = 0;
|
||||
|
||||
virtual ByteOffset processStateEntry(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 &currGlyph,
|
||||
le_int32 glyphCount, EntryTableIndex index) = 0;
|
||||
virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) = 0;
|
||||
|
||||
virtual void endStateTable() = 0;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)SubtableProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -18,9 +17,11 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class SubtableProcessor : public UMemory {
|
||||
public:
|
||||
virtual void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyph) = 0;
|
||||
virtual void process(LEGlyphStorage &glyphStorage) = 0;
|
||||
virtual ~SubtableProcessor();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
/*
|
||||
* @(#)ThaiLayoutEngine.cpp 1.2 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -10,6 +9,7 @@
|
|||
#include "LayoutEngine.h"
|
||||
#include "ThaiLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "ThaiShaping.h"
|
||||
|
||||
|
@ -51,7 +51,7 @@ ThaiLayoutEngine::~ThaiLayoutEngine()
|
|||
// Output: glyphs, char indices
|
||||
// Returns: the glyph count
|
||||
// NOTE: this assumes that ThaiShaping::compose will allocate the outChars array...
|
||||
le_int32 ThaiLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
|
||||
le_int32 ThaiLayoutEngine::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;
|
||||
|
@ -74,19 +74,20 @@ le_int32 ThaiLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offse
|
|||
return 0;
|
||||
}
|
||||
|
||||
charIndices = LE_NEW_ARRAY(le_int32, count * 2);
|
||||
glyphStorage.allocateGlyphArray(count * 2, FALSE, success);
|
||||
|
||||
if (charIndices == NULL) {
|
||||
if (LE_FAILURE(success)) {
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphCount = ThaiShaping::compose(chars, offset, count, fGlyphSet, fErrorChar, outChars, charIndices);
|
||||
mapCharsToGlyphs(outChars, 0, glyphCount, FALSE, FALSE, glyphs, charIndices, success);
|
||||
glyphCount = ThaiShaping::compose(chars, offset, count, fGlyphSet, fErrorChar, outChars, glyphStorage);
|
||||
mapCharsToGlyphs(outChars, 0, glyphCount, FALSE, FALSE, glyphStorage, success);
|
||||
|
||||
LE_DELETE_ARRAY(outChars);
|
||||
|
||||
glyphStorage.adoptGlyphCount(glyphCount);
|
||||
return glyphCount;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
/*
|
||||
* @(#)ThaiLayoutEngine.h 1.3 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -17,6 +16,8 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
/**
|
||||
* This class implements layout for the Thai script, using the ThaiShapingClass.
|
||||
* All existing Thai fonts use an encoding which assigns character codes to all
|
||||
|
@ -112,7 +113,7 @@ protected:
|
|||
* @internal
|
||||
*/
|
||||
virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* @(#)ThaiShaping.cpp 1.13 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
#include "OpenTypeTables.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "ThaiShaping.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -143,36 +143,38 @@ LEUnicode ThaiShaping::noDescenderCOD(LEUnicode cod, le_uint8 glyphSet)
|
|||
}
|
||||
|
||||
le_uint8 ThaiShaping::doTransition (StateTransition transition, LEUnicode currChar, le_int32 inputIndex, le_uint8 glyphSet,
|
||||
LEUnicode errorChar, LEUnicode *outputBuffer, le_int32 *charIndices, le_int32 &outputIndex)
|
||||
LEUnicode errorChar, LEUnicode *outputBuffer, LEGlyphStorage &glyphStorage, le_int32 &outputIndex)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
switch (transition.action) {
|
||||
case tA:
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = currChar;
|
||||
break;
|
||||
|
||||
case tC:
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = currChar;
|
||||
break;
|
||||
|
||||
case tD:
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = leftAboveVowel(currChar, glyphSet);
|
||||
break;
|
||||
|
||||
case tE:
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = lowerRightTone(currChar, glyphSet);
|
||||
break;
|
||||
|
||||
case tF:
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = lowerLeftTone(currChar, glyphSet);
|
||||
break;
|
||||
|
||||
case tG:
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = upperLeftTone(currChar, glyphSet);
|
||||
break;
|
||||
|
||||
|
@ -184,38 +186,38 @@ le_uint8 ThaiShaping::doTransition (StateTransition transition, LEUnicode currCh
|
|||
if (cod != coa) {
|
||||
outputBuffer[outputIndex - 1] = coa;
|
||||
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = currChar;
|
||||
break;
|
||||
}
|
||||
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = lowerBelowVowel(currChar, glyphSet);
|
||||
break;
|
||||
}
|
||||
|
||||
case tR:
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = errorChar;
|
||||
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = currChar;
|
||||
break;
|
||||
|
||||
case tS:
|
||||
if (currChar == CH_SARA_AM) {
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = errorChar;
|
||||
}
|
||||
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = currChar;
|
||||
break;
|
||||
|
||||
default:
|
||||
// FIXME: if we get here, there's an error
|
||||
// in the state table!
|
||||
charIndices[outputIndex] = inputIndex;
|
||||
glyphStorage.setCharIndex(outputIndex, inputIndex, success);
|
||||
outputBuffer[outputIndex++] = currChar;
|
||||
break;
|
||||
}
|
||||
|
@ -224,14 +226,14 @@ le_uint8 ThaiShaping::doTransition (StateTransition transition, LEUnicode currCh
|
|||
}
|
||||
|
||||
le_uint8 ThaiShaping::getNextState(LEUnicode ch, le_uint8 prevState, le_int32 inputIndex, le_uint8 glyphSet, LEUnicode errorChar,
|
||||
le_uint8 &charClass, LEUnicode *output, le_int32 *charIndices, le_int32 &outputIndex)
|
||||
le_uint8 &charClass, LEUnicode *output, LEGlyphStorage &glyphStorage, le_int32 &outputIndex)
|
||||
{
|
||||
StateTransition transition;
|
||||
|
||||
charClass = getCharClass(ch);
|
||||
transition = getTransition(prevState, charClass);
|
||||
|
||||
return doTransition(transition, ch, inputIndex, glyphSet, errorChar, output, charIndices, outputIndex);
|
||||
return doTransition(transition, ch, inputIndex, glyphSet, errorChar, output, glyphStorage, outputIndex);
|
||||
}
|
||||
|
||||
le_bool ThaiShaping::isLegalHere(LEUnicode ch, le_uint8 prevState)
|
||||
|
@ -261,7 +263,7 @@ le_bool ThaiShaping::isLegalHere(LEUnicode ch, le_uint8 prevState)
|
|||
}
|
||||
|
||||
le_int32 ThaiShaping::compose(const LEUnicode *input, le_int32 offset, le_int32 charCount, le_uint8 glyphSet,
|
||||
LEUnicode errorChar, LEUnicode *output, le_int32 *charIndices)
|
||||
LEUnicode errorChar, LEUnicode *output, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
le_uint8 state = 0;
|
||||
le_int32 inputIndex;
|
||||
|
@ -278,19 +280,19 @@ le_int32 ThaiShaping::compose(const LEUnicode *input, le_int32 offset, le_int32
|
|||
if (ch == CH_SARA_AM && isLegalHere(ch, state)) {
|
||||
outputIndex = conOutput;
|
||||
state = getNextState(CH_NIKHAHIT, conState, inputIndex, glyphSet, errorChar, charClass,
|
||||
output, charIndices, outputIndex);
|
||||
output, glyphStorage, outputIndex);
|
||||
|
||||
for (int j = conInput + 1; j < inputIndex; j += 1) {
|
||||
ch = input[j + offset];
|
||||
state = getNextState(ch, state, j, glyphSet, errorChar, charClass,
|
||||
output, charIndices, outputIndex);
|
||||
output, glyphStorage, outputIndex);
|
||||
}
|
||||
|
||||
ch = CH_SARA_AA;
|
||||
}
|
||||
|
||||
state = getNextState(ch, state, inputIndex, glyphSet, errorChar, charClass,
|
||||
output, charIndices, outputIndex);
|
||||
output, glyphStorage, outputIndex);
|
||||
|
||||
if (charClass >= CON && charClass <= COD) {
|
||||
conState = state;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)ThaiShaping.h 1.9 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -19,6 +18,8 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class ThaiShaping /* not : public UObject because all methods are static */ {
|
||||
public:
|
||||
|
||||
|
@ -67,7 +68,7 @@ public:
|
|||
};
|
||||
|
||||
static le_int32 compose(const LEUnicode *input, le_int32 offset, le_int32 charCount, le_uint8 glyphSet,
|
||||
LEUnicode errorChar, LEUnicode *output, le_int32 *charIndices);
|
||||
LEUnicode errorChar, LEUnicode *output, LEGlyphStorage &glyphStorage);
|
||||
|
||||
private:
|
||||
// forbid instantiation
|
||||
|
@ -78,10 +79,10 @@ private:
|
|||
|
||||
static StateTransition getTransition(le_uint8 state, le_uint8 currClass);
|
||||
static le_uint8 doTransition(StateTransition transition, LEUnicode currChar, le_int32 inputIndex, le_uint8 glyphSet,
|
||||
LEUnicode errorChar, LEUnicode *outputBuffer, le_int32 *charIndices, le_int32 &outputIndex);
|
||||
LEUnicode errorChar, LEUnicode *outputBuffer, LEGlyphStorage &glyphStorage, le_int32 &outputIndex);
|
||||
|
||||
static le_uint8 getNextState(LEUnicode ch, le_uint8 state, le_int32 inputIndex, le_uint8 glyphSet, LEUnicode errorChar,
|
||||
le_uint8 &charClass, LEUnicode *output, le_int32 *charIndices, le_int32 &outputIndex);
|
||||
le_uint8 &charClass, LEUnicode *output, LEGlyphStorage &glyphStorage, le_int32 &outputIndex);
|
||||
|
||||
static le_bool isLegalHere(LEUnicode ch, le_uint8 prevState);
|
||||
static le_uint8 getCharClass(LEUnicode ch);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)TrimmedArrayProcessor.cpp 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -11,6 +10,7 @@
|
|||
#include "NonContextualGlyphSubst.h"
|
||||
#include "NonContextualGlyphSubstProc.h"
|
||||
#include "TrimmedArrayProcessor.h"
|
||||
#include "LEGlyphStorage.h"
|
||||
#include "LESwaps.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -35,17 +35,19 @@ TrimmedArrayProcessor::~TrimmedArrayProcessor()
|
|||
{
|
||||
}
|
||||
|
||||
void TrimmedArrayProcessor::process(LEGlyphID *glyphs, le_int32 * /*charIndices*/, le_int32 glyphCount)
|
||||
void TrimmedArrayProcessor::process(LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
le_int32 glyph;
|
||||
|
||||
for (glyph = 0; glyph < glyphCount; glyph += 1) {
|
||||
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphs[glyph]);
|
||||
LEGlyphID thisGlyph = glyphStorage[glyph];
|
||||
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph);
|
||||
|
||||
if ((ttGlyph > firstGlyph) && (ttGlyph < lastGlyph)) {
|
||||
TTGlyphID newGlyph = SWAPW(trimmedArrayLookupTable->valueArray[ttGlyph - firstGlyph]);
|
||||
|
||||
glyphs[glyph] = LE_SET_GLYPH(glyphs[glyph], newGlyph);
|
||||
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* @(#)TrimmedArrayProcessor.h 1.6 00/03/15
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -21,10 +20,12 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage;
|
||||
|
||||
class TrimmedArrayProcessor : public NonContextualGlyphSubstitutionProcessor
|
||||
{
|
||||
public:
|
||||
virtual void process(LEGlyphID *glyphs, le_int32 *charIndices, le_int32 glyphCount);
|
||||
virtual void process(LEGlyphStorage &glyphStorage);
|
||||
|
||||
TrimmedArrayProcessor(const MorphSubtableHeader *morphSubtableHeader);
|
||||
|
||||
|
|
|
@ -241,6 +241,12 @@
|
|||
<File
|
||||
RelativePath=".\LEFontInstance.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LEGlyphStorage.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LEInsertionList.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LigatureSubstProc.cpp">
|
||||
</File>
|
||||
|
@ -503,6 +509,12 @@
|
|||
Outputs="..\..\include\layout\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LEGlyphStorage.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LEInsertionList.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LELanguages.h">
|
||||
<FileConfiguration
|
||||
|
|
Loading…
Add table
Reference in a new issue