0N/A/*
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A *
0N/A */
0N/A
0N/A/*
0N/A **********************************************************************
3171N/A * Copyright (C) 1998-2009, International Business Machines
0N/A * Corporation and others. All Rights Reserved.
0N/A **********************************************************************
0N/A */
0N/A
0N/A#include "LETypes.h"
0N/A#include "LEInsertionList.h"
0N/A#include "LEGlyphStorage.h"
0N/A
1693N/AU_NAMESPACE_BEGIN
1693N/A
1693N/AUOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
1693N/A
3171N/ALEInsertionCallback::~LEInsertionCallback()
3171N/A{
3171N/A // nothing to do...
3171N/A}
3171N/A
0N/ALEGlyphStorage::LEGlyphStorage()
0N/A : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
0N/A fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
0N/A{
0N/A // nothing else to do!
0N/A}
0N/A
0N/ALEGlyphStorage::~LEGlyphStorage()
0N/A{
0N/A reset();
0N/A}
0N/A
0N/Avoid LEGlyphStorage::reset()
0N/A{
0N/A fGlyphCount = 0;
0N/A
0N/A if (fPositions != NULL) {
0N/A LE_DELETE_ARRAY(fPositions);
0N/A fPositions = NULL;
0N/A }
0N/A
0N/A if (fAuxData != NULL) {
0N/A LE_DELETE_ARRAY(fAuxData);
0N/A fAuxData = NULL;
0N/A }
0N/A
0N/A if (fInsertionList != NULL) {
0N/A delete fInsertionList;
0N/A fInsertionList = NULL;
0N/A }
0N/A
0N/A if (fCharIndices != NULL) {
0N/A LE_DELETE_ARRAY(fCharIndices);
0N/A fCharIndices = NULL;
0N/A }
0N/A
0N/A if (fGlyphs != NULL) {
0N/A LE_DELETE_ARRAY(fGlyphs);
0N/A fGlyphs = NULL;
0N/A }
0N/A}
0N/A
0N/A// FIXME: This might get called more than once, for various reasons. Is
0N/A// testing for pre-existing glyph and charIndices arrays good enough?
0N/Avoid LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (initialGlyphCount <= 0) {
0N/A success = LE_ILLEGAL_ARGUMENT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fGlyphs == NULL) {
0N/A fGlyphCount = initialGlyphCount;
0N/A fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
0N/A
0N/A if (fGlyphs == NULL) {
0N/A success = LE_MEMORY_ALLOCATION_ERROR;
0N/A return;
0N/A }
0N/A }
0N/A
0N/A if (fCharIndices == NULL) {
0N/A fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
0N/A
0N/A if (fCharIndices == NULL) {
0N/A LE_DELETE_ARRAY(fGlyphs);
0N/A fGlyphs = NULL;
0N/A success = LE_MEMORY_ALLOCATION_ERROR;
0N/A return;
0N/A }
0N/A
0N/A // Initialize the charIndices array
0N/A le_int32 i, count = fGlyphCount, dir = 1, out = 0;
0N/A
0N/A if (rightToLeft) {
0N/A out = fGlyphCount - 1;
0N/A dir = -1;
0N/A }
0N/A
0N/A for (i = 0; i < count; i += 1, out += dir) {
0N/A fCharIndices[out] = i;
0N/A }
0N/A }
0N/A
0N/A if (fInsertionList == NULL) {
0N/A // FIXME: check this for failure?
0N/A fInsertionList = new LEInsertionList(rightToLeft);
3171N/A if (fInsertionList == NULL) {
3171N/A LE_DELETE_ARRAY(fCharIndices);
3171N/A fCharIndices = NULL;
3171N/A
3171N/A LE_DELETE_ARRAY(fGlyphs);
3171N/A fGlyphs = NULL;
3171N/A
3171N/A success = LE_MEMORY_ALLOCATION_ERROR;
3171N/A return;
0N/A }
0N/A}
3171N/A}
0N/A
0N/A// FIXME: do we want to initialize the positions to [0, 0]?
0N/Ale_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return -1;
0N/A }
0N/A
3171N/A if (fPositions != NULL) {
3171N/A success = LE_INTERNAL_ERROR;
3171N/A return -1;
3171N/A }
3171N/A
0N/A fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
0N/A
0N/A if (fPositions == NULL) {
0N/A success = LE_MEMORY_ALLOCATION_ERROR;
0N/A return -1;
0N/A }
0N/A
0N/A return fGlyphCount;
0N/A}
0N/A
0N/A// FIXME: do we want to initialize the aux data to NULL?
0N/Ale_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return -1;
0N/A }
0N/A
3171N/A if (fAuxData != NULL) {
3171N/A success = LE_INTERNAL_ERROR;
3171N/A return -1;
3171N/A }
3171N/A
0N/A fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount);
0N/A
0N/A if (fAuxData == NULL) {
0N/A success = LE_MEMORY_ALLOCATION_ERROR;
0N/A return -1;
0N/A }
0N/A
0N/A return fGlyphCount;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
0N/A{
0N/A le_int32 i;
0N/A
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (charIndices == NULL) {
0N/A success = LE_ILLEGAL_ARGUMENT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fCharIndices == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A for (i = 0; i < fGlyphCount; i += 1) {
0N/A charIndices[i] = fCharIndices[i] + indexBase;
0N/A }
0N/A}
0N/A
0N/Avoid LEGlyphStorage::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (charIndices == NULL) {
0N/A success = LE_ILLEGAL_ARGUMENT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fCharIndices == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
0N/A}
0N/A
0N/A// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
0N/Avoid LEGlyphStorage::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
0N/A{
0N/A le_int32 i;
0N/A
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (glyphs == NULL) {
0N/A success = LE_ILLEGAL_ARGUMENT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fGlyphs == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A for (i = 0; i < fGlyphCount; i += 1) {
0N/A glyphs[i] = fGlyphs[i] | extraBits;
0N/A }
0N/A}
0N/A
0N/Avoid LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (glyphs == NULL) {
0N/A success = LE_ILLEGAL_ARGUMENT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fGlyphs == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
0N/A}
0N/A
0N/ALEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return 0xFFFF;
0N/A }
0N/A
0N/A if (fGlyphs == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return 0xFFFF;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return 0xFFFF;
0N/A }
0N/A
0N/A return fGlyphs[glyphIndex];
0N/A}
0N/A
0N/Avoid LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (fGlyphs == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return;
0N/A }
0N/A
0N/A fGlyphs[glyphIndex] = glyphID;
0N/A}
0N/A
0N/Ale_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return -1;
0N/A }
0N/A
0N/A if (fCharIndices == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return -1;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return -1;
0N/A }
0N/A
0N/A return fCharIndices[glyphIndex];
0N/A}
0N/A
0N/Avoid LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (fCharIndices == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return;
0N/A }
0N/A
0N/A fCharIndices[glyphIndex] = charIndex;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::getAuxData(le_uint32 auxData[], LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (auxData == NULL) {
0N/A success = LE_ILLEGAL_ARGUMENT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fAuxData == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
0N/A}
0N/A
0N/Ale_uint32 LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return 0;
0N/A }
0N/A
0N/A if (fAuxData == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return 0;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return 0;
0N/A }
0N/A
0N/A return fAuxData[glyphIndex];
0N/A}
0N/A
0N/Avoid LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (fAuxData == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return;
0N/A }
0N/A
0N/A fAuxData[glyphIndex] = auxData;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (positions == NULL) {
0N/A success = LE_ILLEGAL_ARGUMENT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fPositions == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
0N/A}
0N/A
0N/Avoid LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return;
0N/A }
0N/A
0N/A if (fPositions == NULL) {
0N/A success = LE_NO_LAYOUT_ERROR;
0N/A return;
0N/A }
0N/A
0N/A x = fPositions[glyphIndex * 2];
0N/A y = fPositions[glyphIndex * 2 + 1];
0N/A}
0N/A
0N/Avoid LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return;
0N/A }
0N/A
0N/A fPositions[glyphIndex * 2] = x;
0N/A fPositions[glyphIndex * 2 + 1] = y;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success)
0N/A{
0N/A if (LE_FAILURE(success)) {
0N/A return;
0N/A }
0N/A
0N/A if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
0N/A success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
0N/A return;
0N/A }
0N/A
0N/A fPositions[glyphIndex * 2] += xAdjust;
0N/A fPositions[glyphIndex * 2 + 1] += yAdjust;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
0N/A{
0N/A if (fGlyphs != NULL) {
0N/A LE_DELETE_ARRAY(fGlyphs);
0N/A }
0N/A
0N/A fGlyphs = from.fGlyphs;
0N/A from.fGlyphs = NULL;
0N/A
0N/A if (fInsertionList != NULL) {
0N/A delete fInsertionList;
0N/A }
0N/A
0N/A fInsertionList = from.fInsertionList;
0N/A from.fInsertionList = NULL;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
0N/A{
0N/A if (fCharIndices != NULL) {
0N/A LE_DELETE_ARRAY(fCharIndices);
0N/A }
0N/A
0N/A fCharIndices = from.fCharIndices;
0N/A from.fCharIndices = NULL;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
0N/A{
0N/A if (fPositions != NULL) {
0N/A LE_DELETE_ARRAY(fPositions);
0N/A }
0N/A
0N/A fPositions = from.fPositions;
0N/A from.fPositions = NULL;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
0N/A{
0N/A if (fAuxData != NULL) {
0N/A LE_DELETE_ARRAY(fAuxData);
0N/A }
0N/A
0N/A fAuxData = from.fAuxData;
0N/A from.fAuxData = NULL;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
0N/A{
0N/A fGlyphCount = from.fGlyphCount;
0N/A}
0N/A
0N/Avoid LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
0N/A{
0N/A fGlyphCount = newGlyphCount;
0N/A}
0N/A
3171N/A// Move a glyph to a different position in the LEGlyphStorage ( used for Indic v2 processing )
3171N/A
3171N/Avoid LEGlyphStorage::moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker )
3171N/A{
3171N/A
3171N/A LEErrorCode success = LE_NO_ERROR;
3171N/A
3171N/A LEGlyphID holdGlyph = getGlyphID(fromPosition,success);
3171N/A le_int32 holdCharIndex = getCharIndex(fromPosition,success);
3171N/A le_uint32 holdAuxData = getAuxData(fromPosition,success);
3171N/A
3171N/A if ( fromPosition < toPosition ) {
3171N/A for ( le_int32 i = fromPosition ; i < toPosition ; i++ ) {
3171N/A setGlyphID(i,getGlyphID(i+1,success),success);
3171N/A setCharIndex(i,getCharIndex(i+1,success),success);
3171N/A setAuxData(i,getAuxData(i+1,success),success);
3171N/A }
3171N/A } else {
3171N/A for ( le_int32 i = toPosition ; i > fromPosition ; i-- ) {
3171N/A setGlyphID(i,getGlyphID(i-1,success),success);
3171N/A setCharIndex(i,getCharIndex(i-1,success),success);
3171N/A setAuxData(i,getAuxData(i-1,success),success);
3171N/A
3171N/A }
3171N/A }
3171N/A
3171N/A setGlyphID(toPosition,holdGlyph,success);
3171N/A setCharIndex(toPosition,holdCharIndex,success);
3171N/A setAuxData(toPosition,holdAuxData | marker,success);
3171N/A
3171N/A}
3171N/A
3171N/A// Glue code for existing stable API
0N/ALEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount)
0N/A{
3171N/A LEErrorCode ignored = LE_NO_LAYOUT_ERROR;
3171N/A return insertGlyphs(atIndex, insertCount, ignored);
3171N/A}
3171N/A
3171N/A// FIXME: add error checking?
3171N/ALEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success)
3171N/A{
3171N/A return fInsertionList->insert(atIndex, insertCount, success);
0N/A}
0N/A
0N/Ale_int32 LEGlyphStorage::applyInsertions()
0N/A{
0N/A le_int32 growAmount = fInsertionList->getGrowAmount();
0N/A
6322N/A if (growAmount <= 0) {
0N/A return fGlyphCount;
0N/A }
0N/A
0N/A le_int32 newGlyphCount = fGlyphCount + growAmount;
0N/A
3171N/A LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
3171N/A if (newGlyphs == NULL) {
3171N/A // Could not grow the glyph array
3171N/A return fGlyphCount;
3171N/A }
3171N/A fGlyphs = newGlyphs;
3171N/A
3171N/A le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
3171N/A if (newCharIndices == NULL) {
3171N/A // Could not grow the glyph array
3171N/A return fGlyphCount;
3171N/A }
3171N/A fCharIndices = newCharIndices;
0N/A
0N/A if (fAuxData != NULL) {
3171N/A le_uint32 *newAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount);
3171N/A if (newAuxData == NULL) {
3171N/A // could not grow the aux data array
3171N/A return fGlyphCount;
3171N/A }
3171N/A fAuxData = (le_uint32 *)newAuxData;
0N/A }
0N/A
6322N/A if (fGlyphCount > 0) {
6322N/A fSrcIndex = fGlyphCount - 1;
6322N/A }
0N/A fDestIndex = newGlyphCount - 1;
0N/A
0N/A#if 0
0N/A // If the current position is at the end of the array
0N/A // update it to point to the end of the new array. The
0N/A // insertion callback will handle all other cases.
0N/A // FIXME: this is left over from GlyphIterator, but there's no easy
0N/A // way to implement this here... it seems that GlyphIterator doesn't
0N/A // really need it 'cause the insertions don't get applied until after a
0N/A // complete pass over the glyphs, after which the iterator gets reset anyhow...
0N/A // probably better to just document that for LEGlyphStorage and GlyphIterator...
0N/A if (position == glyphCount) {
0N/A position = newGlyphCount;
0N/A }
0N/A#endif
0N/A
0N/A fInsertionList->applyInsertions(this);
0N/A
0N/A fInsertionList->reset();
0N/A
0N/A return fGlyphCount = newGlyphCount;
0N/A}
0N/A
0N/Ale_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
0N/A{
0N/A#if 0
0N/A // if the current position is within the block we're shifting
0N/A // it needs to be updated to the current glyph's
0N/A // new location.
0N/A // FIXME: this is left over from GlyphIterator, but there's no easy
0N/A // way to implement this here... it seems that GlyphIterator doesn't
0N/A // really need it 'cause the insertions don't get applied until after a
0N/A // complete pass over the glyphs, after which the iterator gets reset anyhow...
0N/A // probably better to just document that for LEGlyphStorage and GlyphIterator...
0N/A if (position >= atPosition && position <= fSrcIndex) {
0N/A position += fDestIndex - fSrcIndex;
0N/A }
0N/A#endif
0N/A
6322N/A if (atPosition < 0 || fSrcIndex < 0 || fDestIndex < 0) {
6322N/A return FALSE;
6322N/A }
6322N/A
0N/A if (fAuxData != NULL) {
0N/A le_int32 src = fSrcIndex, dest = fDestIndex;
0N/A
0N/A while (src > atPosition) {
0N/A fAuxData[dest--] = fAuxData[src--];
0N/A }
0N/A
0N/A for (le_int32 i = count - 1; i >= 0; i -= 1) {
0N/A fAuxData[dest--] = fAuxData[atPosition];
0N/A }
0N/A }
0N/A
6322N/A while (fSrcIndex > atPosition && fSrcIndex >= 0 && fDestIndex >= 0) {
0N/A fGlyphs[fDestIndex] = fGlyphs[fSrcIndex];
0N/A fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
0N/A
0N/A fDestIndex -= 1;
0N/A fSrcIndex -= 1;
0N/A }
0N/A
6322N/A for (le_int32 i = count - 1; i >= 0 && fDestIndex >= 0; i -= 1) {
0N/A fGlyphs[fDestIndex] = newGlyphs[i];
0N/A fCharIndices[fDestIndex] = fCharIndices[atPosition];
0N/A
0N/A fDestIndex -= 1;
0N/A }
0N/A
0N/A // the source glyph we're pointing at
0N/A // just got replaced by the insertion
6322N/A fSrcIndex -= 1;
0N/A
0N/A return FALSE;
0N/A}
1693N/A
1693N/AU_NAMESPACE_END
1693N/A