os/textandloc/fontservices/textshaperplugin/IcuSource/layout/LEGlyphStorage.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
 **********************************************************************
sl@0
     3
 *   Copyright (C) 1998-2004, International Business Machines
sl@0
     4
 *   Corporation and others.  All Rights Reserved.
sl@0
     5
 **********************************************************************
sl@0
     6
 */
sl@0
     7
sl@0
     8
#include "LETypes.h"
sl@0
     9
#include "LEInsertionList.h"
sl@0
    10
#include "LEGlyphStorage.h"
sl@0
    11
sl@0
    12
U_NAMESPACE_BEGIN
sl@0
    13
sl@0
    14
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
sl@0
    15
sl@0
    16
LEGlyphStorage::LEGlyphStorage()
sl@0
    17
    : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
sl@0
    18
      fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
sl@0
    19
{
sl@0
    20
    // nothing else to do!
sl@0
    21
}
sl@0
    22
sl@0
    23
LEGlyphStorage::~LEGlyphStorage()
sl@0
    24
{
sl@0
    25
    reset();
sl@0
    26
}
sl@0
    27
sl@0
    28
void LEGlyphStorage::reset()
sl@0
    29
{
sl@0
    30
    fGlyphCount = 0;
sl@0
    31
sl@0
    32
    if (fPositions != NULL) {
sl@0
    33
        LE_DELETE_ARRAY(fPositions);
sl@0
    34
        fPositions = NULL;
sl@0
    35
    }
sl@0
    36
sl@0
    37
    if (fAuxData != NULL) {
sl@0
    38
        LE_DELETE_ARRAY(fAuxData);
sl@0
    39
        fAuxData = NULL;
sl@0
    40
    }
sl@0
    41
sl@0
    42
    if (fInsertionList != NULL) {
sl@0
    43
        delete fInsertionList;
sl@0
    44
        fInsertionList = NULL;
sl@0
    45
    }
sl@0
    46
sl@0
    47
    if (fCharIndices != NULL) {
sl@0
    48
        LE_DELETE_ARRAY(fCharIndices);
sl@0
    49
        fCharIndices = NULL;
sl@0
    50
    }
sl@0
    51
sl@0
    52
    if (fGlyphs != NULL) {
sl@0
    53
        LE_DELETE_ARRAY(fGlyphs);
sl@0
    54
        fGlyphs = NULL;
sl@0
    55
    }
sl@0
    56
}
sl@0
    57
sl@0
    58
// FIXME: This might get called more than once, for various reasons. Is
sl@0
    59
// testing for pre-existing glyph and charIndices arrays good enough?
sl@0
    60
void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success)
sl@0
    61
{
sl@0
    62
    if (LE_FAILURE(success)) {
sl@0
    63
        return;
sl@0
    64
    }
sl@0
    65
sl@0
    66
    if (initialGlyphCount <= 0) {
sl@0
    67
        success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
    68
        return;
sl@0
    69
    }
sl@0
    70
sl@0
    71
    if (fGlyphs == NULL) {
sl@0
    72
        fGlyphCount = initialGlyphCount;
sl@0
    73
        fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
sl@0
    74
sl@0
    75
        if (fGlyphs == NULL) {
sl@0
    76
            success = LE_MEMORY_ALLOCATION_ERROR;
sl@0
    77
            return;
sl@0
    78
        }
sl@0
    79
    }
sl@0
    80
sl@0
    81
    if (fCharIndices == NULL) {
sl@0
    82
        fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
sl@0
    83
sl@0
    84
        if (fCharIndices == NULL) {
sl@0
    85
            LE_DELETE_ARRAY(fGlyphs);
sl@0
    86
            fGlyphs = NULL;
sl@0
    87
            success = LE_MEMORY_ALLOCATION_ERROR;
sl@0
    88
            return;
sl@0
    89
        }
sl@0
    90
sl@0
    91
        // Initialize the charIndices array
sl@0
    92
        le_int32 i, count = fGlyphCount, dir = 1, out = 0;
sl@0
    93
sl@0
    94
        if (rightToLeft) {
sl@0
    95
            out = fGlyphCount - 1;
sl@0
    96
            dir = -1;
sl@0
    97
        }
sl@0
    98
sl@0
    99
        for (i = 0; i < count; i += 1, out += dir) {
sl@0
   100
            fCharIndices[out] = i;
sl@0
   101
        }
sl@0
   102
    }
sl@0
   103
sl@0
   104
    if (fInsertionList == NULL) {
sl@0
   105
        fInsertionList = new LEInsertionList(rightToLeft);
sl@0
   106
        if (fInsertionList == NULL) {
sl@0
   107
            LE_DELETE_ARRAY(fCharIndices);
sl@0
   108
            fCharIndices = NULL;
sl@0
   109
            LE_DELETE_ARRAY(fGlyphs);
sl@0
   110
            fGlyphs = NULL;
sl@0
   111
            success = LE_MEMORY_ALLOCATION_ERROR;
sl@0
   112
            return;
sl@0
   113
        }
sl@0
   114
    }
sl@0
   115
}
sl@0
   116
