Logo Search packages:      
Sourcecode: icu version File versions  Download package

le_int32 LayoutEngine::characterProcessing ( const LEUnicode  chars[],
le_int32  offset,
le_int32  count,
le_int32  max,
le_bool  rightToLeft,
LEUnicode *&  outChars,
LEGlyphStorage glyphStorage,
LEErrorCode success 
) [protected, virtual, inherited]

This method does any required pre-processing to the input characters. It may generate output characters that differ from the input charcters due to insertions, deletions, or reorderings. In such cases, it will also generate an output character index array reflecting these changes.

Subclasses must override this method.

Input parameters:

Parameters:
chars - the input character context
offset - the index of the first character to process
count - the number of characters to process
max - the number of characters in the input context
rightToLeft - TRUE if the characters are in a right to left directional run
outChars - the output character array, if different from the input
glyphStorage - the object that holds the per-glyph storage. The character index array may be set.
success - set to an error code if the operation fails
Returns:
the output character count (input character count if no change)

For internal use only.

Reimplemented in ArabicOpenTypeLayoutEngine, HangulOpenTypeLayoutEngine, HanOpenTypeLayoutEngine, IndicOpenTypeLayoutEngine, KhmerOpenTypeLayoutEngine, OpenTypeLayoutEngine, and TibetanOpenTypeLayoutEngine.

Definition at line 192 of file LayoutEngine.cpp.

References LEGlyphStorage::adoptCharIndicesArray(), LEGlyphStorage::allocateAuxData(), LEGlyphStorage::allocateGlyphArray(), FALSE, LayoutEngine::fFontInstance, LayoutEngine::fLanguageCode, LayoutEngine::fScriptCode, OpenTypeLayoutEngine::getLangSysTag(), OpenTypeLayoutEngine::getScriptTag(), LE_FAILURE, LE_GET_GLYPH, LE_ILLEGAL_ARGUMENT_ERROR, LE_MEMORY_ALLOCATION_ERROR, NULL, and LEGlyphStorage::setAuxData().

Referenced by LayoutEngine::computeGlyphs().

{
    if (LE_FAILURE(success)) {
        return 0;
    }

    if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
        success = LE_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
    LETag scriptTag  = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
    LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
    le_int32 i, dir = 1, out = 0, outCharCount = count;

    if (canonGSUBTable->coversScript(scriptTag)) {
        CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
        if (substitutionFilter == NULL) { 
            success = LE_MEMORY_ALLOCATION_ERROR;
            return 0;
        }

            const LEUnicode *inChars = &chars[offset];
            LEUnicode *reordered = NULL;
        LEGlyphStorage fakeGlyphStorage;

        fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success);

        if (LE_FAILURE(success)) {
            delete substitutionFilter;
            return 0;
        }

            // This is the cheapest way to get mark reordering only for Hebrew.
            // We could just do the mark reordering for all scripts, but most
            // of them probably don't need it...
            if (fScriptCode == hebrScriptCode) {
                  reordered = LE_NEW_ARRAY(LEUnicode, count);

                  if (reordered == NULL) {
                delete substitutionFilter;
                        success = LE_MEMORY_ALLOCATION_ERROR;
                        return 0;
                  }

                  CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
                  inChars = reordered;
        }

        fakeGlyphStorage.allocateAuxData(success);

        if (LE_FAILURE(success)) {
            delete substitutionFilter;
            return 0;
        }

        if (rightToLeft) {
            out = count - 1;
            dir = -1;
        }

        for (i = 0; i < count; i += 1, out += dir) {
            fakeGlyphStorage[out] = (LEGlyphID) inChars[i];
            fakeGlyphStorage.setAuxData(out, canonFeatures, success);
        }

            if (reordered != NULL) {
                  LE_DELETE_ARRAY(reordered);
            }

        outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);

        if (LE_FAILURE(success)) {
            delete substitutionFilter;
            return 0;
        }

        out = (rightToLeft? outCharCount - 1 : 0);

        /*
         * The char indices array in fakeGlyphStorage has the correct mapping
         * back to the original input characters. Save it in glyphStorage. The
         * subsequent call to glyphStoratge.allocateGlyphArray will keep this
         * array rather than allocating and initializing a new one.
         */
        glyphStorage.adoptCharIndicesArray(fakeGlyphStorage);

        outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);

        if (outChars == NULL) {
            delete substitutionFilter;
            success = LE_MEMORY_ALLOCATION_ERROR;
            return 0;
        }

        for (i = 0; i < outCharCount; i += 1, out += dir) {
            outChars[out] = (LEUnicode) LE_GET_GLYPH(fakeGlyphStorage[i]);
        }

        delete substitutionFilter;
    }

    return outCharCount;
}


Generated by  Doxygen 1.6.0   Back to index