author | prr |
Wed, 09 Nov 2016 11:28:13 -0800 | |
changeset 42208 | 7c1017f0ade5 |
parent 34414 | e496a8d8fc8a |
child 47188 | 0048f025c993 |
permissions | -rw-r--r-- |
2 | 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 |
|
5506 | 6 |
* published by the Free Software Foundation. Oracle designates this |
2 | 7 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 8 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 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 |
* |
|
5506 | 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. |
|
2 | 23 |
* |
24 |
*/ |
|
25 |
||
26 |
/* |
|
27 |
* |
|
28 |
* (C) Copyright IBM Corp. 2003 - All Rights Reserved |
|
29 |
*/ |
|
30 |
||
31 |
package sun.font; |
|
32 |
||
33 |
import sun.font.GlyphLayout.*; |
|
34 |
import java.awt.geom.Point2D; |
|
35 |
import java.lang.ref.SoftReference; |
|
12993
98899b2d514c
7027300: Unsynchronized HashMap access causes endless loop
prr
parents:
5506
diff
changeset
|
36 |
import java.util.concurrent.ConcurrentHashMap; |
2 | 37 |
import java.util.Locale; |
38 |
||
39 |
/* |
|
40 |
* different ways to do this |
|
41 |
* 1) each physical font2d keeps a hashtable mapping scripts to layout |
|
42 |
* engines, we query and fill this cache. |
|
43 |
* 2) we keep a mapping independent of font using the key Most likely |
|
44 |
* few fonts will be used, so option 2 seems better |
|
45 |
* |
|
46 |
* Once we know which engine to use for a font, we always know, so we |
|
47 |
* shouldn't have to recheck each time we do layout. So the cache is |
|
48 |
* ok. |
|
49 |
* |
|
50 |
* Should we reuse engines? We could instantiate an engine for each |
|
51 |
* font/script pair. The engine would hold onto the table(s) from the |
|
52 |
* font that it needs. If we have multiple threads using the same |
|
53 |
* engine, we still need to keep the state separate, so the native |
|
54 |
* engines would still need to be allocated for each call, since they |
|
55 |
* keep their state in themselves. If they used the passed-in GVData |
|
56 |
* arrays directly (with some checks for space) then since each GVData |
|
57 |
* is different per thread, we could reuse the layout engines. This |
|
58 |
* still requires a separate layout engine per font, because of the |
|
59 |
* table state in the engine. If we pushed that out too and passed it |
|
60 |
* in with the native call as well, we'd be ok if the layout engines |
|
61 |
* keep all their process state on the stack, but I don't know if this |
|
62 |
* is true. Then we'd basically just be down to an engine index which |
|
63 |
* we pass into native and then invoke the engine code (now a |
|
64 |
* procedure call, not an object invocation) based on a switch on the |
|
65 |
* index. There would be only half a dozen engine objects then, not |
|
66 |
* potentially half a dozen per font. But we'd have to stack-allocate |
|
67 |
* some state that included the pointer to the required font tables. |
|
68 |
* |
|
69 |
* Seems for now that the way to do things is to come in with a |
|
70 |
* selector and the font. The selector indicates which engine to use, |
|
71 |
* the engine is stack allocated and initialized with the required |
|
72 |
* font tables (the selector indicates which). Then layout is called, |
|
73 |
* the contents are copied (or not), and the stack is destroyed on |
|
74 |
* exit. So the association is between the font/script (layout engine |
|
28059
e576535359cc
8067377: My hobby: caning, then then canning, the the can-can
martin
parents:
25859
diff
changeset
|
75 |
* desc) and one of a few permanent engine objects, which are |
2 | 76 |
* handed the key when they need to process something. In the native |
77 |
* case, the engine holds an index, and just passes it together with |
|
78 |
* the key info down to native. Some default cases are the 'default |
|
79 |
* layout' case that just runs the c2gmapper, this stays in java and |
|
80 |
* just uses the mapper from the font/strike. Another default case |
|
81 |
* might be the unicode arabic shaper, since this doesn't care about |
|
82 |
* the font (or script or lang?) it wouldn't need to extract this |
|
83 |
* data. It could be (yikes) ported back to java even to avoid |
|
84 |
* upcalls to check if the font supports a particular unicode |
|
85 |
* character. |
|
86 |
* |
|
87 |
* I'd expect that the majority of scripts use the default mapper for |
|
88 |
* a particular font. Loading the hastable with 40 or so keys 30+ of |
|
89 |
* which all map to the same object is unfortunate. It might be worth |
|
90 |
* instead having a per-font list of 'scripts with non-default |
|
91 |
* engines', e.g. the factory has a hashtable mapping fonts to 'script |
|
92 |
* lists' (the factory has this since the design potentially has other |
|
93 |
* factories, though I admit there's no client for this yet and no |
|
94 |
* public api) and then the script list is queried for the script in |
|
95 |
* question. it can be preloaded at creation time with all the |
|
96 |
* scripts that don't have default engines-- either a list or a hash |
|
97 |
* table, so a null return from the table means 'default' and not 'i |
|
98 |
* don't know yet'. |
|
99 |
* |
|
100 |
* On the other hand, in most all cases the number of unique |
|
101 |
* script/font combinations will be small, so a flat hashtable should |
|
102 |
* suffice. |
|
103 |
* */ |
|
104 |
public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory { |
|
105 |
private static native void initGVIDs(); |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
106 |
private static final boolean useICU; |
2 | 107 |
static { |
108 |
FontManagerNativeLibrary.load(); |
|
109 |
initGVIDs(); |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
110 |
String le = java.security.AccessController.doPrivileged( |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
111 |
new sun.security.action. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
112 |
GetPropertyAction("sun.font.layoutengine", "")); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
113 |
useICU = le.equals("icu"); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
114 |
String verbose = java.security.AccessController.doPrivileged( |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
115 |
new sun.security.action. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
116 |
GetPropertyAction("sun.font.layoutengine.verbose", "")); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
117 |
if ("true".equalsIgnoreCase(verbose)) { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
118 |
System.out.println("Using " + (useICU ? "icu." : "harfbuzz.")); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
119 |
} |
2 | 120 |
} |
121 |
||
122 |
private LayoutEngineKey key; |
|
123 |
||
124 |
private static LayoutEngineFactory instance; |
|
125 |
||
126 |
public static LayoutEngineFactory instance() { |
|
127 |
if (instance == null) { |
|
128 |
instance = new SunLayoutEngine(); |
|
129 |
} |
|
130 |
return instance; |
|
131 |
} |
|
132 |
||
133 |
private SunLayoutEngine() { |
|
134 |
// actually a factory, key is null so layout cannot be called on it |
|
135 |
} |
|
136 |
||
137 |
public LayoutEngine getEngine(Font2D font, int script, int lang) { |
|
138 |
return getEngine(new LayoutEngineKey(font, script, lang)); |
|
139 |
} |
|
140 |
||
141 |
// !!! don't need this unless we have more than one sun layout engine... |
|
142 |
public LayoutEngine getEngine(LayoutEngineKey key) { |
|
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
13232
diff
changeset
|
143 |
ConcurrentHashMap<LayoutEngineKey, LayoutEngine> cache = cacheref.get(); |
2 | 144 |
if (cache == null) { |
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
13232
diff
changeset
|
145 |
cache = new ConcurrentHashMap<>(); |
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
13232
diff
changeset
|
146 |
cacheref = new SoftReference<>(cache); |
2 | 147 |
} |
148 |
||
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
13232
diff
changeset
|
149 |
LayoutEngine e = cache.get(key); |
2 | 150 |
if (e == null) { |
13232
f4d1488bff92
7183251: Netbeans editor renders text wrong on JDK 7u6 build 17
prr
parents:
12993
diff
changeset
|
151 |
LayoutEngineKey copy = key.copy(); |
f4d1488bff92
7183251: Netbeans editor renders text wrong on JDK 7u6 build 17
prr
parents:
12993
diff
changeset
|
152 |
e = new SunLayoutEngine(copy); |
f4d1488bff92
7183251: Netbeans editor renders text wrong on JDK 7u6 build 17
prr
parents:
12993
diff
changeset
|
153 |
cache.put(copy, e); |
2 | 154 |
} |
155 |
return e; |
|
156 |
} |
|
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
13232
diff
changeset
|
157 |
private SoftReference<ConcurrentHashMap<LayoutEngineKey, LayoutEngine>> cacheref = |
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
13232
diff
changeset
|
158 |
new SoftReference<>(null); |
2 | 159 |
|
160 |
private SunLayoutEngine(LayoutEngineKey key) { |
|
161 |
this.key = key; |
|
162 |
} |
|
163 |
||
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
164 |
private boolean isAAT(Font2D font) { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
165 |
if (font instanceof TrueTypeFont) { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
166 |
TrueTypeFont ttf = (TrueTypeFont)font; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
167 |
return ttf.getDirectoryEntry(TrueTypeFont.morxTag) != null || |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
168 |
ttf.getDirectoryEntry(TrueTypeFont.mortTag) != null; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
169 |
} else if (font instanceof PhysicalFont) { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
170 |
PhysicalFont pf = (PhysicalFont)font; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
171 |
return pf.getTableBytes(TrueTypeFont.morxTag) != null || |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
172 |
pf.getTableBytes(TrueTypeFont.mortTag) != null; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
173 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
174 |
return false; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
175 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
176 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
177 |
public void layout(FontStrikeDesc desc, float[] mat, float ptSize, int gmask, |
2 | 178 |
int baseIndex, TextRecord tr, int typo_flags, |
179 |
Point2D.Float pt, GVData data) { |
|
180 |
Font2D font = key.font(); |
|
181 |
FontStrike strike = font.getStrike(desc); |
|
34399
7ea60f3aab93
7162125: [macosx] A font has different behaviour for ligatures depending on its creation mod
prr
parents:
28059
diff
changeset
|
182 |
long layoutTables = font.getLayoutTableCache(); |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
183 |
if (useICU) { |
2 | 184 |
nativeLayout(font, strike, mat, gmask, baseIndex, |
185 |
tr.text, tr.start, tr.limit, tr.min, tr.max, |
|
186 |
key.script(), key.lang(), typo_flags, pt, data, |
|
187 |
font.getUnitsPerEm(), layoutTables); |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
188 |
} else { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
189 |
long pNativeFont = font.getPlatformNativeFontPtr(); // used on OSX |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
190 |
// pScaler probably not needed long term. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
191 |
long pScaler = 0L; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
192 |
if (font instanceof FileFont) { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
193 |
pScaler = ((FileFont)font).getScaler().nativeScaler; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
194 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
195 |
shape(font, strike, ptSize, mat, pScaler, pNativeFont, isAAT(font), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
196 |
tr.text, data, key.script(), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
197 |
tr.start, tr.limit, baseIndex, pt, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
198 |
typo_flags, gmask); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
199 |
} |
2 | 200 |
} |
201 |
||
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
202 |
/* Native method to invoke ICU layout engine */ |
2 | 203 |
private static native void |
204 |
nativeLayout(Font2D font, FontStrike strike, float[] mat, int gmask, |
|
205 |
int baseIndex, char[] chars, int offset, int limit, |
|
206 |
int min, int max, int script, int lang, int typo_flags, |
|
207 |
Point2D.Float pt, GVData data, long upem, long layoutTables); |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
208 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
209 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
210 |
/* Native method to invoke harfbuzz layout engine */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
211 |
private static native boolean |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
212 |
shape(Font2D font, FontStrike strike, float ptSize, float[] mat, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
213 |
long pscaler, long pNativeFont, boolean aat, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
214 |
char[] chars, GVData data, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
215 |
int script, int offset, int limit, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
34399
diff
changeset
|
216 |
int baseIndex, Point2D.Float pt, int typo_flags, int slot); |
2 | 217 |
} |