sl@0
   117
// FIXME: do we want to initialize the positions to [0, 0]?
sl@0
   118
le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
sl@0
   119
{
sl@0
   120
    if (LE_FAILURE(success)) {
sl@0
   121
        return -1;
sl@0
   122
    }
sl@0
   123
sl@0
   124
    if (fPositions != NULL) {
sl@0
   125
        LE_DELETE_ARRAY(fPositions);
sl@0
   126
    }
sl@0
   127
sl@0
   128
    fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
sl@0
   129
sl@0
   130
    if (fPositions == NULL) {
sl@0
   131
        success = LE_MEMORY_ALLOCATION_ERROR;
sl@0
   132
        return -1;
sl@0
   133
    }
sl@0
   134
sl@0
   135
    return fGlyphCount;
sl@0
   136
}
sl@0
   137
sl@0
   138
// FIXME: do we want to initialize the aux data to NULL?
sl@0
   139
le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
sl@0
   140
{
sl@0
   141
    if (LE_FAILURE(success)) {
sl@0
   142
        return -1;
sl@0
   143
    }
sl@0
   144
sl@0
   145
    fAuxData = LE_NEW_ARRAY(void *, fGlyphCount);
sl@0
   146
sl@0
   147
    if (fAuxData == NULL) {
sl@0
   148
        success = LE_MEMORY_ALLOCATION_ERROR;
sl@0
   149
        return -1;
sl@0
   150
    }
sl@0
   151
sl@0
   152
    return fGlyphCount;
sl@0
   153
}
sl@0
   154
sl@0
   155
void LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
sl@0
   156
{
sl@0
   157
    le_int32 i;
sl@0
   158
sl@0
   159
    if (LE_FAILURE(success)) {
sl@0
   160
        return;
sl@0
   161
    }
sl@0
   162
sl@0
   163
    if (charIndices == NULL) {
sl@0
   164
        success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   165
        return;
sl@0
   166
    }
sl@0
   167
sl@0
   168
    if (fCharIndices == NULL) {
sl@0
   169
        success = LE_NO_LAYOUT_ERROR;
sl@0
   170
        return;
sl@0
   171
    }
sl@0
   172
sl@0
   173
    for (i = 0; i < fGlyphCount; i += 1) {
sl@0
   174
        charIndices[i] = fCharIndices[i] + indexBase;
sl@0
   175
    }
sl@0
   176
}
sl@0
   177
sl@0
   178
void LEGlyphStorage::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
sl@0
   179
{
sl@0
   180
    if (LE_FAILURE(success)) {
sl@0
   181
      return;
sl@0
   182
    }
sl@0
   183
    
sl@0
   184
    if (charIndices == NULL) {
sl@0
   185
      success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   186
      return;
sl@0
   187
    }
sl@0
   188
    
sl@0
   189
    if (fCharIndices == NULL) {
sl@0
   190
      success = LE_NO_LAYOUT_ERROR;
sl@0
   191
      return;
sl@0
   192
    }
sl@0
   193
    
sl@0
   194
    LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
sl@0
   195
}
sl@0
   196
sl@0
   197
// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
sl@0
   198
void LEGlyphStorage::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
sl@0
   199
{
sl@0
   200
    le_int32 i;
sl@0
   201
sl@0
   202
    if (LE_FAILURE(success)) {
sl@0
   203
        return;
sl@0
   204
    }
sl@0
   205
sl@0
   206
    if (glyphs == NULL) {
sl@0
   207
        success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   208
        return;
sl@0
   209
    }
sl@0
   210
sl@0
   211
    if (fGlyphs == NULL) {
sl@0
   212
        success = LE_NO_LAYOUT_ERROR;
sl@0
   213
        return;
sl@0
   214
    }
sl@0
   215
sl@0
   216
    for (i = 0; i < fGlyphCount; i += 1) {
sl@0
   217
        glyphs[i] = fGlyphs[i] | extraBits;
sl@0
   218
    }
sl@0
   219
}
sl@0
   220
