ICU-2259 Changes for canonical equivalence porcessing.
X-SVN-Rev: 15130
This commit is contained in:
parent
4c9e98ac06
commit
6884636181
@ -13,6 +13,7 @@
|
||||
#include "OpenTypeLayoutEngine.h"
|
||||
#include "ArabicLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "CharSubstitutionFilter.h"
|
||||
|
||||
#include "GlyphSubstitutionTables.h"
|
||||
#include "GlyphDefinitionTables.h"
|
||||
@ -25,33 +26,6 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
|
||||
{
|
||||
private:
|
||||
const LEFontInstance *fFontInstance;
|
||||
|
||||
CharSubstitutionFilter(const CharSubstitutionFilter &other); // forbid copying of this class
|
||||
CharSubstitutionFilter &operator=(const CharSubstitutionFilter &other); // forbid copying of this class
|
||||
|
||||
public:
|
||||
CharSubstitutionFilter(const LEFontInstance *fontInstance);
|
||||
~CharSubstitutionFilter();
|
||||
|
||||
le_bool accept(LEGlyphID glyph) const;
|
||||
};
|
||||
|
||||
CharSubstitutionFilter::CharSubstitutionFilter(const LEFontInstance *fontInstance)
|
||||
: fFontInstance(fontInstance)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
CharSubstitutionFilter::~CharSubstitutionFilter()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
||||
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
|
||||
{
|
||||
return fFontInstance->canDisplay((LEUnicode) glyph);
|
||||
|
@ -98,7 +98,7 @@ protected:
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - TRUE if the characters are in a right to left directional run
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
*
|
||||
* Output parameters:
|
||||
* @param outChars - the output character arrayt
|
||||
@ -122,7 +122,7 @@ protected:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param reverse - TRUE if the glyphs in the glyph array have been reordered
|
||||
* @param reverse - <code>TRUE</code> if the glyphs in the glyph array have been reordered
|
||||
* @param glyphs - the input glyph array
|
||||
* @param glyphCount - the number of glyphs
|
||||
* @param positions - the position array, will be updated as needed
|
||||
@ -132,7 +132,7 @@ protected:
|
||||
*/
|
||||
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);
|
||||
// static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
private:
|
||||
|
||||
@ -210,12 +210,10 @@ protected:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to be mapped
|
||||
* @param count - the number of characters to be mapped
|
||||
* @param reverse - if TRUE, the output will be in reverse order
|
||||
* @param mirror - if TRUE, do character mirroring
|
||||
* @param reverse - if <code>TRUE</code>, the output will be in reverse order
|
||||
* @param mirror - if <code>TRUE</code>, do character mirroring
|
||||
* @param glyphStorage - the glyph storage object. Glyph and char index arrays will be updated.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param glyphs - the glyph array
|
||||
* @param charIndices - the character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
@ -231,10 +229,8 @@ protected:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param reverse - TRUE if the glyphs in the glyph array have been reordered
|
||||
* @param glyphs - the input glyph array
|
||||
* @param glyphCount - the number of glyphs
|
||||
* @param positions - the position array, will be updated as needed
|
||||
* @param reverse - <code>TRUE</code> if the glyphs in the glyph array have been reordered
|
||||
* @param glyphStorage - the glyph storage object. The glyph positions will be updated as needed.
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
|
1097
icu4c/source/layout/CanonData.cpp
Normal file
1097
icu4c/source/layout/CanonData.cpp
Normal file
File diff suppressed because it is too large
Load Diff
21
icu4c/source/layout/CanonShaping.h
Normal file
21
icu4c/source/layout/CanonShaping.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CANONSHAPING_H
|
||||
#define __CANONSHAPING_H
|
||||
|
||||
#include "LETypes.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class CanonShaping /* not : public UObject because all members are static */
|
||||
{
|
||||
public:
|
||||
static const le_uint8 glyphSubstitutionTable[];
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
81
icu4c/source/layout/CharSubstitutionFilter.h
Normal file
81
icu4c/source/layout/CharSubstitutionFilter.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CHARSUBSTITUTIONFILTER_H
|
||||
#define __CHARSUBSTITUTIONFILTER_H
|
||||
|
||||
#include "LETypes.h"
|
||||
#include "LEGlyphFilter.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEFontInstance;
|
||||
|
||||
/**
|
||||
* This filter is used by character-based GSUB processors. It
|
||||
* accepts only those characters which the given font can display.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Holds the font which is used to test the characters.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
const LEFontInstance *fFontInstance;
|
||||
|
||||
/**
|
||||
* The copy constructor. Not allowed!
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
CharSubstitutionFilter(const CharSubstitutionFilter &other); // forbid copying of this class
|
||||
|
||||
/**
|
||||
* The replacement operator. Not allowed!
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
CharSubstitutionFilter &operator=(const CharSubstitutionFilter &other); // forbid copying of this class
|
||||
|
||||
public:
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param fontInstance - the font to use to test the characters.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
CharSubstitutionFilter(const LEFontInstance *fontInstance);
|
||||
|
||||
/**
|
||||
* The destructor.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
~CharSubstitutionFilter();
|
||||
|
||||
/**
|
||||
* This method is used to test if a particular
|
||||
* character can be displayed by the filter's
|
||||
* font.
|
||||
*
|
||||
* @param glyph - the Unicode character code to be tested
|
||||
*
|
||||
* @return TRUE if the filter's font can display this character.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_bool accept(LEGlyphID glyph) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
@ -171,8 +171,6 @@ le_bool GlyphIterator::hasCursiveLastExitPoint() const
|
||||
|
||||
LEGlyphID GlyphIterator::getCurrGlyphID() const
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
if (direction < 0) {
|
||||
if (position <= nextLimit || position >= prevLimit) {
|
||||
return 0xFFFF;
|
||||
@ -188,8 +186,6 @@ LEGlyphID GlyphIterator::getCurrGlyphID() const
|
||||
|
||||
LEGlyphID GlyphIterator::getCursiveLastGlyphID() const
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
if (direction < 0) {
|
||||
if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit) {
|
||||
return 0xFFFF;
|
||||
|
@ -108,12 +108,11 @@ protected:
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - TRUE if the characters are in a right to left directional run
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and character index arrays will be set.
|
||||
* the auxillary data array will be set to the feature tags.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param outChars - the output character arrayt
|
||||
* @param charIndices - the output character index array
|
||||
* @param featureTags - the output feature tag array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the output character count
|
||||
@ -137,12 +136,11 @@ protected:
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - TRUE if the characters are in a right to left directional run
|
||||
* @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run
|
||||
* @param featureTags - the feature tag array
|
||||
* @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param glyphs - the output glyph index array
|
||||
* @param charIndices - the output character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the output glyph index array
|
||||
|
@ -66,7 +66,7 @@ class LEGlyphStorage;
|
||||
* methods with some default behavior such as returning constant values, or using the
|
||||
* values from the first subfont.
|
||||
*
|
||||
* @draft ICU 2.6
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
class U_LAYOUT_API LEFontInstance : public UObject
|
||||
{
|
||||
@ -167,7 +167,7 @@ public:
|
||||
*
|
||||
* @param ch - the character to be tested
|
||||
*
|
||||
* @return TRUE if the font can render ch.
|
||||
* @return <code>TRUE</code> if the font can render ch.
|
||||
*
|
||||
* @draft ICU 2.6
|
||||
*/
|
||||
@ -190,7 +190,7 @@ public:
|
||||
* @param chars - the character array
|
||||
* @param offset - the index of the first character
|
||||
* @param count - the number of characters
|
||||
* @param reverse - if TRUE, store the glyph indices in reverse order.
|
||||
* @param reverse - if <code>TRUE</code>, store the glyph indices in reverse order.
|
||||
* @param mapper - the character mapper.
|
||||
* @param glyphStorage - the object which contains the output glyph array
|
||||
*
|
||||
@ -252,7 +252,7 @@ public:
|
||||
* @param pointNumber - the number of the point
|
||||
* @param point - the point's X and Y pixel values will be stored here
|
||||
*
|
||||
* @return TRUE if the point coordinates could be stored.
|
||||
* @return <code>TRUE</code> if the point coordinates could be stored.
|
||||
*
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
|
@ -17,128 +17,128 @@ LEGlyphStorage::LEGlyphStorage()
|
||||
: fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
|
||||
fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
|
||||
{
|
||||
// nothing else to do!
|
||||
// nothing else to do!
|
||||
}
|
||||
|
||||
LEGlyphStorage::~LEGlyphStorage()
|
||||
{
|
||||
reset();
|
||||
reset();
|
||||
}
|
||||
|
||||
void LEGlyphStorage::reset()
|
||||
{
|
||||
fGlyphCount = 0;
|
||||
fGlyphCount = 0;
|
||||
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
fPositions = NULL;
|
||||
}
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
fPositions = NULL;
|
||||
}
|
||||
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
fAuxData = NULL;
|
||||
}
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
fAuxData = NULL;
|
||||
}
|
||||
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
fInsertionList = NULL;
|
||||
}
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
fInsertionList = NULL;
|
||||
}
|
||||
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
fCharIndices = NULL;
|
||||
}
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
fCharIndices = NULL;
|
||||
}
|
||||
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
fGlyphs = 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 (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialGlyphCount <= 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
if (initialGlyphCount <= 0) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
fGlyphCount = initialGlyphCount;
|
||||
fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
|
||||
if (fGlyphs == NULL) {
|
||||
fGlyphCount = initialGlyphCount;
|
||||
fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
// Initialize the charIndices array
|
||||
le_int32 i, count = fGlyphCount, dir = 1, out = 0;
|
||||
|
||||
if (rightToLeft) {
|
||||
out = fGlyphCount - 1;
|
||||
dir = -1;
|
||||
}
|
||||
if (rightToLeft) {
|
||||
out = fGlyphCount - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
fCharIndices[out] = i;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
fCharIndices[out] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (fInsertionList == NULL) {
|
||||
// FIXME: check this for failure?
|
||||
fInsertionList = new LEInsertionList(rightToLeft);
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
|
||||
fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
|
||||
|
||||
if (fPositions == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
if (fPositions == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fGlyphCount;
|
||||
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;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fAuxData = LE_NEW_ARRAY(void *, fGlyphCount);
|
||||
fAuxData = LE_NEW_ARRAY(void *, fGlyphCount);
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fGlyphCount;
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
|
||||
@ -220,7 +220,7 @@ void LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
|
||||
@ -228,78 +228,78 @@ void LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
|
||||
|
||||
LEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
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;
|
||||
}
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
return fGlyphs[glyphIndex];
|
||||
return fGlyphs[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
if (fGlyphs == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fGlyphs[glyphIndex] = glyphID;
|
||||
fGlyphs[glyphIndex] = glyphID;
|
||||
}
|
||||
|
||||
le_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
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;
|
||||
}
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fCharIndices[glyphIndex];
|
||||
return fCharIndices[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
if (fCharIndices == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fCharIndices[glyphIndex] = charIndex;
|
||||
fCharIndices[glyphIndex] = charIndex;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const
|
||||
@ -315,7 +315,7 @@ void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
|
||||
@ -323,40 +323,40 @@ void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const
|
||||
|
||||
void *LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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];
|
||||
return fAuxData[glyphIndex];
|
||||
}
|
||||
|
||||
void LEGlyphStorage::setAuxData(le_int32 glyphIndex, void *auxData, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
if (fAuxData == NULL) {
|
||||
success = LE_NO_LAYOUT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fAuxData[glyphIndex] = auxData;
|
||||
fAuxData[glyphIndex] = auxData;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
|
||||
@ -400,186 +400,186 @@ void LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, L
|
||||
|
||||
void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
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 (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;
|
||||
fPositions[glyphIndex * 2] += xAdjust;
|
||||
fPositions[glyphIndex * 2 + 1] += yAdjust;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
}
|
||||
if (fGlyphs != NULL) {
|
||||
LE_DELETE_ARRAY(fGlyphs);
|
||||
}
|
||||
|
||||
fGlyphs = from.fGlyphs;
|
||||
from.fGlyphs = NULL;
|
||||
fGlyphs = from.fGlyphs;
|
||||
from.fGlyphs = NULL;
|
||||
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
}
|
||||
if (fInsertionList != NULL) {
|
||||
delete fInsertionList;
|
||||
}
|
||||
|
||||
fInsertionList = from.fInsertionList;
|
||||
from.fInsertionList = NULL;
|
||||
fInsertionList = from.fInsertionList;
|
||||
from.fInsertionList = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
}
|
||||
if (fCharIndices != NULL) {
|
||||
LE_DELETE_ARRAY(fCharIndices);
|
||||
}
|
||||
|
||||
fCharIndices = from.fCharIndices;
|
||||
from.fCharIndices = NULL;
|
||||
fCharIndices = from.fCharIndices;
|
||||
from.fCharIndices = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
}
|
||||
if (fPositions != NULL) {
|
||||
LE_DELETE_ARRAY(fPositions);
|
||||
}
|
||||
|
||||
fPositions = from.fPositions;
|
||||
from.fPositions = NULL;
|
||||
fPositions = from.fPositions;
|
||||
from.fPositions = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
|
||||
{
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
}
|
||||
if (fAuxData != NULL) {
|
||||
LE_DELETE_ARRAY(fAuxData);
|
||||
}
|
||||
|
||||
fAuxData = from.fAuxData;
|
||||
from.fAuxData = NULL;
|
||||
fAuxData = from.fAuxData;
|
||||
from.fAuxData = NULL;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
|
||||
{
|
||||
fGlyphCount = from.fGlyphCount;
|
||||
fGlyphCount = from.fGlyphCount;
|
||||
}
|
||||
|
||||
void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
|
||||
{
|
||||
fGlyphCount = newGlyphCount;
|
||||
fGlyphCount = newGlyphCount;
|
||||
}
|
||||
|
||||
// FIXME: add error checking?
|
||||
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount)
|
||||
{
|
||||
return fInsertionList->insert(atIndex, insertCount);
|
||||
return fInsertionList->insert(atIndex, insertCount);
|
||||
}
|
||||
|
||||
le_int32 LEGlyphStorage::applyInsertions()
|
||||
{
|
||||
le_int32 growAmount = fInsertionList->getGrowAmount();
|
||||
le_int32 growAmount = fInsertionList->getGrowAmount();
|
||||
|
||||
if (growAmount == 0) {
|
||||
return fGlyphCount;
|
||||
}
|
||||
if (growAmount == 0) {
|
||||
return fGlyphCount;
|
||||
}
|
||||
|
||||
le_int32 newGlyphCount = fGlyphCount + growAmount;
|
||||
le_int32 newGlyphCount = fGlyphCount + growAmount;
|
||||
|
||||
fGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
|
||||
fCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
|
||||
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);
|
||||
}
|
||||
if (fAuxData != NULL) {
|
||||
fAuxData = (void **) LE_GROW_ARRAY(fAuxData, newGlyphCount);
|
||||
}
|
||||
|
||||
fSrcIndex = fGlyphCount - 1;
|
||||
fDestIndex = newGlyphCount - 1;
|
||||
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.
|
||||
// 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;
|
||||
}
|
||||
// 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->applyInsertions(this);
|
||||
|
||||
fInsertionList->reset();
|
||||
fInsertionList->reset();
|
||||
|
||||
return fGlyphCount = newGlyphCount;
|
||||
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.
|
||||
// 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;
|
||||
}
|
||||
// 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;
|
||||
if (fAuxData != NULL) {
|
||||
le_int32 src = fSrcIndex, dest = fDestIndex;
|
||||
|
||||
while (src > atPosition) {
|
||||
fAuxData[dest--] = fAuxData[src--];
|
||||
}
|
||||
while (src > atPosition) {
|
||||
fAuxData[dest--] = fAuxData[src--];
|
||||
}
|
||||
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
fAuxData[dest--] = fAuxData[atPosition];
|
||||
}
|
||||
}
|
||||
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];
|
||||
while (fSrcIndex > atPosition) {
|
||||
fGlyphs[fDestIndex] = fGlyphs[fSrcIndex];
|
||||
fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
|
||||
|
||||
fDestIndex -= 1;
|
||||
fSrcIndex -= 1;
|
||||
}
|
||||
fDestIndex -= 1;
|
||||
fSrcIndex -= 1;
|
||||
}
|
||||
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
fGlyphs[fDestIndex] = newGlyphs[i];
|
||||
fCharIndices[fDestIndex] = fCharIndices[atPosition];
|
||||
for (le_int32 i = count - 1; i >= 0; i -= 1) {
|
||||
fGlyphs[fDestIndex] = newGlyphs[i];
|
||||
fCharIndices[fDestIndex] = fCharIndices[atPosition];
|
||||
|
||||
fDestIndex -= 1;
|
||||
}
|
||||
fDestIndex -= 1;
|
||||
}
|
||||
|
||||
// the source glyph we're pointing at
|
||||
// just got replaced by the insertion
|
||||
fSrcIndex -= 1;
|
||||
// the source glyph we're pointing at
|
||||
// just got replaced by the insertion
|
||||
fSrcIndex -= 1;
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -13,19 +13,78 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class LEGlyphStorage : public UObject, protected LEInsertionCallback
|
||||
/**
|
||||
* This class encapsulates the per-glyph storage used by the ICU LayoutEngine.
|
||||
* For each glyph it holds the glyph ID, the index of the backing store character
|
||||
* which produced the glyph, the X and Y position of the glyph and an auxillary data
|
||||
* pointer.
|
||||
*
|
||||
* The storage is growable using the <code>LEInsertionList</code> class.
|
||||
*
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback
|
||||
{
|
||||
private:
|
||||
le_int32 fGlyphCount;
|
||||
/**
|
||||
* The number of entries in the per-glyph arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 fGlyphCount;
|
||||
|
||||
LEGlyphID *fGlyphs;
|
||||
le_int32 *fCharIndices;
|
||||
float *fPositions;
|
||||
void **fAuxData;
|
||||
/**
|
||||
* The glyph ID array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEGlyphID *fGlyphs;
|
||||
|
||||
/**
|
||||
* The char indices array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 *fCharIndices;
|
||||
|
||||
LEInsertionList *fInsertionList;
|
||||
le_int32 fSrcIndex;
|
||||
le_int32 fDestIndex;
|
||||
/**
|
||||
* The glyph positions array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
float *fPositions;
|
||||
|
||||
/**
|
||||
* The auxillary data array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void **fAuxData;
|
||||
|
||||
|
||||
/**
|
||||
* The insertion list, used to grow the above arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEInsertionList *fInsertionList;
|
||||
|
||||
/**
|
||||
* The source index while growing the data arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 fSrcIndex;
|
||||
|
||||
/**
|
||||
* The destination index used while growing the data arrays.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 fDestIndex;
|
||||
|
||||
/**
|
||||
* The address of this static class variable serves as this class's ID
|
||||
@ -34,19 +93,39 @@ private:
|
||||
static const char fgClassID;
|
||||
|
||||
protected:
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]);
|
||||
/**
|
||||
* This implements <code>LEInsertionCallback</code>. The <code>LEInsertionList</code>
|
||||
* will call this method once for each insertion.
|
||||
*
|
||||
* @param atPosition the position of the insertion
|
||||
* @param count the number of glyphs being inserted
|
||||
* @param newGlyphs the address of the new glyph IDs
|
||||
*
|
||||
* @return <code>true</code> if <code>LEInsertionList</code> should stop
|
||||
* processing the insertion list after this insertion.
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
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();
|
||||
/**
|
||||
* Allocates an empty <code>LEGlyphStorage</code> object. You must call
|
||||
* <code>allocateGlyphArray, allocatePositions and allocateAuxData</code>
|
||||
* to allocate the data.
|
||||
*/
|
||||
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.
|
||||
* The destructor. This will deallocate all of the arrays.
|
||||
*/
|
||||
~LEGlyphStorage();
|
||||
|
||||
/**
|
||||
* This method returns the number of glyphs in the glyph array.
|
||||
*
|
||||
* @return the number of glyphs in the glyph array
|
||||
*
|
||||
@ -137,45 +216,264 @@ public:
|
||||
*/
|
||||
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 allocates the glyph array, the char indices array and the insertion list. You
|
||||
* must call this method before using the object. This method also initializes the char indices
|
||||
* array.
|
||||
*
|
||||
* @param initialGlyphCount the initial size of the glyph and char indices arrays.
|
||||
* @param rightToLeft <code>true</code> if the original input text is right to left.
|
||||
* @param success set to an error code if the storage cannot be allocated of if the initial
|
||||
* glyph count is not positive.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* This method allocates the storage for the glyph positions. It allocates one extra X, Y
|
||||
* position pair for the position just after the last glyph.
|
||||
*
|
||||
* @param success set to an error code if the positions array cannot be allocated.
|
||||
*
|
||||
* @return the number of X, Y position pairs allocated.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
le_int32 allocatePositions(LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method allocates the storage for the auxillary glyph data.
|
||||
*
|
||||
* @param success set to an error code if the aulillary data array cannot be allocated.
|
||||
*
|
||||
* @return the size of the auxillary data array.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
le_int32 allocateAuxData(LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy the entire auxillary data array.
|
||||
*
|
||||
* @param auxData the auxillary data array will be copied to this address
|
||||
* @param success set to an error code if the data cannot be copied
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void getAuxData(void *auxData[], LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* Get the glyph ID for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
* @param success set to an error code if the glyph ID cannot be retrieved.
|
||||
*
|
||||
* @return the glyph ID
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* Get the char index for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
* @param success set to an error code if the char index cannot be retrieved.
|
||||
*
|
||||
* @return the character index
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
le_int32 getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the auxillary data for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
* @param success set to an error code if the auxillary data cannot be retrieved.
|
||||
*
|
||||
* @return the auxillary data
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void *getAuxData(le_int32 glyphIndex, LEErrorCode &success) const;
|
||||
|
||||
/**
|
||||
* This operator allows direct access to the glyph array
|
||||
* using the index operator.
|
||||
*
|
||||
* @param glyphIndex the index into the glyph array
|
||||
*
|
||||
* @return a reference to the given location in the glyph array
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
LEGlyphID &operator[](le_int32 glyphIndex) const;
|
||||
|
||||
/**
|
||||
* Call this method to replace a single glyph in the glyph array
|
||||
* with multiple glyphs. This method uses the <code>LEInsertionList</code>
|
||||
* to do the insertion. It returns the address of storage where the new
|
||||
* glyph IDs can be stored. They will not actually be inserted into the
|
||||
* glyph array until <code>applyInsertions</code> is called.
|
||||
*
|
||||
* @param atIndex the index of the glyph to be replaced
|
||||
* @param insertCount the number of glyphs to replace it with
|
||||
*
|
||||
* @return the address at which to store the replacement glyphs.
|
||||
*
|
||||
* @see LEInsetionList.h
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount);
|
||||
|
||||
/**
|
||||
* This method causes all of the glyph insertions recorded by
|
||||
* <code>insertGlyphs</code> to be applied to the glyph array. The
|
||||
* new slots in the char indices and the auxillary data arrays
|
||||
* will be filled in with the values for the glyph being replaced.
|
||||
*
|
||||
* @return the new size of the glyph array
|
||||
*
|
||||
* @see LEInsertionList.h
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
le_int32 applyInsertions();
|
||||
|
||||
/**
|
||||
* Set the glyph ID for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param glyphID the new glyph ID
|
||||
* @param success will be set to an error code if the glyph ID cannot be set.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Set the char index for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param charIndex the new char index
|
||||
* @param success will be set to an error code if the char index cannot be set.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Set the X, Y position for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param x the new X position
|
||||
* @param y the new Y position
|
||||
* @param success will be set to an error code if the position cannot be set.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Adjust the X, Y position for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param xAdjust the adjustment to the glyph's X position
|
||||
* @param yAdjust the adjustment to the glyph's Y position
|
||||
* @param success will be set to an error code if the glyph's position cannot be adjusted.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Set the auxillary data for a particular glyph.
|
||||
*
|
||||
* @param glyphIndex the index of the glyph
|
||||
* @param auxData the new auxillary data
|
||||
* @param success will be set to an error code if the auxillary data cannot be set.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void setAuxData(le_int32 glyphIndex, void *auxData, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* Delete the glyph array and replace it with the one
|
||||
* in <code>from</code>. Set the glyph array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new glyph array.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void adoptGlyphArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Delete the char indices array and replace it with the one
|
||||
* in <code>from</code>. Set the char indices array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new char indices array.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void adoptCharIndicesArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Delete the position array and replace it with the one
|
||||
* in <code>from</code>. Set the position array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new position array.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void adoptPositionArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Delete the auxillary data array and replace it with the one
|
||||
* in <code>from</code>. Set the auxillary data array pointer
|
||||
* in <code>from</code> to <code>NULL</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new auxillary data array.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void adoptAuxDataArray(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Change the glyph count of this object to be the same
|
||||
* as the one in <code>from</code>.
|
||||
*
|
||||
* @param from the <code>LEGlyphStorage</code> object from which
|
||||
* to get the new glyph count.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void adoptGlyphCount(LEGlyphStorage &from);
|
||||
|
||||
/**
|
||||
* Change the glyph count of this object to the given value.
|
||||
*
|
||||
* @param newGlyphCount the new glyph count.
|
||||
*
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
void adoptGlyphCount(le_int32 newGlyphCount);
|
||||
|
||||
/**
|
||||
* This method frees the glyph, character index, position and
|
||||
* auxillary data 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
|
||||
*/
|
||||
@ -198,7 +496,7 @@ public:
|
||||
|
||||
inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
|
||||
{
|
||||
return fGlyphs[glyphIndex];
|
||||
return fGlyphs[glyphIndex];
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,24 +14,107 @@ U_NAMESPACE_BEGIN
|
||||
|
||||
struct InsertionRecord;
|
||||
|
||||
/**
|
||||
* This class encapsulates the callback used by <code>LEInsertionList</code>
|
||||
* to apply an insertion from the insertion list.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LEInsertionCallback
|
||||
{
|
||||
public:
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0;
|
||||
/**
|
||||
* This method will be called by <code>LEInsertionList::applyInsertions</code> for each
|
||||
* entry on the insertion list.
|
||||
*
|
||||
* @param atPosition the position of the insertion
|
||||
* @param count the number of glyphs to insert
|
||||
* @param newGlyphs the address of the glyphs to insert
|
||||
*
|
||||
* @return <code>TRUE</code> if <code>LEInsertions::applyInsertions</code> should
|
||||
* stop after applying this insertion.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used to keep track of insertions to an array of
|
||||
* <code>LEGlyphIDs</code>. The insertions are kept on a linked
|
||||
* list of <code>InsertionRecords</code> so that the glyph array
|
||||
* doesn't have to be grown for each insertion. The insertions are
|
||||
* stored on the list from leftmost to rightmost to make it easier
|
||||
* to do the insertions.
|
||||
*
|
||||
* The insertions are applied to the array by calling the
|
||||
* <code>applyInsertions</code> method, which calls a client
|
||||
* supplied <code>LEInsertionCallback</code> object to actually
|
||||
* apply the individual insertions.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LEInsertionList : public UObject
|
||||
{
|
||||
public:
|
||||
LEInsertionList(le_bool rightToLeft);
|
||||
~LEInsertionList();
|
||||
/**
|
||||
* Construct an empty insertion list.
|
||||
*
|
||||
* @param rightToLeft <code>TRUE</code> if the glyphs are stored
|
||||
* in the array in right to left order.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEInsertionList(le_bool rightToLeft);
|
||||
|
||||
LEGlyphID *insert(le_int32 position, le_int32 count);
|
||||
le_int32 getGrowAmount();
|
||||
/**
|
||||
* The destructor.
|
||||
*/
|
||||
~LEInsertionList();
|
||||
|
||||
le_bool applyInsertions(LEInsertionCallback *callback);
|
||||
/**
|
||||
* Add an entry to the insertion list.
|
||||
*
|
||||
* @param position the glyph at this position in the array will be
|
||||
* replaced by the new glyphs.
|
||||
* @param count the number of new glyphs
|
||||
*
|
||||
* @return the address of an array in which to store the new glyphs. This will
|
||||
* <em>not</em> be in the glyph array.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
LEGlyphID *insert(le_int32 position, le_int32 count);
|
||||
|
||||
void reset();
|
||||
/**
|
||||
* Return the number of new glyphs that have been inserted.
|
||||
*
|
||||
* @return the number of new glyphs which have been inserted
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 getGrowAmount();
|
||||
|
||||
/**
|
||||
* Call the <code>LEInsertionCallback</code> once for each
|
||||
* entry on the insertion list.
|
||||
*
|
||||
* @param callback the <code>LEInsertionCallback</code> to call for each insertion.
|
||||
*
|
||||
* @return <code>TRUE</code> if <code>callback</code> returned <code>TRUE</code> to
|
||||
* terminate the insertion list processing.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_bool applyInsertions(LEInsertionCallback *callback);
|
||||
|
||||
/**
|
||||
* Empty the insertion list and free all associated
|
||||
* storage.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
||||
@ -55,11 +138,36 @@ private:
|
||||
*/
|
||||
static const char fgClassID;
|
||||
|
||||
InsertionRecord *head;
|
||||
InsertionRecord *tail;
|
||||
/**
|
||||
* The head of the insertion list.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
InsertionRecord *head;
|
||||
|
||||
le_int32 growAmount;
|
||||
le_bool append;
|
||||
/**
|
||||
* The tail of the insertion list.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
InsertionRecord *tail;
|
||||
|
||||
/**
|
||||
* The total number of new glyphs on the insertion list.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_int32 growAmount;
|
||||
|
||||
/**
|
||||
* Set to <code>TRUE</code> if the glyphs are in right
|
||||
* to left order. Since we want the rightmost insertion
|
||||
* to be first on the list, we need to append the
|
||||
* insertions in this case. Otherwise they're prepended.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_bool append;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -12,11 +12,13 @@
|
||||
|
||||
#include "LayoutEngine.h"
|
||||
#include "ArabicLayoutEngine.h"
|
||||
#include "CanonShaping.h"
|
||||
#include "HanLayoutEngine.h"
|
||||
#include "IndicLayoutEngine.h"
|
||||
#include "ThaiLayoutEngine.h"
|
||||
#include "GXLayoutEngine.h"
|
||||
#include "ScriptAndLanguageTags.h"
|
||||
#include "CharSubstitutionFilter.h"
|
||||
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
@ -92,8 +94,26 @@ LEGlyphFilter::~LEGlyphFilter()
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
CharSubstitutionFilter::CharSubstitutionFilter(const LEFontInstance *fontInstance)
|
||||
: fFontInstance(fontInstance)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
CharSubstitutionFilter::~CharSubstitutionFilter()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
||||
const char LayoutEngine::fgClassID=0;
|
||||
|
||||
const LETag emptyTag = 0x00000000;
|
||||
|
||||
const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG;
|
||||
|
||||
const LETag canonFeatures[] = {ccmpFeatureTag, emptyTag};
|
||||
|
||||
LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode)
|
||||
: fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode)
|
||||
{
|
||||
@ -137,6 +157,55 @@ void LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEE
|
||||
fGlyphStorage->getGlyphPosition(glyphIndex, x, y, success);
|
||||
}
|
||||
|
||||
le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
|
||||
LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
|
||||
LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
|
||||
le_int32 i, dir = 1, out = 0, outCharCount = count;
|
||||
|
||||
if (rightToLeft) {
|
||||
out = count - 1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
if (canonGSUBTable->coversScript(scriptTag)) {
|
||||
CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
|
||||
|
||||
glyphStorage.allocateGlyphArray(count, rightToLeft, success);
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i += 1, out += dir) {
|
||||
glyphStorage[i] = (LEGlyphID) chars[offset + i];
|
||||
glyphStorage.setAuxData(i, (void *) canonFeatures, success);
|
||||
}
|
||||
|
||||
outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, NULL);
|
||||
|
||||
outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);
|
||||
for (i = 0; i < outCharCount; i += 1) {
|
||||
outChars[i] = (LEUnicode) LE_GET_GLYPH(glyphStorage[i]);
|
||||
}
|
||||
|
||||
delete substitutionFilter;
|
||||
}
|
||||
|
||||
return outCharCount;
|
||||
}
|
||||
|
||||
le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
@ -150,7 +219,15 @@ le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, l
|
||||
return 0;
|
||||
}
|
||||
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
|
||||
LEUnicode *outChars = NULL;
|
||||
le_int32 outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success);
|
||||
|
||||
if (outChars != NULL) {
|
||||
mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft, glyphStorage, success);
|
||||
LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work...
|
||||
} else {
|
||||
mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
|
||||
}
|
||||
|
||||
return glyphStorage.getGlyphCount();
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class LEGlyphStorage;
|
||||
class U_LAYOUT_API LayoutEngine : public UObject {
|
||||
protected:
|
||||
/**
|
||||
* The number of glyphs in the output
|
||||
* The object which holds the glyph storage
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@ -122,6 +122,31 @@ protected:
|
||||
*/
|
||||
LayoutEngine();
|
||||
|
||||
/**
|
||||
* This method does any required pre-processing to the input characters. It
|
||||
* may generate output characters that differ from the input charcters due to
|
||||
* insertions, deletions, or reorderings. In such cases, it will also generate an
|
||||
* output character index array reflecting these changes.
|
||||
*
|
||||
* Subclasses must override this method.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - TRUE if the characters are in a right to left directional run
|
||||
* @param outChars - the output character array, if different from the input
|
||||
* @param glyphStorege - the object that holds the per-glyph storage. The character index array may be set.
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the output character count (input character count if no change)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
|
||||
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
|
||||
/**
|
||||
* This method does the glyph processing. It converts an array of characters
|
||||
* into an array of glyph indices and character indices. The characters to be
|
||||
@ -138,10 +163,10 @@ protected:
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the context.
|
||||
* @param rightToLeft - TRUE if the text is in a right to left directional run
|
||||
* @param glyphStorage - the object which holds the per-glyph storage. The glyph and char indices arrays
|
||||
* will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param glyphs - the glyph index array
|
||||
* @param charIndices - the character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the glyph index array
|
||||
@ -156,13 +181,10 @@ protected:
|
||||
* is not expected that many subclasses will override this method.
|
||||
*
|
||||
* Input parameters:
|
||||
* @param glyphs - the input glyph array
|
||||
* @param glyphCount - the number of glyphs in the glyph array
|
||||
* @param glyphStorage - the object which holds the per-glyph storage. The glyph position array will be set.
|
||||
* @param x - the starting X position
|
||||
* @param y - the starting Y position
|
||||
*
|
||||
* Output parameters:
|
||||
* @param positions - the output X and Y positions (two entries per glyph)
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@ -181,15 +203,11 @@ protected:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param reverse - TRUE if the glyphs in the glyph array have been reordered
|
||||
* @param glyphs - the input glyph array
|
||||
* @param glyphCount - the number of glyphs
|
||||
* @param positions - the position array, will be updated as needed
|
||||
* @param reverse - <code>TRUE</code> if the glyphs in the glyph array have been reordered
|
||||
* @param glyphStorage - the object which holds the per-glyph storage. The glyph positions will be
|
||||
* adjusted as needed.
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* Note: the positions are passed as a plain array because this method should
|
||||
* not need to reallocate them.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, LEGlyphStorage &glyphStorage, LEErrorCode &success);
|
||||
@ -223,12 +241,10 @@ protected:
|
||||
* @param chars - the input character context
|
||||
* @param offset - the offset of the first character to be mapped
|
||||
* @param count - the number of characters to be mapped
|
||||
* @param reverse - if TRUE, the output will be in reverse order
|
||||
* @param mirror - if TRUE, do character mirroring
|
||||
*
|
||||
* Output parameters:
|
||||
* @param glyphs - the glyph array
|
||||
* @param charIndices - the character index array
|
||||
* @param reverse - if <code>TRUE</code>, the output will be in reverse order
|
||||
* @param mirror - if <code>TRUE</code>, do character mirroring
|
||||
* @param glyphStorage - the object which holds the per-glyph storage. The glyph and char
|
||||
* indices arrays will be filled in.
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LEFontInstance
|
||||
@ -241,11 +257,9 @@ protected:
|
||||
* This is a convenience method that forces the advance width of mark
|
||||
* glyphs to be zero, which is required for proper selection and highlighting.
|
||||
*
|
||||
* @param glyphs - the glyph array
|
||||
* @param glyphCount - the number of glyphs
|
||||
* @param reverse - TRUE if the glyph array has been reordered
|
||||
* @param glyphStorage - the object containing the per-glyph storage. The positions array will be modified.
|
||||
* @param reverse - <code>TRUE</code> if the glyph array has been reordered
|
||||
* @param markFilter - used to identify mark glyphs
|
||||
* @param positions - the glyph position array - updated as required
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* @see LEGlyphFilter
|
||||
@ -254,6 +268,25 @@ protected:
|
||||
*/
|
||||
static void adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);
|
||||
|
||||
|
||||
/**
|
||||
* This is a convenience method that forces the advance width of mark
|
||||
* glyphs to be zero, which is required for proper selection and highlighting.
|
||||
* This method uses the input characters to identify marks. This is required in
|
||||
* cases where the font does not contain enough information to identify them based
|
||||
* on the glyph IDs.
|
||||
*
|
||||
* @param chars - the array of input characters
|
||||
* @param charCount - the number of input characers
|
||||
* @param glyphStorage - the object containing the per-glyph storage. The positions array will be modified.
|
||||
* @param reverse - <code>TRUE</code> if the glyph array has been reordered
|
||||
* @param markFilter - used to identify mark glyphs
|
||||
* @param success - output parameter set to an error code if the operation fails
|
||||
*
|
||||
* @see LEGlyphFilter
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);
|
||||
|
||||
|
||||
|
@ -77,6 +77,7 @@ AlternateSubstSubtables.o \
|
||||
AnchorTables.o \
|
||||
ArabicLigatureData.o \
|
||||
ArabicShaping.o \
|
||||
CanonData.o \
|
||||
ClassDefinitionTables.o \
|
||||
ContextualSubstSubtables.o \
|
||||
CoverageTables.o \
|
||||
|
@ -18,6 +18,18 @@ U_NAMESPACE_BEGIN
|
||||
le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
|
||||
{
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
|
||||
// If there's a filter, we only want to do the
|
||||
// substitution if the *input* glyphs doesn't
|
||||
// exist.
|
||||
//
|
||||
// FIXME: is this always the right thing to do?
|
||||
// FIXME: should this only be done for a non-zero
|
||||
// glyphCount?
|
||||
if (filter != NULL && filter->accept(glyph)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_int32 coverageIndex = getGlyphCoverage(glyph);
|
||||
le_uint16 seqCount = SWAPW(sequenceCount);
|
||||
|
||||
@ -32,12 +44,25 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
|
||||
} else if (glyphCount == 1) {
|
||||
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
|
||||
|
||||
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) {
|
||||
glyphIterator->setCurrGlyphID(substitute);
|
||||
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrGlyphID(substitute);
|
||||
return 1;
|
||||
} else {
|
||||
// If there's a filter, make sure all of the output glyphs
|
||||
// exist.
|
||||
if (filter != NULL) {
|
||||
for (le_int32 i = 0; i < glyphCount; i += 1) {
|
||||
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
|
||||
|
||||
if (! filter->accept(substitute)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount);
|
||||
le_int32 insert = 0, direction = 1;
|
||||
|
||||
|
@ -26,9 +26,21 @@ U_NAMESPACE_BEGIN
|
||||
|
||||
const char OpenTypeLayoutEngine::fgClassID=0;
|
||||
|
||||
const LETag emptyTag = 0x00000000;
|
||||
|
||||
const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG;
|
||||
const LETag ligaFeatureTag = LE_LIGA_FEATURE_TAG;
|
||||
const LETag cligFeatureTag = LE_CLIG_FEATURE_TAG;
|
||||
const LETag kernFeatureTag = LE_KERN_FEATURE_TAG;
|
||||
const LETag markFeatureTag = LE_MARK_FEATURE_TAG;
|
||||
const LETag mkmkFeatureTag = LE_MKMK_FEATURE_TAG;
|
||||
|
||||
const LETag defaultFeatures[] = {ccmpFeatureTag, ligaFeatureTag, cligFeatureTag, kernFeatureTag, markFeatureTag, mkmkFeatureTag, emptyTag};
|
||||
|
||||
|
||||
OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
|
||||
const GlyphSubstitutionTableHeader *gsubTable)
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureOrder(NULL),
|
||||
: LayoutEngine(fontInstance, scriptCode, languageCode), fFeatureList(defaultFeatures), fFeatureOrder(NULL),
|
||||
fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
|
||||
{
|
||||
static le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG;
|
||||
@ -89,8 +101,8 @@ void OpenTypeLayoutEngine::setScriptAndLanguageTags()
|
||||
fLangSysTag = getLangSysTag(fLanguageCode);
|
||||
}
|
||||
|
||||
le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode /*chars*/[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/,
|
||||
LEUnicode *&/*outChars*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
le_int32 OpenTypeLayoutEngine::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;
|
||||
@ -101,7 +113,19 @@ le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode /*chars*/[],
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
le_int32 outCharCount = LayoutEngine::characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
glyphStorage.allocateAuxData(success);
|
||||
|
||||
for (le_int32 i = 0; i < outCharCount; i += 1) {
|
||||
glyphStorage.setAuxData(i, (void *) fFeatureList, success);
|
||||
}
|
||||
|
||||
return outCharCount;
|
||||
}
|
||||
|
||||
// Input: characters, tags
|
||||
@ -160,17 +184,18 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o
|
||||
return 0;
|
||||
}
|
||||
|
||||
outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, fakeGlyphStorage, success);
|
||||
outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, fakeGlyphStorage, success);
|
||||
|
||||
if (outChars != NULL) {
|
||||
fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success);
|
||||
LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work...
|
||||
//adjustGlyphs(outChars, 0, outCharCount, rightToLeft, fakeGlyphs, fakeGlyphCount);
|
||||
} else {
|
||||
fakeGlyphCount = glyphProcessing(chars, offset, count, max, rightToLeft, fakeGlyphStorage, success);
|
||||
//adjustGlyphs(chars, offset, count, rightToLeft, fakeGlyphs, fakeGlyphCount);
|
||||
}
|
||||
|
||||
outGlyphCount = glyphPostProcessing(fakeGlyphStorage, glyphStorage, success);
|
||||
outGlyphCount = glyphPostProcessing(fakeGlyphStorage, glyphStorage, success);
|
||||
|
||||
return outGlyphCount;
|
||||
}
|
||||
|
@ -149,6 +149,14 @@ private:
|
||||
static const char fgClassID;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* A list of "default" features. The default characterProcessing method
|
||||
* will apply all of these tags to every glyph.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
const LETag *fFeatureList;
|
||||
|
||||
/**
|
||||
* A list of tags in the order in which the features in
|
||||
* the font should be applied, as opposed to using the
|
||||
@ -206,7 +214,7 @@ protected:
|
||||
/**
|
||||
* This method does the OpenType character processing. It assigns the OpenType feature
|
||||
* tags to the characters, and may generate output characters that differ from the input
|
||||
* charcters dueto insertions, deletions, or reorderings. In such cases, it will also
|
||||
* charcters due to insertions, deletions, or reorderings. In such cases, it will also
|
||||
* generate an output character index array reflecting these changes.
|
||||
*
|
||||
* Subclasses must override this method.
|
||||
|
@ -99,11 +99,10 @@ protected:
|
||||
* @param offset - the index of the first character to process
|
||||
* @param count - the number of characters to process
|
||||
* @param max - the number of characters in the input context
|
||||
* @param rightToLeft - TRUE if the text is in a right to left directional run
|
||||
* @param rightToLeft - <code>TRUE</code> if the text is in a right to left directional run
|
||||
* @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
|
||||
*
|
||||
* Output parameters:
|
||||
* @param glyphs - the glyph index array
|
||||
* @param charIndices - the character index array
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @return the number of glyphs in the glyph index array
|
||||
|
@ -163,6 +163,9 @@
|
||||
<File
|
||||
RelativePath=".\ArabicShaping.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CanonData.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ClassDefinitionTables.cpp">
|
||||
</File>
|
||||
@ -365,6 +368,12 @@
|
||||
<File
|
||||
RelativePath=".\AttachmentPosnSubtables.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CanonShaping.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CharSubstitutionFilter.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ClassDefinitionTables.h">
|
||||
</File>
|
||||
@ -511,9 +520,41 @@
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LEGlyphStorage.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\layout
|
||||
"
|
||||
Outputs="..\..\include\layout\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\layout
|
||||
"
|
||||
Outputs="..\..\include\layout\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LEInsertionList.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\layout
|
||||
"
|
||||
Outputs="..\..\include\layout\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\layout
|
||||
"
|
||||
Outputs="..\..\include\layout\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LELanguages.h">
|
||||
|
Loading…
Reference in New Issue
Block a user