ThaiFormatter.java
5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Decompiled with CFR 0_118.
*/
package com.adobe.fontengine.inlineformatting.infontformatting;
import com.adobe.fontengine.font.FontLoadingException;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.UnsupportedFontException;
import com.adobe.fontengine.font.opentype.OpenTypeFont;
import com.adobe.fontengine.inlineformatting.AttributedRun;
import com.adobe.fontengine.inlineformatting.ElementAttribute;
import com.adobe.fontengine.inlineformatting.infontformatting.GenericFormatter;
final class ThaiFormatter
extends GenericFormatter {
ThaiFormatter() {
}
protected int removeSaraAm(AttributedRun run, int start, int limit) {
for (int cur = start; cur < limit; ++cur) {
int usv = run.elementAt(cur);
if (usv != 3635) continue;
int prev = cur;
while (start <= prev - 1 && run.getElementStyle(prev - 1, ElementAttribute.isGlyph) != Boolean.TRUE && 3656 <= run.elementAt(prev - 1) && run.elementAt(prev - 1) <= 3659) {
--prev;
}
if (prev == cur) {
run.replace(cur, new int[]{3661, 3634});
} else {
int[] positions = new int[cur - prev + 1];
for (int i = 0; i < positions.length; ++i) {
positions[i] = prev + i;
}
int[] elementIds = new int[cur - prev + 2];
elementIds[0] = 3661;
for (int i2 = 1; i2 < elementIds.length - 1; ++i2) {
elementIds[i2] = run.elementAt(prev + i2 - 1);
}
elementIds[elementIds.length - 1] = 3634;
run.replace(positions, elementIds);
}
++cur;
++limit;
}
return limit;
}
public int firstPass(AttributedRun run, int start, int limit) {
limit = this.removeSaraAm(run, start, limit);
return super.firstPass(run, start, limit);
}
protected void shapeTT(AttributedRun run, int start, int limit) {
boolean OT = false;
boolean C0 = true;
int CA = 2;
int CD = 3;
int CR = 4;
int BASE = 5;
int VA = 6;
int VB = 7;
int DA = 8;
int[] charClass = new int[]{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 6, 0, 0, 6, 6, 6, 6, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 8, 8, 8, 8, 8, 0};
int[] shiftLeft = new int[]{3632, 63248, 3634, 3635, 63233, 63234, 63235, 63236, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 63250, 63251, 63252, 63253, 63254, 63255, 63249, 3662, 3663};
int[] shiftDown = new int[]{3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 63256, 63257, 63258, 3643, 3644, 3645, 3646, 3647, 57408, 57409, 57410, 57411, 57412, 57413, 57414, 57415, 63242, 63243, 63244, 63245, 63246, 3661, 3662, 3663};
int[] shiftLeftAndDown = new int[]{3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 63237, 63238, 63239, 63240, 63241, 3661, 3662, 3663};
int[] removePieceUnder = new int[]{3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 63247, 3598, 3599, 63232, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631};
int baseIndex = Integer.MIN_VALUE;
int baseType = 0;
int baseUsv = -1;
boolean hasVowelAbove = false;
while (start < limit) {
int usv = run.elementAt(start);
if (usv < 3584 || 3663 < usv) {
baseIndex = start;
baseType = 0;
baseUsv = usv;
hasVowelAbove = false;
} else {
int thisCharClass = charClass[usv - 3584];
if (thisCharClass <= 5) {
baseIndex = start;
baseType = thisCharClass;
baseUsv = usv;
hasVowelAbove = false;
} else if (thisCharClass == 7) {
if (baseType == 4) {
run.replace(baseIndex, removePieceUnder[baseUsv - 3584]);
baseType = 1;
} else if (baseType == 3) {
run.replace(start, shiftDown[usv - 3632]);
}
} else if (thisCharClass == 6) {
if (baseType == 2) {
run.replace(start, shiftLeft[usv - 3632]);
}
hasVowelAbove = true;
} else if (thisCharClass == 8) {
if (baseType == 2) {
if (hasVowelAbove) {
run.replace(start, shiftLeft[usv - 3632]);
} else {
run.replace(start, shiftLeftAndDown[usv - 3632]);
}
} else if (!hasVowelAbove) {
run.replace(start, shiftDown[usv - 3632]);
}
}
}
++start;
}
}
protected boolean canFormatTT() {
return true;
}
protected int formatTT(OpenTypeFont otFont, AttributedRun run, int start, int limit, boolean shouldKern) throws InvalidFontException, UnsupportedFontException, FontLoadingException {
this.shapeTT(run, start, limit);
return super.formatTT(otFont, run, start, limit, shouldKern);
}
}