Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp
38918 views
1
/*
2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation. Oracle designates this
7
* particular file as subject to the "Classpath" exception as provided
8
* by Oracle in the LICENSE file that accompanied this code.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
27
/*
28
*
29
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
30
*
31
*/
32
33
#include "LETypes.h"
34
#include "LEScripts.h"
35
#include "LEGlyphFilter.h"
36
#include "LEGlyphStorage.h"
37
#include "LayoutEngine.h"
38
#include "OpenTypeLayoutEngine.h"
39
#include "ArabicLayoutEngine.h"
40
#include "ScriptAndLanguageTags.h"
41
#include "CharSubstitutionFilter.h"
42
43
#include "GlyphSubstitutionTables.h"
44
#include "GlyphDefinitionTables.h"
45
#include "GlyphPositioningTables.h"
46
47
#include "GDEFMarkFilter.h"
48
49
#include "ArabicShaping.h"
50
#include "CanonShaping.h"
51
52
U_NAMESPACE_BEGIN
53
54
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph, LEErrorCode &/*success*/) const
55
{
56
return fFontInstance->canDisplay((LEUnicode) glyph);
57
}
58
59
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
60
61
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
62
le_int32 languageCode, le_int32 typoFlags,
63
const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
64
LEErrorCode &success)
65
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
66
{
67
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
68
fFeatureOrder = TRUE;
69
}
70
71
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
72
le_int32 languageCode,
73
le_int32 typoFlags, LEErrorCode &success)
74
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
75
{
76
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
77
78
// NOTE: We don't need to set fFeatureOrder to TRUE here
79
// because this constructor is only called by the constructor
80
// for UnicodeArabicOpenTypeLayoutEngine, which uses a pre-built
81
// GSUB table that has the features in the correct order.
82
83
//fFeatureOrder = TRUE;
84
}
85
86
ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
87
{
88
// nothing to do
89
}
90
91
// Input: characters
92
// Output: characters, char indices, tags
93
// Returns: output character count
94
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
95
le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
96
LEGlyphStorage &glyphStorage, LEErrorCode &success)
97
{
98
if (LE_FAILURE(success)) {
99
return 0;
100
}
101
102
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
103
success = LE_ILLEGAL_ARGUMENT_ERROR;
104
return 0;
105
}
106
107
outChars = LE_NEW_ARRAY(LEUnicode, count);
108
109
if (outChars == NULL) {
110
success = LE_MEMORY_ALLOCATION_ERROR;
111
return 0;
112
}
113
114
glyphStorage.allocateGlyphArray(count, rightToLeft, success);
115
glyphStorage.allocateAuxData(success);
116
117
if (LE_FAILURE(success)) {
118
LE_DELETE_ARRAY(outChars);
119
return 0;
120
}
121
122
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);
123
124
// Note: This processes the *original* character array so we can get context
125
// for the first and last characters. This is OK because only the marks
126
// will have been reordered, and they don't contribute to shaping.
127
ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);
128
129
return count;
130
}
131
132
void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
133
LEGlyphStorage &glyphStorage, LEErrorCode &success)
134
{
135
if (LE_FAILURE(success)) {
136
return;
137
}
138
139
if (chars == NULL || offset < 0 || count < 0) {
140
success = LE_ILLEGAL_ARGUMENT_ERROR;
141
return;
142
}
143
144
if (!fGPOSTable.isEmpty()) {
145
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
146
} else if (!fGDEFTable.isEmpty()) {
147
GDEFMarkFilter filter(fGDEFTable, success);
148
adjustMarkGlyphs(glyphStorage, &filter, success);
149
} else {
150
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData,
151
CanonShaping::glyphDefinitionTable,
152
CanonShaping::glyphDefinitionTableLen);
153
GDEFMarkFilter filter(gdefTable, success);
154
155
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
156
}
157
}
158
159
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
160
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
161
{
162
fGSUBTable.setTo(LETableReference::kStaticData, (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable, CanonShaping::glyphSubstitutionTableLen);
163
fGDEFTable.setTo(LETableReference::kStaticData, (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
164
/* OpenTypeLayoutEngine will allocate a substitution filter */
165
}
166
167
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
168
{
169
/* OpenTypeLayoutEngine will cleanup the substitution filter */
170
}
171
172
// "glyphs", "indices" -> glyphs, indices
173
le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)
174
{
175
if (LE_FAILURE(success)) {
176
return 0;
177
}
178
179
// FIXME: we could avoid the memory allocation and copy if we
180
// made a clone of mapCharsToGlyphs which took the fake glyphs
181
// directly.
182
le_int32 tempGlyphCount = tempGlyphStorage.getGlyphCount();
183
LEUnicode *tempChars = LE_NEW_ARRAY(LEUnicode, tempGlyphCount);
184
185
if (tempChars == NULL) {
186
success = LE_MEMORY_ALLOCATION_ERROR;
187
return 0;
188
}
189
190
for (le_int32 i = 0; i < tempGlyphCount; i += 1) {
191
tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphStorage[i]);
192
}
193
194
glyphStorage.adoptCharIndicesArray(tempGlyphStorage);
195
196
ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success);
197
198
LE_DELETE_ARRAY(tempChars);
199
200
return tempGlyphCount;
201
}
202
203
void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
204
{
205
if (LE_FAILURE(success)) {
206
return;
207
}
208
209
if (chars == NULL || offset < 0 || count < 0) {
210
success = LE_ILLEGAL_ARGUMENT_ERROR;
211
return;
212
}
213
214
le_int32 i, dir = 1, out = 0;
215
216
if (reverse) {
217
out = count - 1;
218
dir = -1;
219
}
220
221
glyphStorage.allocateGlyphArray(count, reverse, success);
222
223
for (i = 0; i < count; i += 1, out += dir) {
224
glyphStorage[out] = (LEGlyphID) chars[offset + i];
225
}
226
}
227
228
void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
229
LEGlyphStorage &glyphStorage, LEErrorCode &success)
230
{
231
if (LE_FAILURE(success)) {
232
return;
233
}
234
235
if (chars == NULL || offset < 0 || count < 0) {
236
success = LE_ILLEGAL_ARGUMENT_ERROR;
237
return;
238
}
239
240
GDEFMarkFilter filter(fGDEFTable, success);
241
242
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
243
}
244
245
U_NAMESPACE_END
246
247
248