os/textandloc/fontservices/textshaperplugin/IcuSource/layout/ArabicLayoutEngine.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
sl@0
     2
/*
sl@0
     3
 *
sl@0
     4
 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
sl@0
     5
 *
sl@0
     6
 */
sl@0
     7
sl@0
     8
#include "LETypes.h"
sl@0
     9
#include "LEScripts.h"
sl@0
    10
#include "LEGlyphFilter.h"
sl@0
    11
#include "LEGlyphStorage.h"
sl@0
    12
#include "LayoutEngine.h"
sl@0
    13
#include "OpenTypeLayoutEngine.h"
sl@0
    14
#include "ArabicLayoutEngine.h"
sl@0
    15
#include "ScriptAndLanguageTags.h"
sl@0
    16
#include "CharSubstitutionFilter.h"
sl@0
    17
sl@0
    18
#include "GlyphSubstitutionTables.h"
sl@0
    19
#include "GlyphDefinitionTables.h"
sl@0
    20
#include "GlyphPositioningTables.h"
sl@0
    21
sl@0
    22
#include "GDEFMarkFilter.h"
sl@0
    23
sl@0
    24
#include "ArabicShaping.h"
sl@0
    25
#include "CanonShaping.h"
sl@0
    26
sl@0
    27
U_NAMESPACE_BEGIN
sl@0
    28
sl@0
    29
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
sl@0
    30
{
sl@0
    31
    return fFontInstance->canDisplay((LEUnicode) glyph);
sl@0
    32
}
sl@0
    33
sl@0
    34
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
sl@0
    35
sl@0
    36
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
sl@0
    37
                        le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
sl@0
    38
    : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable)
sl@0
    39
{
sl@0
    40
    /**/ fFeatureOrder = ArabicShaping::getFeatureOrder();
sl@0
    41
}
sl@0
    42
sl@0
    43
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
sl@0
    44
						       le_int32 typoFlags)
sl@0
    45
    : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
sl@0
    46
{
sl@0
    47
    // fFeatureOrder = ArabicShaping::getFeatureOrder();
sl@0
    48
}
sl@0
    49
sl@0
    50
ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
sl@0
    51
{
sl@0
    52
    // nothing to do
sl@0
    53
}
sl@0
    54
sl@0
    55
// Input: characters
sl@0
    56
// Output: characters, char indices, tags
sl@0
    57
// Returns: output character count
sl@0
    58
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
sl@0
    59
        LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
sl@0
    60
{
sl@0
    61
    if (LE_FAILURE(success)) {
sl@0
    62
        return 0;
sl@0
    63
    }
sl@0
    64
sl@0
    65
    if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
sl@0
    66
        success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
    67
        return 0;
sl@0
    68
    }
sl@0
    69
sl@0
    70
    outChars = LE_NEW_ARRAY(LEUnicode, count);
sl@0
    71
sl@0
    72
    if (outChars == NULL) {
sl@0
    73
        success = LE_MEMORY_ALLOCATION_ERROR;
sl@0
    74
        return 0;
sl@0
    75
    }
sl@0
    76
sl@0
    77
    glyphStorage.allocateGlyphArray(count, rightToLeft, success);
sl@0
    78
    glyphStorage.allocateAuxData(success);
sl@0
    79
sl@0
    80
    if (LE_FAILURE(success)) {
sl@0
    81
        LE_DELETE_ARRAY(outChars);
sl@0
    82
        return 0;
sl@0
    83
    }
sl@0
    84
sl@0
    85
    CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);
sl@0
    86
sl@0
    87
    // Note: This processes the *original* character array so we can get context
sl@0
    88
    // for the first and last characters. This is OK because only the marks
sl@0
    89
    // will have been reordered, and they don't contribute to shaping.
sl@0
    90
    ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);
sl@0
    91
sl@0
    92
    return count;
sl@0
    93
}
sl@0
    94
sl@0
    95
void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
sl@0
    96
                                                      LEGlyphStorage &glyphStorage, LEErrorCode &success)
