113c83a2a09a0842ff57ec020fe3f534de766ccd1Chad Rosier/*
219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu **********************************************************************
319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu *   Copyright (C) 1998-2009, International Business Machines
419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu *   Corporation and others.  All Rights Reserved.
519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu **********************************************************************
619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu */
719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu#include "LETypes.h"
919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu#include "LEInsertionList.h"
1019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu#include "LEGlyphStorage.h"
1119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
1219fdc268c316b3b0bdcb2b558449819f4f402d6aHao LiuU_NAMESPACE_BEGIN
1319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
1419fdc268c316b3b0bdcb2b558449819f4f402d6aHao LiuUOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
1519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
1619fdc268c316b3b0bdcb2b558449819f4f402d6aHao LiuLEInsertionCallback::~LEInsertionCallback()
1719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
1819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu	// nothing to do...
1919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
2019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
2119fdc268c316b3b0bdcb2b558449819f4f402d6aHao LiuLEGlyphStorage::LEGlyphStorage()
2219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
2319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
2419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
2519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    // nothing else to do!
2619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
2719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
2819fdc268c316b3b0bdcb2b558449819f4f402d6aHao LiuLEGlyphStorage::~LEGlyphStorage()
2919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
3019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    reset();
3119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
3219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
3319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::reset()
3419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
3519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    fGlyphCount = 0;
3619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
3719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fPositions != NULL) {
3819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        LE_DELETE_ARRAY(fPositions);
3919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fPositions = NULL;
4019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
4119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
4219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fAuxData != NULL) {
4319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        LE_DELETE_ARRAY(fAuxData);
4419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fAuxData = NULL;
4519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
4619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
4719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fInsertionList != NULL) {
4819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        delete fInsertionList;
4919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fInsertionList = NULL;
5019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
5119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
5219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fCharIndices != NULL) {
5319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        LE_DELETE_ARRAY(fCharIndices);
5419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fCharIndices = NULL;
5519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
5619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
5719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fGlyphs != NULL) {
5819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        LE_DELETE_ARRAY(fGlyphs);
5919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fGlyphs = NULL;
6019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
6119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
6219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
6319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu// FIXME: This might get called more than once, for various reasons. Is
6419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu// testing for pre-existing glyph and charIndices arrays good enough?
6519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success)
6619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
6719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
6819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
6919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
7019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
7119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (initialGlyphCount <= 0) {
7219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_ILLEGAL_ARGUMENT_ERROR;
7319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
7419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
7519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
7619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fGlyphs == NULL) {
7719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fGlyphCount = initialGlyphCount;
7819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
7919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
8019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        if (fGlyphs == NULL) {
8119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            success = LE_MEMORY_ALLOCATION_ERROR;
8219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            return;
8319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        }
8419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
8519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
8619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fCharIndices == NULL) {
8719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
8819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
8919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        if (fCharIndices == NULL) {
9019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            LE_DELETE_ARRAY(fGlyphs);
9119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            fGlyphs = NULL;
9219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            success = LE_MEMORY_ALLOCATION_ERROR;
9319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            return;
9419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        }
9519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
9619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        // Initialize the charIndices array
9719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        le_int32 i, count = fGlyphCount, dir = 1, out = 0;
9819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
9919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        if (rightToLeft) {
10019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            out = fGlyphCount - 1;
10119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            dir = -1;
10219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        }
10319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
10419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        for (i = 0; i < count; i += 1, out += dir) {
10519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            fCharIndices[out] = i;
10619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        }
10719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
10819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
10919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fInsertionList == NULL) {
11019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        // FIXME: check this for failure?
11119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        fInsertionList = new LEInsertionList(rightToLeft);
11219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        if (fInsertionList == NULL) {
11319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            LE_DELETE_ARRAY(fCharIndices);
11419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            fCharIndices = NULL;
11519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
11619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            LE_DELETE_ARRAY(fGlyphs);
11719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            fGlyphs = NULL;
11819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
11919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            success = LE_MEMORY_ALLOCATION_ERROR;
12019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu            return;
12119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        }
12219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
12319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
12419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
12519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu// FIXME: do we want to initialize the positions to [0, 0]?
12619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liule_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
12719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
12819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
12919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
13019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
13119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
13219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fPositions != NULL) {
13319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INTERNAL_ERROR;
13419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
13519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
13619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
13719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
13819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
13919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fPositions == NULL) {
14019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_MEMORY_ALLOCATION_ERROR;
14119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
14219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
14319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
14419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    return fGlyphCount;
14519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
14619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
14719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu// FIXME: do we want to initialize the aux data to NULL?
14819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liule_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
14919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
15019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
15119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
15219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
15319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
15419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fAuxData != NULL) {
15519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INTERNAL_ERROR;
15619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
15719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
15819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
15919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount);
16019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
16119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fAuxData == NULL) {
16219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_MEMORY_ALLOCATION_ERROR;
16319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
16419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
16519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
16619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    return fGlyphCount;
16719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
16819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
16919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
17019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
17119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    le_int32 i;
17219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
17319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
17419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
17519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
17619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
17719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (charIndices == NULL) {
17819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_ILLEGAL_ARGUMENT_ERROR;
17919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
18019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
18119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
18219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fCharIndices == NULL) {
18319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
18419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
18519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
18619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
18719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    for (i = 0; i < fGlyphCount; i += 1) {
18819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        charIndices[i] = fCharIndices[i] + indexBase;
18919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
19019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
19119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
19219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
19319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
19419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
19519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
19619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
19719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
19819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (charIndices == NULL) {
19919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_ILLEGAL_ARGUMENT_ERROR;
20019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
20119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
20219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
20319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fCharIndices == NULL) {
20419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_NO_LAYOUT_ERROR;
20519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
20619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
20719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
20819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
20919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
21019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
21119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
21219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
21319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
21419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    le_int32 i;
21519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
21619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
21719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
21819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
21919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
22019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphs == NULL) {
22119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_ILLEGAL_ARGUMENT_ERROR;
22219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
22319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
22419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
22519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fGlyphs == NULL) {
22619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
22719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
22819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
22919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
23019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    for (i = 0; i < fGlyphCount; i += 1) {
23119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        glyphs[i] = fGlyphs[i] | extraBits;
23219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
23319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
23419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
23519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
23619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
23719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
23819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
23919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
24019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
24119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphs == NULL) {
24219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_ILLEGAL_ARGUMENT_ERROR;
24319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
24419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
24519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
24619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fGlyphs == NULL) {
24719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_NO_LAYOUT_ERROR;
24819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
24919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
25019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
25119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
25219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
25319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
25419fdc268c316b3b0bdcb2b558449819f4f402d6aHao LiuLEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
25519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
25619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
25719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return 0xFFFF;
25819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
25919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
26019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fGlyphs == NULL) {
26119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
26219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return 0xFFFF;
26319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
26419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
26519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
26619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
26719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return 0xFFFF;
26819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
26919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
27019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    return fGlyphs[glyphIndex];
27119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
27219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
27319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
27419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
27519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
27619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
27719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
27819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
27919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fGlyphs == NULL) {
28019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
28119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
28219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
28319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
28419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
28519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
28619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
28719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
28819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
28919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    fGlyphs[glyphIndex] = glyphID;
29019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
29119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
29219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liule_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
29319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
29419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
29519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
29619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
29719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
29819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fCharIndices == NULL) {
29919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
30019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
30119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
30219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
30319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
30419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
30519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return -1;
30619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
30719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
30819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    return fCharIndices[glyphIndex];
30919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
31019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
31119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
31219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
31319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
31419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
31519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
31619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
31719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fCharIndices == NULL) {
31819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
31919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
32019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
32119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
32219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
32319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
32419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
32519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
32619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
32719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    fCharIndices[glyphIndex] = charIndex;
32819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
32919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
33019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::getAuxData(le_uint32 auxData[], LEErrorCode &success) const
33119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
33219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
33319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
33419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
33519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
33619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (auxData == NULL) {
33719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_ILLEGAL_ARGUMENT_ERROR;
33819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
33919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
34019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
34119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fAuxData == NULL) {
34219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_NO_LAYOUT_ERROR;
34319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
34419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
34519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
34619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
34719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
34819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
34919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liule_uint32 LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
35019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
35119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
35219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return 0;
35319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
35419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
35519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fAuxData == NULL) {
35619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
35719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return 0;
35819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
35919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
36019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
36119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
36219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return 0;
36319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
36419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
36519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    return fAuxData[glyphIndex];
36619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
36719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
36819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success)
36919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
37019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
37119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
37219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
37319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
37419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fAuxData == NULL) {
37519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_NO_LAYOUT_ERROR;
37619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
37719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
37819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
37919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
38019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
38119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
38219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
38319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
38419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    fAuxData[glyphIndex] = auxData;
38519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
38619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
38719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
38819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
38919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
39019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
39119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
39219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
39319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (positions == NULL) {
39419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_ILLEGAL_ARGUMENT_ERROR;
39519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
39619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
39719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
39819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fPositions == NULL) {
39919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_NO_LAYOUT_ERROR;
40019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
40119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
40219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
40319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
40419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
40519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
40619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
40719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
40819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
40919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
41019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
41119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
41219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
41319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
41419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
41519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
41619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
41719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (fPositions == NULL) {
41819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_NO_LAYOUT_ERROR;
41919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
42019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
42119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
42219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    x = fPositions[glyphIndex * 2];
42319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    y = fPositions[glyphIndex * 2 + 1];
42419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu}
42519fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
42619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liuvoid LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
42719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu{
42819fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (LE_FAILURE(success)) {
42919fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu        return;
43019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    }
43119fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu
43219fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
43319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
43419fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return;
435    }
436
437    fPositions[glyphIndex * 2]     = x;
438    fPositions[glyphIndex * 2 + 1] = y;
439}
440
441void LEGlyphStorage::adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success)
442{
443    if (LE_FAILURE(success)) {
444        return;
445    }
446
447    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
448      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
449      return;
450    }
451
452    fPositions[glyphIndex * 2]     += xAdjust;
453    fPositions[glyphIndex * 2 + 1] += yAdjust;
454}
455
456void LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
457{
458    if (fGlyphs != NULL) {
459        LE_DELETE_ARRAY(fGlyphs);
460    }
461
462    fGlyphs = from.fGlyphs;
463    from.fGlyphs = NULL;
464
465    if (fInsertionList != NULL) {
466        delete fInsertionList;
467    }
468
469    fInsertionList = from.fInsertionList;
470    from.fInsertionList = NULL;
471}
472
473void LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
474{
475    if (fCharIndices != NULL) {
476        LE_DELETE_ARRAY(fCharIndices);
477    }
478
479    fCharIndices = from.fCharIndices;
480    from.fCharIndices = NULL;
481}
482
483void LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
484{
485    if (fPositions != NULL) {
486        LE_DELETE_ARRAY(fPositions);
487    }
488
489    fPositions = from.fPositions;
490    from.fPositions = NULL;
491}
492
493void LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
494{
495    if (fAuxData != NULL) {
496        LE_DELETE_ARRAY(fAuxData);
497    }
498
499    fAuxData = from.fAuxData;
500    from.fAuxData = NULL;
501}
502
503void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
504{
505    fGlyphCount = from.fGlyphCount;
506}
507
508void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
509{
510    fGlyphCount = newGlyphCount;
511}
512
513// Move a glyph to a different position in the LEGlyphStorage ( used for Indic v2 processing )
514
515void LEGlyphStorage::moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker )
516{
517
518    LEErrorCode success = LE_NO_ERROR;
519
520    LEGlyphID holdGlyph = getGlyphID(fromPosition,success);
521    le_int32 holdCharIndex = getCharIndex(fromPosition,success);
522    le_uint32 holdAuxData = getAuxData(fromPosition,success);
523
524    if ( fromPosition < toPosition ) {
525        for ( le_int32 i = fromPosition ; i < toPosition ; i++ ) {
526            setGlyphID(i,getGlyphID(i+1,success),success);
527            setCharIndex(i,getCharIndex(i+1,success),success);
528            setAuxData(i,getAuxData(i+1,success),success);
529        }
530    } else {
531        for ( le_int32 i = toPosition ; i > fromPosition ; i-- ) {
532            setGlyphID(i,getGlyphID(i-1,success),success);
533            setCharIndex(i,getCharIndex(i-1,success),success);
534            setAuxData(i,getAuxData(i-1,success),success);
535
536        }
537    }
538
539    setGlyphID(toPosition,holdGlyph,success);
540    setCharIndex(toPosition,holdCharIndex,success);
541    setAuxData(toPosition,holdAuxData | marker,success);
542
543}
544
545// Glue code for existing stable API
546LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32  atIndex, le_int32 insertCount)
547{
548    LEErrorCode ignored = LE_NO_LAYOUT_ERROR;
549    return insertGlyphs(atIndex, insertCount, ignored);
550}
551
552// FIXME: add error checking?
553LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32  atIndex, le_int32 insertCount, LEErrorCode& success)
554{
555    return fInsertionList->insert(atIndex, insertCount, success);
556}
557
558le_int32 LEGlyphStorage::applyInsertions()
559{
560    le_int32 growAmount = fInsertionList->getGrowAmount();
561
562    if (growAmount == 0) {
563        return fGlyphCount;
564    }
565
566    le_int32 newGlyphCount = fGlyphCount + growAmount;
567
568    LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
569    if (newGlyphs == NULL) {
570        // Could not grow the glyph array
571        return fGlyphCount;
572    }
573    fGlyphs = newGlyphs;
574
575    le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
576    if (newCharIndices == NULL) {
577        // Could not grow the glyph array
578        return fGlyphCount;
579    }
580    fCharIndices = newCharIndices;
581
582    if (fAuxData != NULL) {
583        le_uint32 *newAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount);
584        if (newAuxData == NULL) {
585            // could not grow the aux data array
586            return fGlyphCount;
587        }
588        fAuxData = (le_uint32 *)newAuxData;
589    }
590
591    fSrcIndex  = fGlyphCount - 1;
592    fDestIndex = newGlyphCount - 1;
593
594#if 0
595    // If the current position is at the end of the array
596    // update it to point to the end of the new array. The
597    // insertion callback will handle all other cases.
598    // FIXME: this is left over from GlyphIterator, but there's no easy
599    // way to implement this here... it seems that GlyphIterator doesn't
600    // really need it 'cause the insertions don't get  applied until after a
601    // complete pass over the glyphs, after which the iterator gets reset anyhow...
602    // probably better to just document that for LEGlyphStorage and GlyphIterator...
603    if (position == glyphCount) {
604        position = newGlyphCount;
605    }
606#endif
607
608    fInsertionList->applyInsertions(this);
609
610    fInsertionList->reset();
611
612    return fGlyphCount = newGlyphCount;
613}
614
615le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
616{
617#if 0
618    // if the current position is within the block we're shifting
619    // it needs to be updated to the current glyph's
620    // new location.
621    // FIXME: this is left over from GlyphIterator, but there's no easy
622    // way to implement this here... it seems that GlyphIterator doesn't
623    // really need it 'cause the insertions don't get  applied until after a
624    // complete pass over the glyphs, after which the iterator gets reset anyhow...
625    // probably better to just document that for LEGlyphStorage and GlyphIterator...
626    if (position >= atPosition && position <= fSrcIndex) {
627        position += fDestIndex - fSrcIndex;
628    }
629#endif
630
631    if (fAuxData != NULL) {
632        le_int32 src = fSrcIndex, dest = fDestIndex;
633
634        while (src > atPosition) {
635            fAuxData[dest--] = fAuxData[src--];
636        }
637
638        for (le_int32 i = count - 1; i >= 0; i -= 1) {
639            fAuxData[dest--] = fAuxData[atPosition];
640        }
641    }
642
643    while (fSrcIndex > atPosition) {
644        fGlyphs[fDestIndex]      = fGlyphs[fSrcIndex];
645        fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
646
647        fDestIndex -= 1;
648        fSrcIndex  -= 1;
649    }
650
651    for (le_int32 i = count - 1; i >= 0; i -= 1) {
652        fGlyphs[fDestIndex]      = newGlyphs[i];
653        fCharIndices[fDestIndex] = fCharIndices[atPosition];
654
655        fDestIndex -= 1;
656    }
657
658    // the source glyph we're pointing at
659    // just got replaced by the insertion
660    fSrcIndex -= 1;
661
662    return FALSE;
663}
664
665U_NAMESPACE_END
666
667