sl@0
   221
void LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
sl@0
   222
{
sl@0
   223
    if (LE_FAILURE(success)) {
sl@0
   224
      return;
sl@0
   225
    }
sl@0
   226
    
sl@0
   227
    if (glyphs == NULL) {
sl@0
   228
      success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   229
      return;
sl@0
   230
    }
sl@0
   231
    
sl@0
   232
    if (fGlyphs == NULL) {
sl@0
   233
      success = LE_NO_LAYOUT_ERROR;
sl@0
   234
      return;
sl@0
   235
    }
sl@0
   236
    
sl@0
   237
    LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
sl@0
   238
}
sl@0
   239
sl@0
   240
LEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
sl@0
   241
{
sl@0
   242
    if (LE_FAILURE(success)) {
sl@0
   243
        return 0xFFFF;
sl@0
   244
    }
sl@0
   245
sl@0
   246
    if (fGlyphs == NULL) {
sl@0
   247
        success = LE_NO_LAYOUT_ERROR;
sl@0
   248
        return 0xFFFF;
sl@0
   249
    }
sl@0
   250
sl@0
   251
    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
sl@0
   252
        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   253
        return 0xFFFF;
sl@0
   254
    }
sl@0
   255
sl@0
   256
    return fGlyphs[glyphIndex];
sl@0
   257
}
sl@0
   258
sl@0
   259
void LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
sl@0
   260
{
sl@0
   261
    if (LE_FAILURE(success)) {
sl@0
   262
        return;
sl@0
   263
    }
sl@0
   264
sl@0
   265
    if (fGlyphs == NULL) {
sl@0
   266
        success = LE_NO_LAYOUT_ERROR;
sl@0
   267
        return;
sl@0
   268
    }
sl@0
   269
sl@0
   270
    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
sl@0
   271
        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   272
        return;
sl@0
   273
    }
sl@0
   274
sl@0
   275
    fGlyphs[glyphIndex] = glyphID;
sl@0
   276
}
sl@0
   277
sl@0
   278
le_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
sl@0
   279
{
sl@0
   280
    if (LE_FAILURE(success)) {
sl@0
   281
        return -1;
sl@0
   282
    }
sl@0
   283
sl@0
   284
    if (fCharIndices == NULL) {
sl@0
   285
        success = LE_NO_LAYOUT_ERROR;
sl@0
   286
        return -1;
sl@0
   287
    }
sl@0
   288
sl@0
   289
    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
sl@0
   290
        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   291
        return -1;
sl@0
   292
    }
sl@0
   293
sl@0
   294
    return fCharIndices[glyphIndex];
sl@0
   295
}
sl@0
   296
sl@0
   297
void LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
sl@0
   298
{
sl@0
   299
    if (LE_FAILURE(success)) {
sl@0
   300
        return;
sl@0
   301
    }
sl@0
   302
sl@0
   303
    if (fCharIndices == NULL) {
sl@0
   304
        success = LE_NO_LAYOUT_ERROR;
sl@0
   305
        return;
sl@0
   306
    }
sl@0
   307
sl@0
   308
    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
sl@0
   309
        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   310
        return;
sl@0
   311
    }
sl@0
   312
sl@0
   313
    fCharIndices[glyphIndex] = charIndex;
sl@0
   314
}
sl@0
   315
sl@0
   316
void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const
sl@0
   317
{
sl@0
   318
    if (LE_FAILURE(success)) {
sl@0
   319
      return;
sl@0
   320
    }
sl@0
   321
    
sl@0
   322
    if (auxData == NULL) {
sl@0
   323
      success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   324
      return;
sl@0
   325
    }
sl@0
   326
    
sl@0
   327
    if (fAuxData == NULL) {
sl@0
   328
      success = LE_NO_LAYOUT_ERROR;
sl@0
   329
      return;
sl@0
   330
    }
sl@0
   331
    
sl@0
   332
    LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
sl@0
   333
}
sl@0
   334
sl@0
   335