sl@0
    97
{
sl@0
    98
    if (LE_FAILURE(success)) {
sl@0
    99
        return;
sl@0
   100
    }
sl@0
   101
sl@0
   102
    if (chars == NULL || offset < 0 || count < 0) {
sl@0
   103
        success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   104
        return;
sl@0
   105
    }
sl@0
   106
sl@0
   107
    if (fGPOSTable != NULL) {
sl@0
   108
        OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
sl@0
   109
    } else if (fGDEFTable != NULL) {
sl@0
   110
        GDEFMarkFilter filter(fGDEFTable);
sl@0
   111
sl@0
   112
        adjustMarkGlyphs(glyphStorage, &filter, success);
sl@0
   113
    } else {
sl@0
   114
        GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
sl@0
   115
        GDEFMarkFilter filter(gdefTable);
sl@0
   116
sl@0
   117
        adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
sl@0
   118
    }
sl@0
   119
}
sl@0
   120
sl@0
   121
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags)
sl@0
   122
    : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
sl@0
   123
{
sl@0
   124
    fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
sl@0
   125
    fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
sl@0
   126
sl@0
   127
    fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
sl@0
   128
}
sl@0
   129
sl@0
   130
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
sl@0
   131
{
sl@0
   132
    delete fSubstitutionFilter;
sl@0
   133
}
sl@0
   134
sl@0
   135
// "glyphs", "indices" -> glyphs, indices
sl@0
   136
le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)
sl@0
   137
{
sl@0
   138
    if (LE_FAILURE(success)) {
sl@0
   139
        return 0;
sl@0
   140
    }
sl@0
   141
sl@0
   142
    // FIXME: we could avoid the memory allocation and copy if we
sl@0
   143
    // made a clone of mapCharsToGlyphs which took the fake glyphs
sl@0
   144
    // directly.
sl@0
   145
    le_int32 tempGlyphCount = tempGlyphStorage.getGlyphCount();
sl@0
   146
    LEUnicode *tempChars = LE_NEW_ARRAY(LEUnicode, tempGlyphCount);
sl@0
   147
sl@0
   148
    if (tempChars == NULL) {
sl@0
   149
        success = LE_MEMORY_ALLOCATION_ERROR;
sl@0
   150
        return 0;
sl@0
   151
    }
sl@0
   152
sl@0
   153
    for (le_int32 i = 0; i < tempGlyphCount; i += 1) {
sl@0
   154
        tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphStorage[i]);
sl@0
   155
    }
sl@0
   156
sl@0
   157
    glyphStorage.adoptCharIndicesArray(tempGlyphStorage);
sl@0
   158
sl@0
   159
    ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success);
sl@0
   160
sl@0
   161
    LE_DELETE_ARRAY(tempChars);
sl@0
   162
sl@0
   163
    return tempGlyphCount;
sl@0
   164
}
sl@0
   165
sl@0
   166
void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
sl@0
   167
{
sl@0
   168
    if (LE_FAILURE(success)) {
sl@0
   169
        return;
sl@0
   170
    }
sl@0
   171
sl@0
   172
    if (chars == NULL || offset < 0 || count < 0) {
sl@0
   173
        success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   174
        return;
sl@0
   175
    }
sl@0
   176
sl@0
   177
    le_int32 i, dir = 1, out = 0;
sl@0
   178
sl@0
   179
    if (reverse) {
sl@0
   180
        out = count - 1;
sl@0
   181
        dir = -1;
sl@0
   182
    }
sl@0
   183
sl@0
   184
    glyphStorage.allocateGlyphArray(count, reverse, success);
sl@0
   185
sl@0
   186
    for (i = 0; i < count; i += 1, out += dir) {
sl@0
   187
        glyphStorage[out] = (LEGlyphID) chars[offset + i];
sl@0
   188
    }
sl@0
   189
}
sl@0
   190
sl@0
   191
void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
sl@0
   192
                                                      LEGlyphStorage &glyphStorage, LEErrorCode &success)
sl@0
   193
{
sl@0
   194
    if (LE_FAILURE(success)) {
sl@0
   195
        return;
sl@0
   196
    }
sl@0
   197
sl@0
   198
    if (chars == NULL || offset < 0 || count < 0) {
sl@0
   199
        success = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   200
        return;
sl@0
   201
    }
sl@0
   202
sl@0
   203
    GDEFMarkFilter filter(fGDEFTable);
sl@0
   204
sl@0
   205
    adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
sl@0
   206
}
sl@0
   207
sl@0
   208
U_NAMESPACE_END
sl@0
   209