author | erikj |
Tue, 12 Sep 2017 19:03:39 +0200 | |
changeset 47216 | 71c04702a3d5 |
parent 33299 | jdk/src/java.desktop/share/native/libfontmanager/layout/MorphTables2.cpp@78f5508cde89 |
permissions | -rw-r--r-- |
16889 | 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 |
* (C) Copyright IBM Corp. and others 1998 - 2013 - All Rights Reserved |
|
28 |
* |
|
29 |
*/ |
|
30 |
||
31 |
#include "LETypes.h" |
|
32 |
#include "LayoutTables.h" |
|
33 |
#include "MorphTables.h" |
|
34 |
#include "SubtableProcessor2.h" |
|
35 |
#include "IndicRearrangementProcessor2.h" |
|
36 |
#include "ContextualGlyphSubstProc2.h" |
|
37 |
#include "LigatureSubstProc2.h" |
|
38 |
#include "NonContextualGlyphSubstProc2.h" |
|
39 |
#include "ContextualGlyphInsertionProc2.h" |
|
40 |
#include "LEGlyphStorage.h" |
|
41 |
#include "LESwaps.h" |
|
42 |
||
43 |
U_NAMESPACE_BEGIN |
|
44 |
||
16891 | 45 |
void MorphTableHeader2::process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage, |
46 |
le_int32 typoFlags, LEErrorCode &success) const |
|
16889 | 47 |
{ |
16891 | 48 |
if(LE_FAILURE(success)) return; |
16889 | 49 |
|
16891 | 50 |
le_uint32 chainCount = SWAPL(this->nChains); |
51 |
LEReferenceTo<ChainHeader2> chainHeader(base, success, &chains[0]); |
|
52 |
/* chainHeader and subtableHeader are implemented as a moving pointer rather than an array dereference |
|
53 |
* to (slightly) reduce code churn. However, must be careful to preincrement them the 2nd time through. |
|
54 |
* We don't want to increment them at the end of the loop, as that would attempt to dereference |
|
55 |
* out of range memory. |
|
56 |
*/ |
|
57 |
le_uint32 chain; |
|
58 |
||
59 |
for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain++) { |
|
60 |
if (chain>0) { |
|
61 |
le_uint32 chainLength = SWAPL(chainHeader->chainLength); |
|
31694
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
62 |
if (chainLength & 0x03) { // incorrect alignment for 32 bit tables |
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
63 |
success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any |
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
64 |
return; |
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
65 |
} |
16891 | 66 |
chainHeader.addOffset(chainLength, success); // Don't increment the first time |
67 |
} |
|
16889 | 68 |
FeatureFlags flag = SWAPL(chainHeader->defaultFlags); |
69 |
le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries); |
|
70 |
le_uint32 nSubtables = SWAPL(chainHeader->nSubtables); |
|
16891 | 71 |
LEReferenceTo<MorphSubtableHeader2> subtableHeader(chainHeader, |
72 |
success, (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]); |
|
16889 | 73 |
le_uint32 subtable; |
16891 | 74 |
if(LE_FAILURE(success)) break; // malformed table |
16889 | 75 |
|
76 |
if (typoFlags != 0) { |
|
77 |
le_uint32 featureEntry; |
|
16891 | 78 |
LEReferenceToArrayOf<FeatureTableEntry> featureTableRef(chainHeader, success, &chainHeader->featureTable[0], nFeatureEntries); |
79 |
if(LE_FAILURE(success)) break; |
|
16889 | 80 |
// Feature subtables |
81 |
for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) { |
|
16891 | 82 |
const FeatureTableEntry &featureTableEntry = featureTableRef(featureEntry, success); |
16889 | 83 |
le_int16 featureType = SWAPW(featureTableEntry.featureType); |
84 |
le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting); |
|
85 |
le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags); |
|
86 |
le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags); |
|
87 |
switch (featureType) { |
|
88 |
case ligaturesType: |
|
89 |
if ((typoFlags & LE_Ligatures_FEATURE_ENUM ) && (featureSetting ^ 0x1)){ |
|
90 |
flag &= disableFlags; |
|
91 |
flag |= enableFlags; |
|
92 |
} else { |
|
93 |
if (((typoFlags & LE_RLIG_FEATURE_FLAG) && featureSetting == requiredLigaturesOnSelector) || |
|
94 |
((typoFlags & LE_CLIG_FEATURE_FLAG) && featureSetting == contextualLigaturesOnSelector) || |
|
95 |
((typoFlags & LE_HLIG_FEATURE_FLAG) && featureSetting == historicalLigaturesOnSelector) || |
|
96 |
((typoFlags & LE_LIGA_FEATURE_FLAG) && featureSetting == commonLigaturesOnSelector)) { |
|
97 |
flag &= disableFlags; |
|
98 |
flag |= enableFlags; |
|
99 |
} |
|
100 |
} |
|
101 |
break; |
|
102 |
case letterCaseType: |
|
103 |
if ((typoFlags & LE_SMCP_FEATURE_FLAG) && featureSetting == smallCapsSelector) { |
|
104 |
flag &= disableFlags; |
|
105 |
flag |= enableFlags; |
|
106 |
} |
|
107 |
break; |
|
108 |
case verticalSubstitutionType: |
|
109 |
break; |
|
110 |
case linguisticRearrangementType: |
|
111 |
break; |
|
112 |
case numberSpacingType: |
|
113 |
break; |
|
114 |
case smartSwashType: |
|
115 |
if ((typoFlags & LE_SWSH_FEATURE_FLAG) && (featureSetting ^ 0x1)){ |
|
116 |
flag &= disableFlags; |
|
117 |
flag |= enableFlags; |
|
118 |
} |
|
119 |
break; |
|
120 |
case diacriticsType: |
|
121 |
break; |
|
122 |
case verticalPositionType: |
|
123 |
break; |
|
124 |
case fractionsType: |
|
125 |
if (((typoFlags & LE_FRAC_FEATURE_FLAG) && featureSetting == diagonalFractionsSelector) || |
|
126 |
((typoFlags & LE_AFRC_FEATURE_FLAG) && featureSetting == verticalFractionsSelector)) { |
|
127 |
flag &= disableFlags; |
|
128 |
flag |= enableFlags; |
|
129 |
} else { |
|
130 |
flag &= disableFlags; |
|
131 |
} |
|
132 |
break; |
|
133 |
case typographicExtrasType: |
|
134 |
if ((typoFlags & LE_ZERO_FEATURE_FLAG) && featureSetting == slashedZeroOnSelector) { |
|
135 |
flag &= disableFlags; |
|
136 |
flag |= enableFlags; |
|
137 |
} |
|
138 |
break; |
|
139 |
case mathematicalExtrasType: |
|
140 |
break; |
|
141 |
case ornamentSetsType: |
|
142 |
break; |
|
143 |
case characterAlternativesType: |
|
144 |
break; |
|
145 |
case designComplexityType: |
|
146 |
if (((typoFlags & LE_SS01_FEATURE_FLAG) && featureSetting == designLevel1Selector) || |
|
147 |
((typoFlags & LE_SS02_FEATURE_FLAG) && featureSetting == designLevel2Selector) || |
|
148 |
((typoFlags & LE_SS03_FEATURE_FLAG) && featureSetting == designLevel3Selector) || |
|
149 |
((typoFlags & LE_SS04_FEATURE_FLAG) && featureSetting == designLevel4Selector) || |
|
150 |
((typoFlags & LE_SS05_FEATURE_FLAG) && featureSetting == designLevel5Selector) || |
|
151 |
((typoFlags & LE_SS06_FEATURE_FLAG) && featureSetting == designLevel6Selector) || |
|
152 |
((typoFlags & LE_SS07_FEATURE_FLAG) && featureSetting == designLevel7Selector)) { |
|
153 |
||
154 |
flag &= disableFlags; |
|
155 |
flag |= enableFlags; |
|
156 |
} |
|
157 |
break; |
|
158 |
case styleOptionsType: |
|
159 |
break; |
|
160 |
case characterShapeType: |
|
161 |
break; |
|
162 |
case numberCaseType: |
|
163 |
break; |
|
164 |
case textSpacingType: |
|
165 |
break; |
|
166 |
case transliterationType: |
|
167 |
break; |
|
168 |
case annotationType: |
|
169 |
if ((typoFlags & LE_NALT_FEATURE_FLAG) && featureSetting == circleAnnotationSelector) { |
|
170 |
flag &= disableFlags; |
|
171 |
flag |= enableFlags; |
|
172 |
} |
|
173 |
break; |
|
174 |
case kanaSpacingType: |
|
175 |
break; |
|
176 |
case ideographicSpacingType: |
|
177 |
break; |
|
178 |
case rubyKanaType: |
|
179 |
if ((typoFlags & LE_RUBY_FEATURE_FLAG) && featureSetting == rubyKanaOnSelector) { |
|
180 |
flag &= disableFlags; |
|
181 |
flag |= enableFlags; |
|
182 |
} |
|
183 |
break; |
|
184 |
case cjkRomanSpacingType: |
|
185 |
break; |
|
186 |
default: |
|
187 |
break; |
|
188 |
} |
|
189 |
} |
|
190 |
} |
|
191 |
||
16891 | 192 |
for (subtable = 0; LE_SUCCESS(success) && subtable < nSubtables; subtable++) { |
193 |
if(subtable>0) { |
|
194 |
le_uint32 length = SWAPL(subtableHeader->length); |
|
31694
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
195 |
if (length & 0x03) { // incorrect alignment for 32 bit tables |
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
196 |
success = LE_MEMORY_ALLOCATION_ERROR; // as good a choice as any |
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
197 |
return; |
dd8aceb1d10e
8074098: 2D_Font/Bug8067699 test fails with SIGBUS crash on Solaris Sparc
prr
parents:
25859
diff
changeset
|
198 |
} |
16891 | 199 |
subtableHeader.addOffset(length, success); // Don't addOffset for the last entry. |
33299 | 200 |
if (LE_FAILURE(success)) break; |
16891 | 201 |
} |
16889 | 202 |
le_uint32 coverage = SWAPL(subtableHeader->coverage); |
203 |
FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures); |
|
204 |
// should check coverage more carefully... |
|
205 |
if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) { |
|
16891 | 206 |
subtableHeader->process(subtableHeader, glyphStorage, success); |
16889 | 207 |
} |
208 |
} |
|
209 |
} |
|
210 |
} |
|
211 |
||
16891 | 212 |
void MorphSubtableHeader2::process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const |
16889 | 213 |
{ |
214 |
SubtableProcessor2 *processor = NULL; |
|
215 |
||
33299 | 216 |
if (LE_FAILURE(success)) return; |
217 |
||
16889 | 218 |
switch (SWAPL(coverage) & scfTypeMask2) |
219 |
{ |
|
220 |
case mstIndicRearrangement: |
|
16891 | 221 |
processor = new IndicRearrangementProcessor2(base, success); |
16889 | 222 |
break; |
223 |
||
224 |
case mstContextualGlyphSubstitution: |
|
16891 | 225 |
processor = new ContextualGlyphSubstitutionProcessor2(base, success); |
16889 | 226 |
break; |
227 |
||
228 |
case mstLigatureSubstitution: |
|
16891 | 229 |
processor = new LigatureSubstitutionProcessor2(base, success); |
16889 | 230 |
break; |
231 |
||
232 |
case mstReservedUnused: |
|
233 |
break; |
|
234 |
||
235 |
case mstNonContextualGlyphSubstitution: |
|
16891 | 236 |
processor = NonContextualGlyphSubstitutionProcessor2::createInstance(base, success); |
16889 | 237 |
break; |
238 |
||
239 |
||
240 |
case mstContextualGlyphInsertion: |
|
16891 | 241 |
processor = new ContextualGlyphInsertionProcessor2(base, success); |
16889 | 242 |
break; |
243 |
||
244 |
default: |
|
16891 | 245 |
return; |
246 |
break; /*NOTREACHED*/ |
|
16889 | 247 |
} |
248 |
||
249 |
if (processor != NULL) { |
|
16891 | 250 |
processor->process(glyphStorage, success); |
16889 | 251 |
delete processor; |
16891 | 252 |
} else { |
253 |
if(LE_SUCCESS(success)) { |
|
254 |
success = LE_MEMORY_ALLOCATION_ERROR; // because ptr is null and we didn't break out. |
|
255 |
} |
|
16889 | 256 |
} |
257 |
} |
|
258 |
||
259 |
U_NAMESPACE_END |