os/textandloc/fontservices/textshaperplugin/IcuSource/layout/LEGlyphStorage.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/LEGlyphStorage.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,644 @@
     1.4 +/*
     1.5 + **********************************************************************
     1.6 + *   Copyright (C) 1998-2004, International Business Machines
     1.7 + *   Corporation and others.  All Rights Reserved.
     1.8 + **********************************************************************
     1.9 + */
    1.10 +
    1.11 +#include "LETypes.h"
    1.12 +#include "LEInsertionList.h"
    1.13 +#include "LEGlyphStorage.h"
    1.14 +
    1.15 +U_NAMESPACE_BEGIN
    1.16 +
    1.17 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
    1.18 +
    1.19 +LEGlyphStorage::LEGlyphStorage()
    1.20 +    : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
    1.21 +      fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
    1.22 +{
    1.23 +    // nothing else to do!
    1.24 +}
    1.25 +
    1.26 +LEGlyphStorage::~LEGlyphStorage()
    1.27 +{
    1.28 +    reset();
    1.29 +}
    1.30 +
    1.31 +void LEGlyphStorage::reset()
    1.32 +{
    1.33 +    fGlyphCount = 0;
    1.34 +
    1.35 +    if (fPositions != NULL) {
    1.36 +        LE_DELETE_ARRAY(fPositions);
    1.37 +        fPositions = NULL;
    1.38 +    }
    1.39 +
    1.40 +    if (fAuxData != NULL) {
    1.41 +        LE_DELETE_ARRAY(fAuxData);
    1.42 +        fAuxData = NULL;
    1.43 +    }
    1.44 +
    1.45 +    if (fInsertionList != NULL) {
    1.46 +        delete fInsertionList;
    1.47 +        fInsertionList = NULL;
    1.48 +    }
    1.49 +
    1.50 +    if (fCharIndices != NULL) {
    1.51 +        LE_DELETE_ARRAY(fCharIndices);
    1.52 +        fCharIndices = NULL;
    1.53 +    }
    1.54 +
    1.55 +    if (fGlyphs != NULL) {
    1.56 +        LE_DELETE_ARRAY(fGlyphs);
    1.57 +        fGlyphs = NULL;
    1.58 +    }
    1.59 +}
    1.60 +
    1.61 +// FIXME: This might get called more than once, for various reasons. Is
    1.62 +// testing for pre-existing glyph and charIndices arrays good enough?
    1.63 +void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success)
    1.64 +{
    1.65 +    if (LE_FAILURE(success)) {
    1.66 +        return;
    1.67 +    }
    1.68 +
    1.69 +    if (initialGlyphCount <= 0) {
    1.70 +        success = LE_ILLEGAL_ARGUMENT_ERROR;
    1.71 +        return;
    1.72 +    }
    1.73 +
    1.74 +    if (fGlyphs == NULL) {
    1.75 +        fGlyphCount = initialGlyphCount;
    1.76 +        fGlyphs = LE_NEW_ARRAY(LEGlyphID, fGlyphCount);
    1.77 +
    1.78 +        if (fGlyphs == NULL) {
    1.79 +            success = LE_MEMORY_ALLOCATION_ERROR;
    1.80 +            return;
    1.81 +        }
    1.82 +    }
    1.83 +
    1.84 +    if (fCharIndices == NULL) {
    1.85 +        fCharIndices = LE_NEW_ARRAY(le_int32, fGlyphCount);
    1.86 +
    1.87 +        if (fCharIndices == NULL) {
    1.88 +            LE_DELETE_ARRAY(fGlyphs);
    1.89 +            fGlyphs = NULL;
    1.90 +            success = LE_MEMORY_ALLOCATION_ERROR;
    1.91 +            return;
    1.92 +        }
    1.93 +
    1.94 +        // Initialize the charIndices array
    1.95 +        le_int32 i, count = fGlyphCount, dir = 1, out = 0;
    1.96 +
    1.97 +        if (rightToLeft) {
    1.98 +            out = fGlyphCount - 1;
    1.99 +            dir = -1;
   1.100 +        }
   1.101 +
   1.102 +        for (i = 0; i < count; i += 1, out += dir) {
   1.103 +            fCharIndices[out] = i;
   1.104 +        }
   1.105 +    }
   1.106 +
   1.107 +    if (fInsertionList == NULL) {
   1.108 +        fInsertionList = new LEInsertionList(rightToLeft);
   1.109 +        if (fInsertionList == NULL) {
   1.110 +            LE_DELETE_ARRAY(fCharIndices);
   1.111 +            fCharIndices = NULL;
   1.112 +            LE_DELETE_ARRAY(fGlyphs);
   1.113 +            fGlyphs = NULL;
   1.114 +            success = LE_MEMORY_ALLOCATION_ERROR;
   1.115 +            return;
   1.116 +        }
   1.117 +    }
   1.118 +}
   1.119 +
   1.120 +// FIXME: do we want to initialize the positions to [0, 0]?
   1.121 +le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
   1.122 +{
   1.123 +    if (LE_FAILURE(success)) {
   1.124 +        return -1;
   1.125 +    }
   1.126 +
   1.127 +    if (fPositions != NULL) {
   1.128 +        LE_DELETE_ARRAY(fPositions);
   1.129 +    }
   1.130 +
   1.131 +    fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
   1.132 +
   1.133 +    if (fPositions == NULL) {
   1.134 +        success = LE_MEMORY_ALLOCATION_ERROR;
   1.135 +        return -1;
   1.136 +    }
   1.137 +
   1.138 +    return fGlyphCount;
   1.139 +}
   1.140 +
   1.141 +// FIXME: do we want to initialize the aux data to NULL?
   1.142 +le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
   1.143 +{
   1.144 +    if (LE_FAILURE(success)) {
   1.145 +        return -1;
   1.146 +    }
   1.147 +
   1.148 +    fAuxData = LE_NEW_ARRAY(void *, fGlyphCount);
   1.149 +
   1.150 +    if (fAuxData == NULL) {
   1.151 +        success = LE_MEMORY_ALLOCATION_ERROR;
   1.152 +        return -1;
   1.153 +    }
   1.154 +
   1.155 +    return fGlyphCount;
   1.156 +}
   1.157 +
   1.158 +void LEGlyphStorage::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
   1.159 +{
   1.160 +    le_int32 i;
   1.161 +
   1.162 +    if (LE_FAILURE(success)) {
   1.163 +        return;
   1.164 +    }
   1.165 +
   1.166 +    if (charIndices == NULL) {
   1.167 +        success = LE_ILLEGAL_ARGUMENT_ERROR;
   1.168 +        return;
   1.169 +    }
   1.170 +
   1.171 +    if (fCharIndices == NULL) {
   1.172 +        success = LE_NO_LAYOUT_ERROR;
   1.173 +        return;
   1.174 +    }
   1.175 +
   1.176 +    for (i = 0; i < fGlyphCount; i += 1) {
   1.177 +        charIndices[i] = fCharIndices[i] + indexBase;
   1.178 +    }
   1.179 +}
   1.180 +
   1.181 +void LEGlyphStorage::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
   1.182 +{
   1.183 +    if (LE_FAILURE(success)) {
   1.184 +      return;
   1.185 +    }
   1.186 +    
   1.187 +    if (charIndices == NULL) {
   1.188 +      success = LE_ILLEGAL_ARGUMENT_ERROR;
   1.189 +      return;
   1.190 +    }
   1.191 +    
   1.192 +    if (fCharIndices == NULL) {
   1.193 +      success = LE_NO_LAYOUT_ERROR;
   1.194 +      return;
   1.195 +    }
   1.196 +    
   1.197 +    LE_ARRAY_COPY(charIndices, fCharIndices, fGlyphCount);
   1.198 +}
   1.199 +
   1.200 +// Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
   1.201 +void LEGlyphStorage::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
   1.202 +{
   1.203 +    le_int32 i;
   1.204 +
   1.205 +    if (LE_FAILURE(success)) {
   1.206 +        return;
   1.207 +    }
   1.208 +
   1.209 +    if (glyphs == NULL) {
   1.210 +        success = LE_ILLEGAL_ARGUMENT_ERROR;
   1.211 +        return;
   1.212 +    }
   1.213 +
   1.214 +    if (fGlyphs == NULL) {
   1.215 +        success = LE_NO_LAYOUT_ERROR;
   1.216 +        return;
   1.217 +    }
   1.218 +
   1.219 +    for (i = 0; i < fGlyphCount; i += 1) {
   1.220 +        glyphs[i] = fGlyphs[i] | extraBits;
   1.221 +    }
   1.222 +}
   1.223 +
   1.224 +void LEGlyphStorage::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
   1.225 +{
   1.226 +    if (LE_FAILURE(success)) {
   1.227 +      return;
   1.228 +    }
   1.229 +    
   1.230 +    if (glyphs == NULL) {
   1.231 +      success = LE_ILLEGAL_ARGUMENT_ERROR;
   1.232 +      return;
   1.233 +    }
   1.234 +    
   1.235 +    if (fGlyphs == NULL) {
   1.236 +      success = LE_NO_LAYOUT_ERROR;
   1.237 +      return;
   1.238 +    }
   1.239 +    
   1.240 +    LE_ARRAY_COPY(glyphs, fGlyphs, fGlyphCount);
   1.241 +}
   1.242 +
   1.243 +LEGlyphID LEGlyphStorage::getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const
   1.244 +{
   1.245 +    if (LE_FAILURE(success)) {
   1.246 +        return 0xFFFF;
   1.247 +    }
   1.248 +
   1.249 +    if (fGlyphs == NULL) {
   1.250 +        success = LE_NO_LAYOUT_ERROR;
   1.251 +        return 0xFFFF;
   1.252 +    }
   1.253 +
   1.254 +    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
   1.255 +        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.256 +        return 0xFFFF;
   1.257 +    }
   1.258 +
   1.259 +    return fGlyphs[glyphIndex];
   1.260 +}
   1.261 +
   1.262 +void LEGlyphStorage::setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success)
   1.263 +{
   1.264 +    if (LE_FAILURE(success)) {
   1.265 +        return;
   1.266 +    }
   1.267 +
   1.268 +    if (fGlyphs == NULL) {
   1.269 +        success = LE_NO_LAYOUT_ERROR;
   1.270 +        return;
   1.271 +    }
   1.272 +
   1.273 +    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
   1.274 +        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.275 +        return;
   1.276 +    }
   1.277 +
   1.278 +    fGlyphs[glyphIndex] = glyphID;
   1.279 +}
   1.280 +
   1.281 +le_int32 LEGlyphStorage::getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const
   1.282 +{
   1.283 +    if (LE_FAILURE(success)) {
   1.284 +        return -1;
   1.285 +    }
   1.286 +
   1.287 +    if (fCharIndices == NULL) {
   1.288 +        success = LE_NO_LAYOUT_ERROR;
   1.289 +        return -1;
   1.290 +    }
   1.291 +
   1.292 +    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
   1.293 +        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.294 +        return -1;
   1.295 +    }
   1.296 +
   1.297 +    return fCharIndices[glyphIndex];
   1.298 +}
   1.299 +
   1.300 +void LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success)
   1.301 +{
   1.302 +    if (LE_FAILURE(success)) {
   1.303 +        return;
   1.304 +    }
   1.305 +
   1.306 +    if (fCharIndices == NULL) {
   1.307 +        success = LE_NO_LAYOUT_ERROR;
   1.308 +        return;
   1.309 +    }
   1.310 +
   1.311 +    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
   1.312 +        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.313 +        return;
   1.314 +    }
   1.315 +
   1.316 +    fCharIndices[glyphIndex] = charIndex;
   1.317 +}
   1.318 +
   1.319 +void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const
   1.320 +{
   1.321 +    if (LE_FAILURE(success)) {
   1.322 +      return;
   1.323 +    }
   1.324 +    
   1.325 +    if (auxData == NULL) {
   1.326 +      success = LE_ILLEGAL_ARGUMENT_ERROR;
   1.327 +      return;
   1.328 +    }
   1.329 +    
   1.330 +    if (fAuxData == NULL) {
   1.331 +      success = LE_NO_LAYOUT_ERROR;
   1.332 +      return;
   1.333 +    }
   1.334 +    
   1.335 +    LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount);
   1.336 +}
   1.337 +
   1.338 +void *LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const
   1.339 +{
   1.340 +    if (LE_FAILURE(success)) {
   1.341 +        return NULL;
   1.342 +    }
   1.343 +
   1.344 +    if (fAuxData == NULL) {
   1.345 +        success = LE_NO_LAYOUT_ERROR;
   1.346 +        return NULL;
   1.347 +    }
   1.348 +    
   1.349 +    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
   1.350 +        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.351 +        return NULL;
   1.352 +    }
   1.353 +
   1.354 +    return fAuxData[glyphIndex];
   1.355 +}
   1.356 +
   1.357 +void LEGlyphStorage::setAuxData(le_int32 glyphIndex, void *auxData, LEErrorCode &success)
   1.358 +{
   1.359 +    if (LE_FAILURE(success)) {
   1.360 +        return;
   1.361 +    }
   1.362 +
   1.363 +    if (fAuxData == NULL) {
   1.364 +        success = LE_NO_LAYOUT_ERROR;
   1.365 +        return;
   1.366 +    }
   1.367 +
   1.368 +    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
   1.369 +        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.370 +        return;
   1.371 +    }
   1.372 +
   1.373 +    fAuxData[glyphIndex] = auxData;
   1.374 +}
   1.375 +
   1.376 +void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
   1.377 +{
   1.378 +    if (LE_FAILURE(success)) {
   1.379 +      return;
   1.380 +    }
   1.381 +  
   1.382 +    if (positions == NULL) {
   1.383 +      success = LE_ILLEGAL_ARGUMENT_ERROR;
   1.384 +      return;
   1.385 +    }
   1.386 +    
   1.387 +    if (fPositions == NULL) {
   1.388 +      success = LE_NO_LAYOUT_ERROR;
   1.389 +      return;
   1.390 +    }
   1.391 +    
   1.392 +    LE_ARRAY_COPY(positions, fPositions, fGlyphCount * 2 + 2);
   1.393 +}
   1.394 +
   1.395 +void LEGlyphStorage::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
   1.396 +{
   1.397 +    if (LE_FAILURE(success)) {
   1.398 +      return;
   1.399 +    }
   1.400 +    
   1.401 +    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
   1.402 +      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.403 +      return;
   1.404 +    }
   1.405 +    
   1.406 +    if (fPositions == NULL) {
   1.407 +      success = LE_NO_LAYOUT_ERROR;
   1.408 +      return;
   1.409 +    }
   1.410 +    
   1.411 +    x = fPositions[glyphIndex * 2];
   1.412 +    y = fPositions[glyphIndex * 2 + 1];
   1.413 +}
   1.414 +
   1.415 +void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success)
   1.416 +{
   1.417 +    if (LE_FAILURE(success)) {
   1.418 +        return;
   1.419 +    }
   1.420 +    
   1.421 +    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
   1.422 +      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.423 +      return;
   1.424 +    }
   1.425 +    
   1.426 +    fPositions[glyphIndex * 2]     = x;
   1.427 +    fPositions[glyphIndex * 2 + 1] = y;
   1.428 +}
   1.429 +
   1.430 +void LEGlyphStorage::adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success)
   1.431 +{
   1.432 +    if (LE_FAILURE(success)) {
   1.433 +        return;
   1.434 +    }
   1.435 +    
   1.436 +    if (glyphIndex < 0 || glyphIndex > fGlyphCount) {
   1.437 +      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
   1.438 +      return;
   1.439 +    }
   1.440 +    
   1.441 +    fPositions[glyphIndex * 2]     += xAdjust;
   1.442 +    fPositions[glyphIndex * 2 + 1] += yAdjust;
   1.443 +}
   1.444 +
   1.445 +void LEGlyphStorage::adoptGlyphArray(LEGlyphStorage &from)
   1.446 +{
   1.447 +    if (fGlyphs != NULL) {
   1.448 +        LE_DELETE_ARRAY(fGlyphs);
   1.449 +    }
   1.450 +
   1.451 +    fGlyphs = from.fGlyphs;
   1.452 +    from.fGlyphs = NULL;
   1.453 +
   1.454 +    if (fInsertionList != NULL) {
   1.455 +        delete fInsertionList;
   1.456 +    }
   1.457 +
   1.458 +    fInsertionList = from.fInsertionList;
   1.459 +    from.fInsertionList = NULL;
   1.460 +}
   1.461 +
   1.462 +void LEGlyphStorage::adoptCharIndicesArray(LEGlyphStorage &from)
   1.463 +{
   1.464 +    if (fCharIndices != NULL) {
   1.465 +        LE_DELETE_ARRAY(fCharIndices);
   1.466 +    }
   1.467 +
   1.468 +    fCharIndices = from.fCharIndices;
   1.469 +    from.fCharIndices = NULL;
   1.470 +}
   1.471 +
   1.472 +void LEGlyphStorage::adoptPositionArray(LEGlyphStorage &from)
   1.473 +{
   1.474 +    if (fPositions != NULL) {
   1.475 +        LE_DELETE_ARRAY(fPositions);
   1.476 +    }
   1.477 +
   1.478 +    fPositions = from.fPositions;
   1.479 +    from.fPositions = NULL;
   1.480 +}
   1.481 +
   1.482 +void LEGlyphStorage::adoptAuxDataArray(LEGlyphStorage &from)
   1.483 +{
   1.484 +    if (fAuxData != NULL) {
   1.485 +        LE_DELETE_ARRAY(fAuxData);
   1.486 +    }
   1.487 +
   1.488 +    fAuxData = from.fAuxData;
   1.489 +    from.fAuxData = NULL;
   1.490 +}
   1.491 +
   1.492 +void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
   1.493 +{
   1.494 +    fGlyphCount = from.fGlyphCount;
   1.495 +}
   1.496 +
   1.497 +void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
   1.498 +{
   1.499 +    fGlyphCount = newGlyphCount;
   1.500 +}
   1.501 +
   1.502 +LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32  atIndex, le_int32 insertCount,
   1.503 +    LEErrorCode& success)
   1.504 +{
   1.505 +    return fInsertionList->insert(atIndex, insertCount, success);
   1.506 +}
   1.507 +
   1.508 +le_int32 LEGlyphStorage::applyInsertions()
   1.509 +{
   1.510 +    le_int32 growAmount = fInsertionList->getGrowAmount();
   1.511 +
   1.512 +    if (growAmount == 0) {
   1.513 +        return fGlyphCount;
   1.514 +    }
   1.515 +
   1.516 +    le_int32 newGlyphCount = fGlyphCount + growAmount;
   1.517 +
   1.518 +    LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
   1.519 +    if (!newGlyphs) {
   1.520 +        // Could not grow the glyph array
   1.521 +        return fGlyphCount;
   1.522 +    }
   1.523 +    fGlyphs = newGlyphs;
   1.524 +
   1.525 +    le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
   1.526 +    if (!newCharIndices) {
   1.527 +        // Could not grow the glyph array
   1.528 +        return fGlyphCount;
   1.529 +    }
   1.530 +    fCharIndices = newCharIndices;
   1.531 +
   1.532 +    if (fAuxData != NULL) {
   1.533 +        void **newAuxData = (void **) LE_GROW_ARRAY(fAuxData, newGlyphCount);
   1.534 +        if (!newAuxData) {
   1.535 +            // could not grow the aux data array
   1.536 +            return fGlyphCount;
   1.537 +        }
   1.538 +        fAuxData = newAuxData;
   1.539 +    }
   1.540 +
   1.541 +    fSrcIndex  = fGlyphCount - 1;
   1.542 +    fDestIndex = newGlyphCount - 1;
   1.543 +
   1.544 +#if 0
   1.545 +    // If the current position is at the end of the array
   1.546 +    // update it to point to the end of the new array. The
   1.547 +    // insertion callback will handle all other cases.
   1.548 +    // FIXME: this is left over from GlyphIterator, but there's no easy
   1.549 +    // way to implement this here... it seems that GlyphIterator doesn't
   1.550 +    // really need it 'cause the insertions don't get  applied until after a
   1.551 +    // complete pass over the glyphs, after which the iterator gets reset anyhow...
   1.552 +    // probably better to just document that for LEGlyphStorage and GlyphIterator...
   1.553 +    if (position == glyphCount) {
   1.554 +        position = newGlyphCount;
   1.555 +    }
   1.556 +#endif
   1.557 +
   1.558 +    fInsertionList->applyInsertions(this);
   1.559 +
   1.560 +    fInsertionList->reset();
   1.561 +
   1.562 +    return fGlyphCount = newGlyphCount;
   1.563 +}
   1.564 +
   1.565 +le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[])
   1.566 +{
   1.567 +#if 0
   1.568 +    // if the current position is within the block we're shifting
   1.569 +    // it needs to be updated to the current glyph's
   1.570 +    // new location.
   1.571 +    // FIXME: this is left over from GlyphIterator, but there's no easy
   1.572 +    // way to implement this here... it seems that GlyphIterator doesn't
   1.573 +    // really need it 'cause the insertions don't get  applied until after a
   1.574 +    // complete pass over the glyphs, after which the iterator gets reset anyhow...
   1.575 +    // probably better to just document that for LEGlyphStorage and GlyphIterator...
   1.576 +    if (position >= atPosition && position <= fSrcIndex) {
   1.577 +        position += fDestIndex - fSrcIndex;
   1.578 +    }
   1.579 +#endif
   1.580 +
   1.581 +    if (fAuxData != NULL) {
   1.582 +        le_int32 src = fSrcIndex, dest = fDestIndex;
   1.583 +
   1.584 +        while (src > atPosition) {
   1.585 +            fAuxData[dest--] = fAuxData[src--];
   1.586 +        }
   1.587 +
   1.588 +        for (le_int32 i = count - 1; i >= 0; i -= 1) {
   1.589 +            fAuxData[dest--] = fAuxData[atPosition];
   1.590 +        }
   1.591 +    }
   1.592 +
   1.593 +    while (fSrcIndex > atPosition) {
   1.594 +        fGlyphs[fDestIndex]      = fGlyphs[fSrcIndex];
   1.595 +        fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
   1.596 +
   1.597 +        fDestIndex -= 1;
   1.598 +        fSrcIndex  -= 1;
   1.599 +    }
   1.600 +
   1.601 +    for (le_int32 i = count - 1; i >= 0; i -= 1) {
   1.602 +        fGlyphs[fDestIndex]      = newGlyphs[i];
   1.603 +        fCharIndices[fDestIndex] = fCharIndices[atPosition];
   1.604 +
   1.605 +        fDestIndex -= 1;
   1.606 +    }
   1.607 +
   1.608 +    // the source glyph we're pointing at
   1.609 +    // just got replaced by the insertion
   1.610 +    fSrcIndex -= 1;
   1.611 +
   1.612 +    return FALSE;
   1.613 +}
   1.614 +
   1.615 +void LEGlyphStorage::forMlylRakar(LEGlyphID aGlyphID)
   1.616 +{
   1.617 +    le_int32 i, j;    
   1.618 +
   1.619 +    if (fGlyphs == NULL) {
   1.620 +        return;
   1.621 +    }
   1.622 +
   1.623 +    for (i = 0; i < fGlyphCount; i++) {
   1.624 +        if (fGlyphs[i] == aGlyphID) {
   1.625 +        	j = i - 1;
   1.626 +        	while (j>=0 && fGlyphs[j] == 0xFFFF) {
   1.627 +        		j--;
   1.628 +        	}
   1.629 +        	
   1.630 +        	if (j>=0 && fGlyphs[j] != 0xFFFF && fGlyphs[j] != aGlyphID) {
   1.631 +        		fGlyphs[i] = fGlyphs[j];
   1.632 +        		fGlyphs[j] = aGlyphID;
   1.633 +        		
   1.634 +        		le_int32 tempCharIndex = fCharIndices[j];
   1.635 +        		fCharIndices[j] = fCharIndices[i];
   1.636 +        		fCharIndices[i] = tempCharIndex;
   1.637 +        		
   1.638 +        		void * tempAuxData = fAuxData[j];
   1.639 +        		fAuxData[j] = fAuxData[i];
   1.640 +        		fAuxData[i] = fAuxData[j];
   1.641 +        	}
   1.642 +        }        	
   1.643 +    }
   1.644 +}
   1.645 +
   1.646 +U_NAMESPACE_END
   1.647 +