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/ArabicShaping.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
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
29
*
30
*/
31
32
#include "LETypes.h"
33
#include "OpenTypeTables.h"
34
#include "ArabicShaping.h"
35
#include "LEGlyphStorage.h"
36
#include "ClassDefinitionTables.h"
37
38
U_NAMESPACE_BEGIN
39
40
// This table maps Unicode joining types to
41
// ShapeTypes.
42
const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
43
{
44
ArabicShaping::ST_NOSHAPE_NONE, // [U]
45
ArabicShaping::ST_NOSHAPE_DUAL, // [C]
46
ArabicShaping::ST_DUAL, // [D]
47
ArabicShaping::ST_LEFT, // [L]
48
ArabicShaping::ST_RIGHT, // [R]
49
ArabicShaping::ST_TRANSPARENT // [T]
50
};
51
52
/*
53
shaping array holds types for Arabic chars between 0610 and 0700
54
other values are either unshaped, or transparent if a mark or format
55
code, except for format codes 200c (zero-width non-joiner) and 200d
56
(dual-width joiner) which are both unshaped and non_joining or
57
dual-joining, respectively.
58
*/
59
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
60
{
61
LEErrorCode success = LE_NO_ERROR;
62
const LEReferenceTo<ClassDefinitionTable> joiningTypes(LETableReference::kStaticData,
63
(const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
64
ArabicShaping::shapingTypeTableLen);
65
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
66
67
if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) {
68
return ArabicShaping::shapeTypes[joiningType];
69
}
70
71
return ArabicShaping::ST_NOSHAPE_NONE;
72
}
73
74
#define isolFeatureTag LE_ISOL_FEATURE_TAG
75
#define initFeatureTag LE_INIT_FEATURE_TAG
76
#define mediFeatureTag LE_MEDI_FEATURE_TAG
77
#define finaFeatureTag LE_FINA_FEATURE_TAG
78
#define ligaFeatureTag LE_LIGA_FEATURE_TAG
79
#define msetFeatureTag LE_MSET_FEATURE_TAG
80
#define markFeatureTag LE_MARK_FEATURE_TAG
81
#define ccmpFeatureTag LE_CCMP_FEATURE_TAG
82
#define rligFeatureTag LE_RLIG_FEATURE_TAG
83
#define caltFeatureTag LE_CALT_FEATURE_TAG
84
#define dligFeatureTag LE_DLIG_FEATURE_TAG
85
#define cswhFeatureTag LE_CSWH_FEATURE_TAG
86
#define cursFeatureTag LE_CURS_FEATURE_TAG
87
#define kernFeatureTag LE_KERN_FEATURE_TAG
88
#define mkmkFeatureTag LE_MKMK_FEATURE_TAG
89
90
// NOTE:
91
// The isol, fina, init and medi features must be
92
// defined in the above order, and have masks that
93
// are all in the same nibble.
94
#define isolFeatureMask 0x80000000UL
95
#define finaFeatureMask 0x40000000UL
96
#define initFeatureMask 0x20000000UL
97
#define mediFeatureMask 0x10000000UL
98
#define ccmpFeatureMask 0x08000000UL
99
#define rligFeatureMask 0x04000000UL
100
#define caltFeatureMask 0x02000000UL
101
#define ligaFeatureMask 0x01000000UL
102
#define dligFeatureMask 0x00800000UL
103
#define cswhFeatureMask 0x00400000UL
104
#define msetFeatureMask 0x00200000UL
105
#define cursFeatureMask 0x00100000UL
106
#define kernFeatureMask 0x00080000UL
107
#define markFeatureMask 0x00040000UL
108
#define mkmkFeatureMask 0x00020000UL
109
110
#define NO_FEATURES 0
111
#define ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask)
112
113
#define SHAPE_MASK 0xF0000000UL
114
115
static const FeatureMap featureMap[] = {
116
{ccmpFeatureTag, ccmpFeatureMask},
117
{isolFeatureTag, isolFeatureMask},
118
{finaFeatureTag, finaFeatureMask},
119
{mediFeatureTag, mediFeatureMask},
120
{initFeatureTag, initFeatureMask},
121
{rligFeatureTag, rligFeatureMask},
122
{caltFeatureTag, caltFeatureMask},
123
{ligaFeatureTag, ligaFeatureMask},
124
{dligFeatureTag, dligFeatureMask},
125
{cswhFeatureTag, cswhFeatureMask},
126
{msetFeatureTag, msetFeatureMask},
127
{cursFeatureTag, cursFeatureMask},
128
{kernFeatureTag, kernFeatureMask},
129
{markFeatureTag, markFeatureMask},
130
{mkmkFeatureTag, mkmkFeatureMask}
131
};
132
133
const FeatureMap *ArabicShaping::getFeatureMap(le_int32 &count)
134
{
135
count = LE_ARRAY_SIZE(featureMap);
136
137
return featureMap;
138
}
139
140
void ArabicShaping::adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage)
141
{
142
LEErrorCode success = LE_NO_ERROR;
143
FeatureMask featureMask = (FeatureMask) glyphStorage.getAuxData(outIndex, success);
144
FeatureMask shape = featureMask & SHAPE_MASK;
145
146
shape >>= shapeOffset;
147
148
glyphStorage.setAuxData(outIndex, ((featureMask & ~SHAPE_MASK) | shape), success);
149
}
150
151
void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
152
le_bool rightToLeft, LEGlyphStorage &glyphStorage)
153
{
154
// iterate in logical order, store tags in visible order
155
//
156
// the effective right char is the most recently encountered
157
// non-transparent char
158
//
159
// four boolean states:
160
// the effective right char shapes
161
// the effective right char causes left shaping
162
// the current char shapes
163
// the current char causes right shaping
164
//
165
// if both cause shaping, then
166
// shaper.shape(errout, 2) (isolate to initial, or final to medial)
167
// shaper.shape(out, 1) (isolate to final)
168
169
ShapeType rightType = ST_NOSHAPE_NONE, leftType = ST_NOSHAPE_NONE;
170
LEErrorCode success = LE_NO_ERROR;
171
le_int32 i;
172
173
for (i = offset - 1; i >= 0; i -= 1) {
174
rightType = getShapeType(chars[i]);
175
176
if (rightType != ST_TRANSPARENT) {
177
break;
178
}
179
}
180
181
for (i = offset + charCount; i < charMax; i += 1) {
182
leftType = getShapeType(chars[i]);
183
184
if (leftType != ST_TRANSPARENT) {
185
break;
186
}
187
}
188
189
// erout is effective right logical index
190
le_int32 erout = -1;
191
le_bool rightShapes = FALSE;
192
le_bool rightCauses = (rightType & MASK_SHAPE_LEFT) != 0;
193
le_int32 in, e, out = 0, dir = 1;
194
195
if (rightToLeft) {
196
out = charCount - 1;
197
erout = charCount;
198
dir = -1;
199
}
200
201
for (in = offset, e = offset + charCount; in < e; in += 1, out += dir) {
202
LEUnicode c = chars[in];
203
ShapeType t = getShapeType(c);
204
205
if (t == ST_NOSHAPE_NONE) {
206
glyphStorage.setAuxData(out, NO_FEATURES, success);
207
} else {
208
glyphStorage.setAuxData(out, ISOL_FEATURES, success);
209
}
210
211
if ((t & MASK_TRANSPARENT) != 0) {
212
continue;
213
}
214
215
le_bool curShapes = (t & MASK_NOSHAPE) == 0;
216
le_bool curCauses = (t & MASK_SHAPE_RIGHT) != 0;
217
218
if (rightCauses && curCauses) {
219
if (rightShapes) {
220
adjustTags(erout, 2, glyphStorage);
221
}
222
223
if (curShapes) {
224
adjustTags(out, 1, glyphStorage);
225
}
226
}
227
228
rightShapes = curShapes;
229
rightCauses = (t & MASK_SHAPE_LEFT) != 0;
230
erout = out;
231
}
232
233
if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) {
234
adjustTags(erout, 2, glyphStorage);
235
}
236
}
237
238
U_NAMESPACE_END
239
240