void *LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
sl@0
   336
{
sl@0
   337
    if (LE_FAILURE(success)) {
sl@0
   338
        return NULL;
sl@0
   339
    }
sl@0
   340
sl@0
   341
    if (fAuxData == NULL) {
sl@0
   342
        success = LE_NO_LAYOUT_ERROR;
sl@0
   343
        return NULL;
sl@0
   344
    }
sl@0
   345
    
sl@0
   346
    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
sl@0
   347
        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   348
        return NULL;
sl@0
   349
    }
sl@0
   350
sl@0
   351
    return fAuxData[glyphIndex];
sl@0
   352
}
sl@0
   353
sl@0
   354
void LEGlyphStorage::setAuxData(le_int32 glyphIndex, void *auxData, LEErrorCode &success)
sl@0
   355
{
sl@0
   356
    if (LE_FAILURE(success)) {
sl@0
   357
        return;
sl@0
   358
    }
sl@0
   359
sl@0
   360
    if (fAuxData == NULL) {
sl@0
   361
        success = LE_NO_LAYOUT_ERROR;
sl@0
   362
        return;
sl@0
   363
    }
sl@0
   364
sl@0
   365
    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
sl@0
   366
        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   367
        return;
sl@0
   368
    }
sl@0
   369
sl@0
   370
    fAuxData[glyphIndex] = auxData;
sl@0
   371
}
sl@0
   372
sl@0
   373
void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
sl@0
   374
{
sl@0
   375
    if (LE_FAILURE(success)) {
sl@0
   376
      return;
sl@0
   377
    }
sl@0
   378
  
sl@0
   379
    if (positions == NULL) {
sl@0
   380
      success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   381
      return;
sl@0
   382
    }
sl@0
   383
    
sl@0
   384
    if (fPositions == NULL) {
sl@0
   385
      success = LE_NO_LAYOUT_ERROR;
sl@0
   386
      return;
sl@0
   387
    }
sl@0
   388
    
sl@0
   389
    LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
sl@0
   390
}
sl@0
   391
sl@0
   392
void LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
sl@0
   393
{
sl@0
   394
    if (LE_FAILURE(success)) {
sl@0
   395
      return;
sl@0
   396
    }
sl@0
   397
    
sl@0
   398
    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
sl@0
   399
      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   400
      return;
sl@0
   401
    }
sl@0
   402
    
sl@0
   403
    if (fPositions == NULL) {
sl@0
   404
      success = LE_NO_LAYOUT_ERROR;
sl@0
   405
      return;
sl@0
   406
    }
sl@0
   407
    
sl@0
   408
    x = fPositions[glyphIndex * 2];
sl@0
   409
    y = fPositions[glyphIndex * 2 + 1];
sl@0
   410
}
sl@0
   411
sl@0
   412
void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
sl@0
   413
{
sl@0
   414
    if (LE_FAILURE(success)) {
sl@0
   415
        return;
sl@0
   416
    }
sl@0
   417
    
sl@0
   418
    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
sl@0
   419
      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   420
      return;
sl@0
   421
    }
sl@0
   422
    
sl@0
   423
    fPositions[glyphIndex * 2]     = x;
sl@0
   424
    fPositions[glyphIndex * 2 + 1] = y;
sl@0
   425
}
sl@0
   426
sl@0
   427
void LEGlyphStorage::adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success)
sl@0
   428
{
sl@0
   429
    if (LE_FAILURE(success)) {
sl@0
   430
        return;
sl@0
   431
    }
sl@0
   432
    
sl@0
   433
    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
sl@0
   434
      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
sl@0
   435
      return;
sl@0
   436
    }
sl@0
   437
    
sl@0
   438
    fPositions[glyphIndex * 2]     += xAdjust;
sl@0
   439
    fPositions[glyphIndex * 2 + 1] += yAdjust;
sl@0
   440
}
sl@0
   441
sl@0
   442
void LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
sl@0
   443
{
sl@0
   444
    if (fGlyphs != NULL) {
sl@0
   445
        LE_DELETE_ARRAY(fGlyphs);
sl@0
   446
    }
sl@0
   447
sl@0
   448
    fGlyphs = from.fGlyphs;
sl@0
   449
    from.fGlyphs = NULL;
sl@0
   450
sl@0
   451
    if (fInsertionList != NULL) {
sl@0
   452
        delete fInsertionList;
sl@0
   453
    }
sl@0
   454
sl@0
   455
    fInsertionList = from.fInsertionList;
sl@0
   456
    from.fInsertionList = NULL;
sl@0
   457
}
sl@0
   458
