ICU-2257 implement glyph insertion.

X-SVN-Rev: 13191
This commit is contained in:
Eric Mader 2003-09-24 21:05:40 +00:00
parent 6746ee1158
commit 8fead94be5
15 changed files with 369 additions and 82 deletions

View File

@ -15,13 +15,79 @@
U_NAMESPACE_BEGIN
GlyphIterator::GlyphIterator(LEGlyphID *theGlyphs, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_int32 theGlyphCount,
le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, const LETag *theGlyphTags[],
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,
const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
: direction(1), position(-1), nextLimit(theGlyphCount), prevLimit(-1),
cursiveFirstPosition(-1), cursiveLastPosition(-1), cursiveBaselineAdjustment(0),
glyphs(theGlyphs), glyphPositionAdjustments(theGlyphPositionAdjustments), lookupFlags(theLookupFlags),
featureTag(theFeatureTag), glyphTags(theGlyphTags),
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)
@ -37,6 +103,8 @@ GlyphIterator::GlyphIterator(LEGlyphID *theGlyphs, GlyphPositionAdjustment *theG
nextLimit = -1;
prevLimit = theGlyphCount;
}
insertionList = new InsertionList(rightToLeft);
}
GlyphIterator::GlyphIterator(GlyphIterator &that)
@ -49,10 +117,19 @@ GlyphIterator::GlyphIterator(GlyphIterator &that)
cursiveFirstPosition = that.cursiveFirstPosition;
cursiveLastPosition = that.cursiveLastPosition;
glyphs = that.glyphs;
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;
@ -68,10 +145,19 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag)
cursiveFirstPosition = that.cursiveFirstPosition;
cursiveLastPosition = that.cursiveLastPosition;
glyphs = that.glyphs;
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;
@ -88,10 +174,19 @@ 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;
@ -103,6 +198,92 @@ GlyphIterator::GlyphIterator()
GlyphIterator::~GlyphIterator()
{
if (ownInsertionList) {
delete insertionList;
}
}
void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag)
{
position = prevLimit;
featureTag = newFeatureTag;
lookupFlags = newLookupFlags;
}
LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count)
{
return insertionList->insert(position, count);
}
le_int32 GlyphIterator::applyInsertions()
{
le_int32 growAmount = insertionList->getGrowAmount();
if (growAmount == 0) {
return glyphCount;
}
le_int32 newGlyphCount = glyphCount + growAmount;
le_int32 dest = newGlyphCount - 1;
*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();
if (direction < 0) {
prevLimit = newGlyphCount;
} else {
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;
}
le_int32 GlyphIterator::getCurrStreamPosition() const

View File

@ -20,10 +20,66 @@
U_NAMESPACE_BEGIN
class GlyphIterator : public UMemory {
struct InsertionRecord
{
InsertionRecord *next;
le_int32 position;
le_int32 count;
LEGlyphID glyphs[ANY_NUMBER];
};
class InsertionCallback
{
public:
GlyphIterator(LEGlyphID *theGlyphs, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_int32 theGlyphCount,
le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, const LETag *theGlyphTags[],
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.
*
* @draft ICU 2.2
*/
virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 2.2
*/
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,
const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader);
GlyphIterator(GlyphIterator &that);
@ -34,6 +90,8 @@ public:
~GlyphIterator();
void reset(le_uint16 newLookupFlags, LETag newFeatureTag);
le_bool next(le_uint32 delta = 1);
le_bool prev(le_uint32 delta = 1);
le_bool findFeatureTag();
@ -71,6 +129,12 @@ public:
void adjustCursiveLastGlyphPositionAdjustment(float xPlacmentAdjust, float yPlacementAdjust,
float xAdvanceAdjust, float yAdvanceAdjust);
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;
@ -86,10 +150,19 @@ private:
le_int32 cursiveLastPosition;
float cursiveBaselineAdjustment;
LEPoint cursiveLastExitPoint;
LEGlyphID **glyphsRef;
LEGlyphID *glyphs;
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

@ -23,8 +23,9 @@ void GlyphPositioningTableHeader::process(LEGlyphID *glyphs, GlyphPositionAdjust
const LEFontInstance *fontInstance, const LETag *featureOrder) const
{
GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureOrder);
le_int32 *charIndices = NULL;
processor.process(glyphs, glyphPositionAdjustments, glyphTags, glyphCount, rightToLeft,
processor.process(glyphs, glyphPositionAdjustments, glyphTags, charIndices, glyphCount, rightToLeft,
glyphDefinitionTableHeader, fontInstance);
}

View File

@ -18,14 +18,14 @@
U_NAMESPACE_BEGIN
void GlyphSubstitutionTableHeader::process(LEGlyphID *glyphs, const LETag **glyphTags, le_int32 glyphCount,
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphID *&glyphs, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEGlyphFilter *filter, const LETag *featureOrder) const
{
GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureOrder);
processor.process(glyphs, NULL, glyphTags, glyphCount, rightToLeft, glyphDefinitionTableHeader, NULL);
return processor.process(glyphs, NULL, glyphTags, charIndices, glyphCount, rightToLeft, glyphDefinitionTableHeader, NULL);
}
le_bool GlyphSubstitutionTableHeader::coversScript(LETag scriptTag) const

View File

@ -29,7 +29,7 @@ struct GlyphSubstitutionTableHeader
Offset featureListOffset;
Offset lookupListOffset;
void process(LEGlyphID *glyphs, const LETag **glyphTags, le_int32 glyphCount,
le_int32 process(LEGlyphID *&glyphs, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
le_bool rightToLeft, LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEGlyphFilter *filter = NULL, const LETag *featureOrder = NULL) const;

View File

@ -48,14 +48,18 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp
return 1;
}
void LookupProcessor::process(LEGlyphID *glyphs, GlyphPositionAdjustment *glyphPositionAdjustments, const LETag **glyphTags, le_int32 glyphCount,
le_int32 LookupProcessor::process(LEGlyphID *&glyphs, GlyphPositionAdjustment *glyphPositionAdjustments, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEFontInstance *fontInstance) const
{
if (lookupSelectArray == NULL) {
return;
return glyphCount;
}
GlyphIterator glyphIterator(glyphs, glyphPositionAdjustments, charIndices, glyphCount,
rightToLeft, 0, 0, glyphTags, glyphDefinitionTableHeader);
le_int32 newGlyphCount = glyphCount;
for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
le_uint16 lookup = lookupOrderArray[order];
LETag selectTag = lookupSelectArray[lookup];
@ -63,9 +67,8 @@ void LookupProcessor::process(LEGlyphID *glyphs, GlyphPositionAdjustment *glyphP
if (selectTag != notSelected) {
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
GlyphIterator glyphIterator(glyphs, glyphPositionAdjustments, glyphCount,
rightToLeft, lookupFlags, selectTag, glyphTags,
glyphDefinitionTableHeader);
glyphIterator.reset(lookupFlags, selectTag);
while (glyphIterator.findFeatureTag()) {
le_uint32 delta = 1;
@ -74,8 +77,12 @@ void LookupProcessor::process(LEGlyphID *glyphs, GlyphPositionAdjustment *glyphP
delta = applyLookupTable(lookupTable, &glyphIterator, fontInstance);
}
}
newGlyphCount = glyphIterator.applyInsertions();
}
}
return newGlyphCount;
}
le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator,

View File

@ -29,7 +29,7 @@ public:
static const LETag notSelected;
static const LETag defaultFeature;
void process(LEGlyphID *glyphs, GlyphPositionAdjustment *glyphPositionAdjustments, const LETag **glyphTags, le_int32 glyphCount,
le_int32 process(LEGlyphID *&glyphs, GlyphPositionAdjustment *glyphPositionAdjustments, const LETag **&glyphTags, le_int32 *&charIndices, le_int32 glyphCount,
le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance) const;
le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;

View File

@ -2,8 +2,8 @@
* (C) Copyright IBM Corp. 2002-2003 - All Rights Reserved
*
* $Source: /xsrl/Nsvn/icu/icu/source/layout/MPreFixups.h,v $
* $Date: 2003/06/03 20:58:22 $
* $Revision: 1.3 $
* $Date: 2003/09/24 21:05:13 $
* $Revision: 1.4 $
*
*/
@ -30,7 +30,7 @@ public:
void add(le_int32 baseIndex, le_int32 mpreIndex);
void apply(LEGlyphID *glyphs, le_int32 *charIndicies);
void apply(LEGlyphID *glyphs, le_int32 *charIndices);
private:
FixupData *fFixupData;

View File

@ -29,7 +29,7 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
if (glyphCount == 0) {
glyphIterator->setCurrGlyphID(0xFFFF);
return 1;
} else if (glyphCount >= 1) {
} else if (glyphCount == 1) {
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) {
@ -38,8 +38,21 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
return 1;
} else {
// Can't do this 'till there's a way to
// grow the glyph array...
LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount);
le_int32 insert = 0, direction = 1;
if (glyphIterator->isRightToLeft()) {
insert = glyphCount - 1;
direction = -1;
}
for (le_int32 i = 0; i < glyphCount; i += 1) {
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
newGlyphs[insert] = LE_SET_GLYPH(glyph, substitute);
insert += direction;
}
return 1;
}
}

View File

@ -109,8 +109,8 @@ 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)
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)
{
if (LE_FAILURE(success)) {
return 0;
@ -128,7 +128,7 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32
}
if (fGSUBTable != NULL) {
fGSUBTable->process(glyphs, featureTags, count, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureOrder);
count = fGSUBTable->process(glyphs, featureTags, charIndices, count, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureOrder);
}
return count;

View File

@ -270,7 +270,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);
const LETag **&featureTags, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);
/**
* This method does any processing necessary to convert "fake"

View File

@ -143,36 +143,36 @@ 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 *charIndicies, le_int32 &outputIndex)
LEUnicode errorChar, LEUnicode *outputBuffer, le_int32 *charIndices, le_int32 &outputIndex)
{
switch (transition.action) {
case tA:
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = currChar;
break;
case tC:
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = currChar;
break;
case tD:
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = leftAboveVowel(currChar, glyphSet);
break;
case tE:
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = lowerRightTone(currChar, glyphSet);
break;
case tF:
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = lowerLeftTone(currChar, glyphSet);
break;
case tG:
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = upperLeftTone(currChar, glyphSet);
break;
@ -184,38 +184,38 @@ le_uint8 ThaiShaping::doTransition (StateTransition transition, LEUnicode currCh
if (cod != coa) {
outputBuffer[outputIndex - 1] = coa;
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = currChar;
break;
}
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = lowerBelowVowel(currChar, glyphSet);
break;
}
case tR:
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = errorChar;
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = currChar;
break;
case tS:
if (currChar == CH_SARA_AM) {
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = errorChar;
}
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = currChar;
break;
default:
// FIXME: if we get here, there's an error
// in the state table!
charIndicies[outputIndex] = inputIndex;
charIndices[outputIndex] = inputIndex;
outputBuffer[outputIndex++] = currChar;
break;
}
@ -224,14 +224,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 *charIndicies, le_int32 &outputIndex)
le_uint8 &charClass, LEUnicode *output, le_int32 *charIndices, le_int32 &outputIndex)
{
StateTransition transition;
charClass = getCharClass(ch);
transition = getTransition(prevState, charClass);
return doTransition(transition, ch, inputIndex, glyphSet, errorChar, output, charIndicies, outputIndex);
return doTransition(transition, ch, inputIndex, glyphSet, errorChar, output, charIndices, outputIndex);
}
le_bool ThaiShaping::isLegalHere(LEUnicode ch, le_uint8 prevState)
@ -261,7 +261,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 *charIndicies)
LEUnicode errorChar, LEUnicode *output, le_int32 *charIndices)
{
le_uint8 state = 0;
le_int32 inputIndex;
@ -278,19 +278,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, charIndicies, outputIndex);
output, charIndices, outputIndex);
for (int j = conInput + 1; j < inputIndex; j += 1) {
ch = input[j + offset];
state = getNextState(ch, state, j, glyphSet, errorChar, charClass,
output, charIndicies, outputIndex);
output, charIndices, outputIndex);
}
ch = CH_SARA_AA;
}
state = getNextState(ch, state, inputIndex, glyphSet, errorChar, charClass,
output, charIndicies, outputIndex);
output, charIndices, outputIndex);
if (charClass >= CON && charClass <= COD) {
conState = state;

View File

@ -67,7 +67,7 @@ public:
};
static le_int32 compose(const LEUnicode *input, le_int32 offset, le_int32 charCount, le_uint8 glyphSet,
LEUnicode errorChar, LEUnicode *output, le_int32 *charIndicies);
LEUnicode errorChar, LEUnicode *output, le_int32 *charIndices);
private:
// forbid instantiation
@ -78,10 +78,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 *charIndicies, le_int32 &outputIndex);
LEUnicode errorChar, LEUnicode *outputBuffer, le_int32 *charIndices, 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 *charIndicies, le_int32 &outputIndex);
le_uint8 &charClass, LEUnicode *output, le_int32 *charIndices, le_int32 &outputIndex);
static le_bool isLegalHere(LEUnicode ch, le_uint8 prevState);
static le_uint8 getCharClass(LEUnicode ch);

View File

@ -221,7 +221,7 @@ ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
fFontRuns(NULL), fLevelRuns(levelRuns), fScriptRuns(scriptRuns), fLocaleRuns(localeRuns),
fVertical(vertical), fClientLevels(true), fClientScripts(true), fClientLocales(true), fEmbeddingLevels(NULL),
fAscent(0), fDescent(0), fLeading(0),
fGlyphToCharMap(NULL), fCharToGlyphMap(NULL), fGlyphWidths(NULL), fGlyphCount(0),
fGlyphToCharMap(NULL), fCharToMinGlyphMap(NULL), fCharToMaxGlyphMap(NULL), fGlyphWidths(NULL), fGlyphCount(0),
fParaBidi(NULL), fLineBidi(NULL),
fStyleRunLimits(NULL), fStyleIndices(NULL), fStyleRunCount(0),
fBreakIterator(NULL), fLineStart(-1), fLineEnd(0),
@ -287,17 +287,19 @@ ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
//
// For each layout get the positions and convert them into glyph widths, in
// logical order. Get the glyph-to-char mapping, offset by starting index in the
// width array, and swap it into logical order. Then fill in the char-to-glyph map
// from this. (charToGlyph[glyphToChar[i]] = i)
fGlyphWidths = LE_NEW_ARRAY(float, fGlyphCount);
fGlyphToCharMap = LE_NEW_ARRAY(le_int32, fGlyphCount + 1);
fCharToGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1);
// character array. Swap the glyph width and glyph-to-char arrays into logical order.
// Finally, fill in the char-to-glyph mappings.
fGlyphWidths = LE_NEW_ARRAY(float, fGlyphCount);
fGlyphToCharMap = LE_NEW_ARRAY(le_int32, fGlyphCount + 1);
fCharToMinGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1);
fCharToMaxGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1);
le_int32 glyph;
for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) {
LayoutEngine *engine = fStyleRunInfo[run].engine;
le_int32 glyphCount = fStyleRunInfo[run].glyphCount;
le_int32 glyphBase = fStyleRunInfo[run].glyphBase;
le_int32 glyph;
fStyleRunInfo[run].glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount);
fStyleRunInfo[run].positions = LE_NEW_ARRAY(float, glyphCount * 2 + 2);
@ -308,23 +310,11 @@ ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
for (glyph = 0; glyph < glyphCount; glyph += 1) {
fGlyphWidths[glyphBase + glyph] = fStyleRunInfo[run].positions[glyph * 2 + 2] - fStyleRunInfo[run].positions[glyph * 2];
fCharToGlyphMap[fGlyphToCharMap[glyphBase + glyph]] = glyphBase + glyph;
}
if ((fStyleRunInfo[run].level & 1) != 0) {
LXUtilities::reverse(&fGlyphWidths[glyphBase], glyphCount);
LXUtilities::reverse(&fGlyphToCharMap[glyphBase], glyphCount);
// LXUtilities::reverse(&fCharToGlyphMap[runStart], fStyleRunLimits[run] - runStart);
// convert from visual to logical glyph indices
for (glyph = glyphBase; glyph < glyphBase + glyphCount; glyph += 1) {
le_int32 ch = fGlyphToCharMap[glyph];
le_int32 lastGlyph = glyphBase + glyphCount - 1;
// both lastGlyph and fCharToGlyphMap[ch] are biased by
// glyphBase, so subtracting them will remove the bias.
fCharToGlyphMap[ch] = lastGlyph - fCharToGlyphMap[ch] + glyphBase;
}
}
runStart = fStyleRunLimits[run];
@ -333,8 +323,23 @@ ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
fStyleRunInfo[run].engine = NULL;
}
fCharToGlyphMap[fCharCount] = fGlyphCount;
fGlyphToCharMap[fGlyphCount] = fCharCount;
for (glyph = fGlyphCount - 1; glyph >= 0; glyph -= 1) {
le_int32 ch = fGlyphToCharMap[glyph];
fCharToMinGlyphMap[ch] = glyph;
}
fCharToMinGlyphMap[fCharCount] = fGlyphCount;
for (glyph = 0; glyph < fGlyphCount; glyph += 1) {
le_int32 ch = fGlyphToCharMap[glyph];
fCharToMaxGlyphMap[ch] = glyph;
}
fCharToMaxGlyphMap[fCharCount] = fGlyphCount;
}
ParagraphLayout::~ParagraphLayout()
@ -372,11 +377,16 @@ ParagraphLayout::~ParagraphLayout()
fGlyphToCharMap = NULL;
}
if (fCharToGlyphMap != NULL) {
LE_DELETE_ARRAY(fCharToGlyphMap);
fCharToGlyphMap = NULL;
if (fCharToMinGlyphMap != NULL) {
LE_DELETE_ARRAY(fCharToMinGlyphMap);
fCharToMinGlyphMap = NULL;
}
if (fCharToMaxGlyphMap != NULL) {
LE_DELETE_ARRAY(fCharToMaxGlyphMap);
fCharToMaxGlyphMap = NULL;
}
if (fGlyphWidths != NULL) {
LE_DELETE_ARRAY(fGlyphWidths);
fGlyphWidths = NULL;
@ -472,7 +482,7 @@ ParagraphLayout::Line *ParagraphLayout::nextLine(float width)
fLineStart = fLineEnd;
if (width > 0) {
le_int32 glyph = fCharToGlyphMap[fLineStart];
le_int32 glyph = fCharToMinGlyphMap[fLineStart];
float widthSoFar = 0;
while (glyph < fGlyphCount && widthSoFar + fGlyphWidths[glyph] <= width) {
@ -810,14 +820,15 @@ void ParagraphLayout::appendRun(ParagraphLayout::Line *line, le_int32 run, le_in
le_int32 ch;
for (ch = firstChar; ch <= lastChar; ch += 1) {
le_int32 glyph = fCharToGlyphMap[ch];
le_int32 minGlyph = fCharToMinGlyphMap[ch];
le_int32 maxGlyph = fCharToMaxGlyphMap[ch];
if (glyph < leftGlyph) {
leftGlyph = glyph;
if (minGlyph < leftGlyph) {
leftGlyph = minGlyph;
}
if (glyph > rightGlyph) {
rightGlyph = glyph;
if (maxGlyph > rightGlyph) {
rightGlyph = maxGlyph;
}
}

View File

@ -580,7 +580,8 @@ private:
le_int32 fLeading;
le_int32 *fGlyphToCharMap;
le_int32 *fCharToGlyphMap;
le_int32 *fCharToMinGlyphMap;
le_int32 *fCharToMaxGlyphMap;
float *fGlyphWidths;
le_int32 fGlyphCount;