ICU-2259 Add LEGlyphStorage, LEInsertionList.

X-SVN-Rev: 14933
This commit is contained in:
Eric Mader 2004-04-12 18:51:31 +00:00
parent 515bf0c731
commit 9672384ada
59 changed files with 1718 additions and 1209 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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();

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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;
};

View file

@ -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

View file

@ -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;
};

View file

@ -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);
}
}

View file

@ -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[];

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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();

View file

@ -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;
}

View file

@ -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();

View file

@ -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;
}
}
}

View file

@ -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

View 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

View 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

View 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

View 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

View file

@ -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)

View file

@ -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

View file

@ -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));

View file

@ -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();

View file

@ -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) {

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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:

View file

@ -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;
}

View file

@ -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:

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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