sl@0
   459
void LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
sl@0
   460
{
sl@0
   461
    if (fCharIndices != NULL) {
sl@0
   462
        LE_DELETE_ARRAY(fCharIndices);
sl@0
   463
    }
sl@0
   464
sl@0
   465
    fCharIndices = from.fCharIndices;
sl@0
   466
    from.fCharIndices = NULL;
sl@0
   467
}
sl@0
   468
sl@0
   469
void LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
sl@0
   470
{
sl@0
   471
    if (fPositions != NULL) {
sl@0
   472
        LE_DELETE_ARRAY(fPositions);
sl@0
   473
    }
sl@0
   474
sl@0
   475
    fPositions = from.fPositions;
sl@0
   476
    from.fPositions = NULL;
sl@0
   477
}
sl@0
   478
sl@0
   479
void LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
sl@0
   480
{
sl@0
   481
    if (fAuxData != NULL) {
sl@0
   482
        LE_DELETE_ARRAY(fAuxData);
sl@0
   483
    }
sl@0
   484
sl@0
   485
    fAuxData = from.fAuxData;
sl@0
   486
    from.fAuxData = NULL;
sl@0
   487
}
sl@0
   488
sl@0
   489
void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
sl@0
   490
{
sl@0
   491
    fGlyphCount = from.fGlyphCount;
sl@0
   492
}
sl@0
   493
sl@0
   494
void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
sl@0
   495
{
sl@0
   496
    fGlyphCount = newGlyphCount;
sl@0
   497
}
sl@0
   498
sl@0
   499
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32  atIndex, le_int32 insertCount,
sl@0
   500
    LEErrorCode& success)
sl@0
   501
{
sl@0
   502
    return fInsertionList->insert(atIndex, insertCount, success);
sl@0
   503
}
sl@0
   504
sl@0
   505
le_int32 LEGlyphStorage::applyInsertions()
sl@0
   506
{
sl@0
   507
    le_int32 growAmount = fInsertionList->getGrowAmount();
sl@0
   508
sl@0
   509
    if (growAmount == 0) {
sl@0
   510
        return fGlyphCount;
sl@0
   511
    }
sl@0
   512
sl@0
   513
    le_int32 newGlyphCount = fGlyphCount + growAmount;
sl@0
   514
sl@0
   515
    LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
sl@0
   516
    if (!newGlyphs) {
sl@0
   517
        // Could not grow the glyph array
sl@0
   518
        return fGlyphCount;
sl@0
   519
    }
sl@0
   520
    fGlyphs = newGlyphs;
sl@0
   521
sl@0
   522
    le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
sl@0
   523
    if (!newCharIndices) {
sl@0
   524
        // Could not grow the glyph array
sl@0
   525
        return fGlyphCount;
sl@0
   526
    }
sl@0
   527
    fCharIndices = newCharIndices;
sl@0
   528
sl@0
   529
    if (fAuxData != NULL) {
sl@0
   530
        void **newAuxData = (void **) LE_GROW_ARRAY(fAuxData, newGlyphCount);
sl@0
   531
        if (!newAuxData) {
sl@0
   532
            // could not grow the aux data array
sl@0
   533
            return fGlyphCount;
sl@0
   534
        }
sl@0
   535
        fAuxData = newAuxData;
sl@0
   536
    }
sl@0
   537
sl@0
   538
    fSrcIndex  = fGlyphCount - 1;
sl@0
   539
    fDestIndex = newGlyphCount - 1;
sl@0
   540
sl@0
   541
#if 0
sl@0
   542
    // If the current position is at the end of the array
sl@0
   543
    // update it to point to the end of the new array. The
sl@0
   544
    // insertion callback will handle all other cases.
sl@0
   545
    // FIXME: this is left over from GlyphIterator, but there's no easy
sl@0
   546
    // way to implement this here... it seems that GlyphIterator doesn't
sl@0
   547
    // really need it 'cause the insertions don't get  applied until after a
sl@0
   548
    // complete pass over the glyphs, after which the iterator gets reset anyhow...
sl@0
   549
    // probably better to just document that for LEGlyphStorage and GlyphIterator...
sl@0
   550
    if (position == glyphCount) {
sl@0
   551
        position = newGlyphCount;
sl@0
   552
    }
sl@0
   553
#endif
sl@0
   554
sl@0
   555
    fInsertionList->applyInsertions(this);
sl@0
   556
sl@0
   557
    fInsertionList->reset();
sl@0
   558
sl@0
   559
    return fGlyphCount = newGlyphCount;
sl@0
   560
}
sl@0
   561
