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/GlyphIterator.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 "GlyphDefinitionTables.h"
35
#include "GlyphPositionAdjustments.h"
36
#include "GlyphIterator.h"
37
#include "LEGlyphStorage.h"
38
#include "Lookups.h"
39
#include "LESwaps.h"
40
41
U_NAMESPACE_BEGIN
42
43
GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
44
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader, LEErrorCode &success)
45
: direction(1), position(-1), nextLimit(-1), prevLimit(-1),
46
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
47
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
48
glyphClassDefinitionTable(), markAttachClassDefinitionTable()
49
50
{
51
le_int32 glyphCount = glyphStorage.getGlyphCount();
52
53
if (theGlyphDefinitionTableHeader.isValid()) {
54
glyphClassDefinitionTable = theGlyphDefinitionTableHeader
55
-> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success);
56
markAttachClassDefinitionTable = theGlyphDefinitionTableHeader
57
->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success);
58
}
59
60
nextLimit = glyphCount;
61
62
if (rightToLeft) {
63
direction = -1;
64
position = glyphCount;
65
nextLimit = -1;
66
prevLimit = glyphCount;
67
}
68
filterResetCache();
69
}
70
71
GlyphIterator::GlyphIterator(GlyphIterator &that)
72
: glyphStorage(that.glyphStorage)
73
{
74
direction = that.direction;
75
position = that.position;
76
nextLimit = that.nextLimit;
77
prevLimit = that.prevLimit;
78
79
glyphPositionAdjustments = that.glyphPositionAdjustments;
80
srcIndex = that.srcIndex;
81
destIndex = that.destIndex;
82
lookupFlags = that.lookupFlags;
83
featureMask = that.featureMask;
84
glyphGroup = that.glyphGroup;
85
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
86
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
87
filterResetCache();
88
}
89
90
GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask)
91
: glyphStorage(that.glyphStorage)
92
{
93
direction = that.direction;
94
position = that.position;
95
nextLimit = that.nextLimit;
96
prevLimit = that.prevLimit;
97
98
glyphPositionAdjustments = that.glyphPositionAdjustments;
99
srcIndex = that.srcIndex;
100
destIndex = that.destIndex;
101
lookupFlags = that.lookupFlags;
102
featureMask = newFeatureMask;
103
glyphGroup = 0;
104
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
105
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
106
filterResetCache();
107
}
108
109
GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
110
: glyphStorage(that.glyphStorage)
111
{
112
direction = that.direction;
113
position = that.position;
114
nextLimit = that.nextLimit;
115
prevLimit = that.prevLimit;
116
117
glyphPositionAdjustments = that.glyphPositionAdjustments;
118
srcIndex = that.srcIndex;
119
destIndex = that.destIndex;
120
lookupFlags = newLookupFlags;
121
featureMask = that.featureMask;
122
glyphGroup = that.glyphGroup;
123
glyphClassDefinitionTable = that.glyphClassDefinitionTable;
124
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
125
filterResetCache();
126
}
127
128
GlyphIterator::~GlyphIterator()
129
{
130
// nothing to do, right?
131
}
132
133
void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask)
134
{
135
position = prevLimit;
136
featureMask = newFeatureMask;
137
glyphGroup = 0;
138
lookupFlags = newLookupFlags;
139
filterResetCache();
140
}
141
142
LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success)
143
{
144
return glyphStorage.insertGlyphs(position, count, success);
145
}
146
147
le_int32 GlyphIterator::applyInsertions()
148
{
149
le_int32 newGlyphCount = glyphStorage.applyInsertions();
150
151
if (direction < 0) {
152
prevLimit = newGlyphCount;
153
} else {
154
nextLimit = newGlyphCount;
155
}
156
157
return newGlyphCount;
158
}
159
160
le_int32 GlyphIterator::getCurrStreamPosition() const
161
{
162
return position;
163
}
164
165
le_bool GlyphIterator::isRightToLeft() const
166
{
167
return direction < 0;
168
}
169
170
le_bool GlyphIterator::ignoresMarks() const
171
{
172
return (lookupFlags & lfIgnoreMarks) != 0;
173
}
174
175
le_bool GlyphIterator::baselineIsLogicalEnd() const
176
{
177
return (lookupFlags & lfBaselineIsLogicalEnd) != 0;
178
}
179
180
LEGlyphID GlyphIterator::getCurrGlyphID() const
181
{
182
if (direction < 0) {
183
if (position <= nextLimit || position >= prevLimit) {
184
return 0xFFFF;
185
}
186
} else {
187
if (position <= prevLimit || position >= nextLimit) {
188
return 0xFFFF;
189
}
190
}
191
192
return glyphStorage[position];
193
}
194
195
void GlyphIterator::getCursiveEntryPoint(LEPoint &entryPoint) const
196
{
197
if (direction < 0) {
198
if (position <= nextLimit || position >= prevLimit) {
199
return;
200
}
201
} else {
202
if (position <= prevLimit || position >= nextLimit) {
203
return;
204
}
205
}
206
207
glyphPositionAdjustments->getEntryPoint(position, entryPoint);
208
}
209
210
void GlyphIterator::getCursiveExitPoint(LEPoint &exitPoint) const
211
{
212
if (direction < 0) {
213
if (position <= nextLimit || position >= prevLimit) {
214
return;
215
}
216
} else {
217
if (position <= prevLimit || position >= nextLimit) {
218
return;
219
}
220
}
221
222
glyphPositionAdjustments->getExitPoint(position, exitPoint);
223
}
224
225
void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID)
226
{
227
if (direction < 0) {
228
if (position <= nextLimit || position >= prevLimit) {
229
return;
230
}
231
} else {
232
if (position <= prevLimit || position >= nextLimit) {
233
return;
234
}
235
}
236
237
LEGlyphID glyph = glyphStorage[position];
238
239
glyphStorage[position] = LE_SET_GLYPH(glyph, glyphID);
240
}
241
242
void GlyphIterator::setCurrStreamPosition(le_int32 newPosition)
243
{
244
if (direction < 0) {
245
if (newPosition >= prevLimit) {
246
position = prevLimit;
247
return;
248
}
249
250
if (newPosition <= nextLimit) {
251
position = nextLimit;
252
return;
253
}
254
} else {
255
if (newPosition <= prevLimit) {
256
position = prevLimit;
257
return;
258
}
259
260
if (newPosition >= nextLimit) {
261
position = nextLimit;
262
return;
263
}
264
}
265
266
position = newPosition - direction;
267
next();
268
}
269
270
void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset)
271
{
272
if (direction < 0) {
273
if (position <= nextLimit || position >= prevLimit) {
274
return;
275
}
276
} else {
277
if (position <= prevLimit || position >= nextLimit) {
278
return;
279
}
280
}
281
282
glyphPositionAdjustments->setBaseOffset(position, baseOffset);
283
}
284
285
void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
286
float xAdvanceAdjust, float yAdvanceAdjust)
287
{
288
if (direction < 0) {
289
if (position <= nextLimit || position >= prevLimit) {
290
return;
291
}
292
} else {
293
if (position <= prevLimit || position >= nextLimit) {
294
return;
295
}
296
}
297
298
glyphPositionAdjustments->adjustXPlacement(position, xPlacementAdjust);
299
glyphPositionAdjustments->adjustYPlacement(position, yPlacementAdjust);
300
glyphPositionAdjustments->adjustXAdvance(position, xAdvanceAdjust);
301
glyphPositionAdjustments->adjustYAdvance(position, yAdvanceAdjust);
302
}
303
304
void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
305
float xAdvanceAdjust, float yAdvanceAdjust)
306
{
307
if (direction < 0) {
308
if (position <= nextLimit || position >= prevLimit) {
309
return;
310
}
311
} else {
312
if (position <= prevLimit || position >= nextLimit) {
313
return;
314
}
315
}
316
317
glyphPositionAdjustments->setXPlacement(position, xPlacementAdjust);
318
glyphPositionAdjustments->setYPlacement(position, yPlacementAdjust);
319
glyphPositionAdjustments->setXAdvance(position, xAdvanceAdjust);
320
glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
321
}
322
323
void GlyphIterator::clearCursiveEntryPoint()
324
{
325
if (direction < 0) {
326
if (position <= nextLimit || position >= prevLimit) {
327
return;
328
}
329
} else {
330
if (position <= prevLimit || position >= nextLimit) {
331
return;
332
}
333
}
334
335
glyphPositionAdjustments->clearEntryPoint(position);
336
}
337
338
void GlyphIterator::clearCursiveExitPoint()
339
{
340
if (direction < 0) {
341
if (position <= nextLimit || position >= prevLimit) {
342
return;
343
}
344
} else {
345
if (position <= prevLimit || position >= nextLimit) {
346
return;
347
}
348
}
349
350
glyphPositionAdjustments->clearExitPoint(position);
351
}
352
353
void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
354
{
355
if (direction < 0) {
356
if (position <= nextLimit || position >= prevLimit) {
357
return;
358
}
359
} else {
360
if (position <= prevLimit || position >= nextLimit) {
361
return;
362
}
363
}
364
365
glyphPositionAdjustments->setEntryPoint(position, entryPoint, baselineIsLogicalEnd());
366
}
367
368
void GlyphIterator::setCursiveExitPoint(LEPoint &exitPoint)
369
{
370
if (direction < 0) {
371
if (position <= nextLimit || position >= prevLimit) {
372
return;
373
}
374
} else {
375
if (position <= prevLimit || position >= nextLimit) {
376
return;
377
}
378
}
379
380
glyphPositionAdjustments->setExitPoint(position, exitPoint, baselineIsLogicalEnd());
381
}
382
383
void GlyphIterator::setCursiveGlyph()
384
{
385
if (direction < 0) {
386
if (position <= nextLimit || position >= prevLimit) {
387
return;
388
}
389
} else {
390
if (position <= prevLimit || position >= nextLimit) {
391
return;
392
}
393
}
394
395
glyphPositionAdjustments->setCursiveGlyph(position, baselineIsLogicalEnd());
396
}
397
398
void GlyphIterator::filterResetCache(void) {
399
filterCacheValid = FALSE;
400
}
401
402
le_bool GlyphIterator::filterGlyph(le_uint32 index)
403
{
404
LEGlyphID glyphID = glyphStorage[index];
405
406
if (!filterCacheValid || filterCache.id != glyphID) {
407
filterCache.id = glyphID;
408
409
le_bool &filterResult = filterCache.result; // NB: Making this a reference to accept the updated value, in case
410
// we want more fancy cacheing in the future.
411
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
412
filterResult = TRUE;
413
} else {
414
LEErrorCode success = LE_NO_ERROR;
415
le_int32 glyphClass = gcdNoGlyphClass;
416
if (glyphClassDefinitionTable.isValid()) {
417
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
418
}
419
switch (glyphClass) {
420
case gcdNoGlyphClass:
421
filterResult = FALSE;
422
break;
423
424
case gcdSimpleGlyph:
425
filterResult = (lookupFlags & lfIgnoreBaseGlyphs) != 0;
426
break;
427
428
case gcdLigatureGlyph:
429
filterResult = (lookupFlags & lfIgnoreLigatures) != 0;
430
break;
431
432
case gcdMarkGlyph:
433
if ((lookupFlags & lfIgnoreMarks) != 0) {
434
filterResult = TRUE;
435
} else {
436
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
437
438
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
439
filterResult = (markAttachClassDefinitionTable
440
-> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType);
441
} else {
442
filterResult = FALSE;
443
}
444
}
445
break;
446
447
case gcdComponentGlyph:
448
filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0);
449
break;
450
451
default:
452
filterResult = FALSE;
453
break;
454
}
455
}
456
filterCacheValid = TRUE;
457
}
458
459
return filterCache.result;
460
}
461
462
le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const
463
{
464
if (featureMask == 0) {
465
return TRUE;
466
}
467
468
LEErrorCode success = LE_NO_ERROR;
469
FeatureMask fm = glyphStorage.getAuxData(position, success);
470
471
return ((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup);
472
}
473
474
le_bool GlyphIterator::findFeatureTag()
475
{
476
//glyphGroup = 0;
477
478
while (nextInternal()) {
479
if (hasFeatureTag(FALSE)) {
480
LEErrorCode success = LE_NO_ERROR;
481
482
glyphGroup = (glyphStorage.getAuxData(position, success) & LE_GLYPH_GROUP_MASK);
483
return TRUE;
484
}
485
}
486
487
return FALSE;
488
}
489
490
491
le_bool GlyphIterator::nextInternal(le_uint32 delta)
492
{
493
le_int32 newPosition = position;
494
495
while (newPosition != nextLimit && delta > 0) {
496
do {
497
newPosition += direction;
498
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
499
} while (newPosition != nextLimit && filterGlyph(newPosition));
500
501
delta -= 1;
502
}
503
504
position = newPosition;
505
506
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
507
return position != nextLimit;
508
}
509
510
le_bool GlyphIterator::next(le_uint32 delta)
511
{
512
return nextInternal(delta) && hasFeatureTag(TRUE);
513
}
514
515
le_bool GlyphIterator::prevInternal(le_uint32 delta)
516
{
517
le_int32 newPosition = position;
518
519
while (newPosition != prevLimit && delta > 0) {
520
do {
521
newPosition -= direction;
522
//fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
523
} while (newPosition != prevLimit && filterGlyph(newPosition));
524
525
delta -= 1;
526
}
527
528
position = newPosition;
529
530
//fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
531
return position != prevLimit;
532
}
533
534
le_bool GlyphIterator::prev(le_uint32 delta)
535
{
536
return prevInternal(delta) && hasFeatureTag(TRUE);
537
}
538
539
le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
540
{
541
le_int32 component = 0;
542
le_int32 posn;
543
544
for (posn = position; posn != markPosition; posn += direction) {
545
if (glyphStorage[posn] == 0xFFFE) {
546
component += 1;
547
}
548
}
549
550
return component;
551
}
552
553
// This is basically prevInternal except that it
554
// doesn't take a delta argument, and it doesn't
555
// filter out 0xFFFE glyphs.
556
le_bool GlyphIterator::findMark2Glyph()
557
{
558
le_int32 newPosition = position;
559
560
do {
561
newPosition -= direction;
562
} while (newPosition != prevLimit && glyphStorage[newPosition] != 0xFFFE && filterGlyph(newPosition));
563
564
position = newPosition;
565
566
return position != prevLimit;
567
}
568
569
U_NAMESPACE_END
570
571