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