sl@0
   562
le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
sl@0
   563
{
sl@0
   564
#if 0
sl@0
   565
    // if the current position is within the block we're shifting
sl@0
   566
    // it needs to be updated to the current glyph's
sl@0
   567
    // new location.
sl@0
   568
    // FIXME: this is left over from GlyphIterator, but there's no easy
sl@0
   569
    // way to implement this here... it seems that GlyphIterator doesn't
sl@0
   570
    // really need it 'cause the insertions don't get  applied until after a
sl@0
   571
    // complete pass over the glyphs, after which the iterator gets reset anyhow...
sl@0
   572
    // probably better to just document that for LEGlyphStorage and GlyphIterator...
sl@0
   573
    if (position >= atPosition && position <= fSrcIndex) {
sl@0
   574
        position += fDestIndex - fSrcIndex;
sl@0
   575
    }
sl@0
   576
#endif
sl@0
   577
sl@0
   578
    if (fAuxData != NULL) {
sl@0
   579
        le_int32 src = fSrcIndex, dest = fDestIndex;
sl@0
   580
sl@0
   581
        while (src > atPosition) {
sl@0
   582
            fAuxData[dest--] = fAuxData[src--];
sl@0
   583
        }
sl@0
   584
sl@0
   585
        for (le_int32 i = count - 1; i >= 0; i -= 1) {
sl@0
   586
            fAuxData[dest--] = fAuxData[atPosition];
sl@0
   587
        }
sl@0
   588
    }
sl@0
   589
sl@0
   590
    while (fSrcIndex > atPosition) {
sl@0
   591
        fGlyphs[fDestIndex]      = fGlyphs[fSrcIndex];
sl@0
   592
        fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
sl@0
   593
sl@0
   594
        fDestIndex -= 1;
sl@0
   595
        fSrcIndex  -= 1;
sl@0
   596
    }
sl@0
   597
sl@0
   598
    for (le_int32 i = count - 1; i >= 0; i -= 1) {
sl@0
   599
        fGlyphs[fDestIndex]      = newGlyphs[i];
sl@0
   600
        fCharIndices[fDestIndex] = fCharIndices[atPosition];
sl@0
   601
sl@0
   602
        fDestIndex -= 1;
sl@0
   603
    }
sl@0
   604
sl@0
   605
    // the source glyph we're pointing at
sl@0
   606
    // just got replaced by the insertion
sl@0
   607
    fSrcIndex -= 1;
sl@0
   608
sl@0
   609
    return FALSE;
sl@0
   610
}
sl@0
   611
sl@0
   612
void LEGlyphStorage::forMlylRakar(LEGlyphID aGlyphID)
sl@0
   613
{
sl@0
   614
    le_int32 i, j;    
sl@0
   615
sl@0
   616
    if (fGlyphs == NULL) {
sl@0
   617
        return;
sl@0
   618
    }
sl@0
   619
sl@0
   620
    for (i = 0; i < fGlyphCount; i++) {
sl@0
   621
        if (fGlyphs[i] == aGlyphID) {
sl@0
   622
        	j = i - 1;
sl@0
   623
        	while (j>=0 && fGlyphs[j] == 0xFFFF) {
sl@0
   624
        		j--;
sl@0
   625
        	}
sl@0
   626
        	
sl@0
   627
        	if (j>=0 && fGlyphs[j] != 0xFFFF && fGlyphs[j] != aGlyphID) {
sl@0
   628
        		fGlyphs[i] = fGlyphs[j];
sl@0
   629
        		fGlyphs[j] = aGlyphID;
sl@0
   630
        		
sl@0
   631
        		le_int32 tempCharIndex = fCharIndices[j];
sl@0
   632
        		fCharIndices[j] = fCharIndices[i];
sl@0
   633
        		fCharIndices[i] = tempCharIndex;
sl@0
   634
        		
sl@0
   635
        		void * tempAuxData = fAuxData[j];
sl@0
   636
        		fAuxData[j] = fAuxData[i];
sl@0
   637
        		fAuxData[i] = fAuxData[j];
sl@0
   638
        	}
sl@0
   639
        }        	
sl@0
   640
    }
sl@0
   641
}
sl@0
   642
sl@0
   643
U_NAMESPACE_END
sl@0
   644