+++ /dev/null
-/*
- **********************************************************************
- * Copyright (C) 1998-2009, International Business Machines
- * Corporation and others. All Rights Reserved.
- **********************************************************************
- */
-
-#include "LETypes.h"
-#include "LEInsertionList.h"
-#include "LEGlyphStorage.h"
-
-U_NAMESPACE_BEGIN
-
-UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
-
-LEInsertionCallback::~LEInsertionCallback()
-{
- // nothing to do...
-}
-
-LEGlyphStorage::LEGlyphStorage()
- : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
- fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
-{
- // nothing else to do!
-}
-
-LEGlyphStorage::~LEGlyphStorage()
-{
- reset();
-}
-
-void LEGlyphStorage::reset()
-{
- fGlyphCount = 0;
-
- if (fPositions != NULL) {
- LE_DELETE_ARRAY(fPositions);
- fPositions = NULL;
- }
-
- if (fAuxData != NULL) {
- LE_DELETE_ARRAY(fAuxData);
- fAuxData = NULL;
- }
-
- if (fInsertionList != NULL) {
- delete fInsertionList;
- fInsertionList = NULL;
- }
-
- if (fCharIndices != NULL) {
- LE_DELETE_ARRAY(fCharIndices);
- fCharIndices = NULL;
- }
-
- if (fGlyphs != NULL) {
- LE_DELETE_ARRAY(fGlyphs);
- fGlyphs = NULL;
- }
-}
-
-// FIXME: This might get called more than once, for various reasons. Is
-// testing for pre-existing glyph and charIndices arrays good enough?
-void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (initialGlyphCount <= 0) {
- success = LE_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- if (fGlyphs == NULL) {
- fGlyphCount = initialGlyphCount;
- fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
-
- if (fGlyphs == NULL) {
- success = LE_MEMORY_ALLOCATION_ERROR;
- return;
- }
- }
-
- if (fCharIndices == NULL) {
- fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
-
- if (fCharIndices == NULL) {
- LE_DELETE_ARRAY(fGlyphs);
- fGlyphs = NULL;
- success = LE_MEMORY_ALLOCATION_ERROR;
- return;
- }
-
- // Initialize the charIndices array
- le_int32 i, count = fGlyphCount, dir = 1, out = 0;
-
- if (rightToLeft) {
- out = fGlyphCount - 1;
- dir = -1;
- }
-
- for (i = 0; i < count; i += 1, out += dir) {
- fCharIndices[out] = i;
- }
- }
-
- if (fInsertionList == NULL) {
- // FIXME: check this for failure?
- fInsertionList = new LEInsertionList(rightToLeft);
- if (fInsertionList == NULL) {
- LE_DELETE_ARRAY(fCharIndices);
- fCharIndices = NULL;
-
- LE_DELETE_ARRAY(fGlyphs);
- fGlyphs = NULL;
-
- success = LE_MEMORY_ALLOCATION_ERROR;
- return;
- }
- }
-}
-
-// FIXME: do we want to initialize the positions to [0, 0]?
-le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return -1;
- }
-
- if (fPositions != NULL) {
- success = LE_INTERNAL_ERROR;
- return -1;
- }
-
- fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
-
- if (fPositions == NULL) {
- success = LE_MEMORY_ALLOCATION_ERROR;
- return -1;
- }
-
- return fGlyphCount;
-}
-
-// FIXME: do we want to initialize the aux data to NULL?
-le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return -1;
- }
-
- if (fAuxData != NULL) {
- success = LE_INTERNAL_ERROR;
- return -1;
- }
-
- fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount);
-
- if (fAuxData == NULL) {
- success = LE_MEMORY_ALLOCATION_ERROR;
- return -1;
- }
-
- return fGlyphCount;
-}
-
-void LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
-{
- le_int32 i;
-
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (charIndices == NULL) {
- success = LE_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- if (fCharIndices == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- for (i = 0; i < fGlyphCount; i += 1) {
- charIndices[i] = fCharIndices[i] + indexBase;
- }
-}
-
-void LEGlyphStorage::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (charIndices == NULL) {
- success = LE_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- if (fCharIndices == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
-}
-
-// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
-void LEGlyphStorage::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
-{
- le_int32 i;
-
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (glyphs == NULL) {
- success = LE_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- if (fGlyphs == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- for (i = 0; i < fGlyphCount; i += 1) {
- glyphs[i] = fGlyphs[i] | extraBits;
- }
-}
-
-void LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (glyphs == NULL) {
- success = LE_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- if (fGlyphs == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
-}
-
-LEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return 0xFFFF;
- }
-
- if (fGlyphs == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return 0xFFFF;
- }
-
- if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return 0xFFFF;
- }
-
- return fGlyphs[glyphIndex];
-}
-
-void LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (fGlyphs == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return;
- }
-
- fGlyphs[glyphIndex] = glyphID;
-}
-
-le_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return -1;
- }
-
- if (fCharIndices == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return -1;
- }
-
- if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return -1;
- }
-
- return fCharIndices[glyphIndex];
-}
-
-void LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (fCharIndices == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return;
- }
-
- fCharIndices[glyphIndex] = charIndex;
-}
-
-void LEGlyphStorage::getAuxData(le_uint32 auxData[], LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (auxData == NULL) {
- success = LE_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- if (fAuxData == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
-}
-
-le_uint32 LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return 0;
- }
-
- if (fAuxData == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return 0;
- }
-
- if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return 0;
- }
-
- return fAuxData[glyphIndex];
-}
-
-void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (fAuxData == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return;
- }
-
- fAuxData[glyphIndex] = auxData;
-}
-
-void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (positions == NULL) {
- success = LE_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- if (fPositions == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
-}
-
-void LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return;
- }
-
- if (fPositions == NULL) {
- success = LE_NO_LAYOUT_ERROR;
- return;
- }
-
- x = fPositions[glyphIndex * 2];
- y = fPositions[glyphIndex * 2 + 1];
-}
-
-void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return;
- }
-
- fPositions[glyphIndex * 2] = x;
- fPositions[glyphIndex * 2 + 1] = y;
-}
-
-void LEGlyphStorage::adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success)
-{
- if (LE_FAILURE(success)) {
- return;
- }
-
- if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
- success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
- return;
- }
-
- fPositions[glyphIndex * 2] += xAdjust;
- fPositions[glyphIndex * 2 + 1] += yAdjust;
-}
-
-void LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
-{
- if (fGlyphs != NULL) {
- LE_DELETE_ARRAY(fGlyphs);
- }
-
- fGlyphs = from.fGlyphs;
- from.fGlyphs = NULL;
-
- if (fInsertionList != NULL) {
- delete fInsertionList;
- }
-
- fInsertionList = from.fInsertionList;
- from.fInsertionList = NULL;
-}
-
-void LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
-{
- if (fCharIndices != NULL) {
- LE_DELETE_ARRAY(fCharIndices);
- }
-
- fCharIndices = from.fCharIndices;
- from.fCharIndices = NULL;
-}
-
-void LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
-{
- if (fPositions != NULL) {
- LE_DELETE_ARRAY(fPositions);
- }
-
- fPositions = from.fPositions;
- from.fPositions = NULL;
-}
-
-void LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
-{
- if (fAuxData != NULL) {
- LE_DELETE_ARRAY(fAuxData);
- }
-
- fAuxData = from.fAuxData;
- from.fAuxData = NULL;
-}
-
-void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
-{
- fGlyphCount = from.fGlyphCount;
-}
-
-void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
-{
- fGlyphCount = newGlyphCount;
-}
-
-// Move a glyph to a different position in the LEGlyphStorage ( used for Indic v2 processing )
-
-void LEGlyphStorage::moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker )
-{
-
- LEErrorCode success = LE_NO_ERROR;
-
- LEGlyphID holdGlyph = getGlyphID(fromPosition,success);
- le_int32 holdCharIndex = getCharIndex(fromPosition,success);
- le_uint32 holdAuxData = getAuxData(fromPosition,success);
-
- if ( fromPosition < toPosition ) {
- for ( le_int32 i = fromPosition ; i < toPosition ; i++ ) {
- setGlyphID(i,getGlyphID(i+1,success),success);
- setCharIndex(i,getCharIndex(i+1,success),success);
- setAuxData(i,getAuxData(i+1,success),success);
- }
- } else {
- for ( le_int32 i = toPosition ; i > fromPosition ; i-- ) {
- setGlyphID(i,getGlyphID(i-1,success),success);
- setCharIndex(i,getCharIndex(i-1,success),success);
- setAuxData(i,getAuxData(i-1,success),success);
-
- }
- }
-
- setGlyphID(toPosition,holdGlyph,success);
- setCharIndex(toPosition,holdCharIndex,success);
- setAuxData(toPosition,holdAuxData | marker,success);
-
-}
-
-// Glue code for existing stable API
-LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount)
-{
- LEErrorCode ignored = LE_NO_LAYOUT_ERROR;
- return insertGlyphs(atIndex, insertCount, ignored);
-}
-
-// FIXME: add error checking?
-LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success)
-{
- return fInsertionList->insert(atIndex, insertCount, success);
-}
-
-le_int32 LEGlyphStorage::applyInsertions()
-{
- le_int32 growAmount = fInsertionList->getGrowAmount();
-
- if (growAmount == 0) {
- return fGlyphCount;
- }
-
- le_int32 newGlyphCount = fGlyphCount + growAmount;
-
- LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
- if (newGlyphs == NULL) {
- // Could not grow the glyph array
- return fGlyphCount;
- }
- fGlyphs = newGlyphs;
-
- le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
- if (newCharIndices == NULL) {
- // Could not grow the glyph array
- return fGlyphCount;
- }
- fCharIndices = newCharIndices;
-
- if (fAuxData != NULL) {
- le_uint32 *newAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount);
- if (newAuxData == NULL) {
- // could not grow the aux data array
- return fGlyphCount;
- }
- fAuxData = (le_uint32 *)newAuxData;
- }
-
- fSrcIndex = fGlyphCount - 1;
- fDestIndex = newGlyphCount - 1;
-
-#if 0
- // If the current position is at the end of the array
- // update it to point to the end of the new array. The
- // insertion callback will handle all other cases.
- // FIXME: this is left over from GlyphIterator, but there's no easy
- // way to implement this here... it seems that GlyphIterator doesn't
- // really need it 'cause the insertions don't get applied until after a
- // complete pass over the glyphs, after which the iterator gets reset anyhow...
- // probably better to just document that for LEGlyphStorage and GlyphIterator...
- if (position == glyphCount) {
- position = newGlyphCount;
- }
-#endif
-
- fInsertionList->applyInsertions(this);
-
- fInsertionList->reset();
-
- return fGlyphCount = newGlyphCount;
-}
-
-le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
-{
-#if 0
- // if the current position is within the block we're shifting
- // it needs to be updated to the current glyph's
- // new location.
- // FIXME: this is left over from GlyphIterator, but there's no easy
- // way to implement this here... it seems that GlyphIterator doesn't
- // really need it 'cause the insertions don't get applied until after a
- // complete pass over the glyphs, after which the iterator gets reset anyhow...
- // probably better to just document that for LEGlyphStorage and GlyphIterator...
- if (position >= atPosition && position <= fSrcIndex) {
- position += fDestIndex - fSrcIndex;
- }
-#endif
-
- if (fAuxData != NULL) {
- le_int32 src = fSrcIndex, dest = fDestIndex;
-
- while (src > atPosition) {
- fAuxData[dest--] = fAuxData[src--];
- }
-
- for (le_int32 i = count - 1; i >= 0; i -= 1) {
- fAuxData[dest--] = fAuxData[atPosition];
- }
- }
-
- while (fSrcIndex > atPosition) {
- fGlyphs[fDestIndex] = fGlyphs[fSrcIndex];
- fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
-
- fDestIndex -= 1;
- fSrcIndex -= 1;
- }
-
- for (le_int32 i = count - 1; i >= 0; i -= 1) {
- fGlyphs[fDestIndex] = newGlyphs[i];
- fCharIndices[fDestIndex] = fCharIndices[atPosition];
-
- fDestIndex -= 1;
- }
-
- // the source glyph we're pointing at
- // just got replaced by the insertion
- fSrcIndex -= 1;
-
- return FALSE;
-}
-
-U_NAMESPACE_END
-