author | prr |
Thu, 22 Mar 2018 14:10:30 -0700 | |
changeset 49310 | edbc57573a1c |
parent 49234 | 3375a8039fde |
child 50651 | 0c94d8cc5081 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
2 |
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.font; |
|
27 |
||
28 |
import java.awt.geom.GeneralPath; |
|
29 |
import java.awt.geom.Point2D; |
|
30 |
import java.awt.geom.Rectangle2D; |
|
31 |
import java.lang.ref.WeakReference; |
|
3928 | 32 |
import java.lang.reflect.Constructor; |
33 |
||
34 |
import sun.java2d.Disposer; |
|
2 | 35 |
import sun.java2d.DisposerRecord; |
36 |
||
37 |
/* FontScaler is "internal interface" to font rasterizer library. |
|
38 |
* |
|
39 |
* Access to native rasterizers without going through this interface is |
|
40 |
* strongly discouraged. In particular, this is important because native |
|
41 |
* data could be disposed due to runtime font processing error at any time. |
|
42 |
* |
|
43 |
* FontScaler represents combination of particular rasterizer implementation |
|
44 |
* and particular font. It does not include rasterization attributes such as |
|
45 |
* transform. These attributes are part of native scalerContext object. |
|
46 |
* This approach allows to share same scaler for different requests related |
|
47 |
* to the same font file. |
|
48 |
* |
|
49 |
* Note that scaler may throw FontScalerException on any operation. |
|
50 |
* Generally this means that runtime error had happened and scaler is not |
|
51 |
* usable. Subsequent calls to this scaler should not cause crash but will |
|
52 |
* likely cause exceptions to be thrown again. |
|
53 |
* |
|
54 |
* It is recommended that callee should replace its reference to the scaler |
|
55 |
* with something else. For instance it could be FontManager.getNullScaler(). |
|
56 |
* Note that NullScaler is trivial and will not actually rasterize anything. |
|
57 |
* |
|
58 |
* Alternatively, callee can use more sophisticated error recovery strategies |
|
59 |
* and for instance try to substitute failed scaler with new scaler instance |
|
60 |
* using another font. |
|
61 |
* |
|
62 |
* Note that in case of error there is no need to call dispose(). Moreover, |
|
63 |
* dispose() generally is called by Disposer thread and explicit calls to |
|
64 |
* dispose might have unexpected sideeffects because scaler can be shared. |
|
65 |
* |
|
66 |
* Current disposing logic is the following: |
|
67 |
* - scaler is registered in the Disposer by the FontManager (on creation) |
|
68 |
* - scalers are disposed when associated Font2D object (e.g. TruetypeFont) |
|
69 |
* is garbage collected. That's why this object implements DisposerRecord |
|
70 |
* interface directly (as it is not used as indicator when it is safe |
|
71 |
* to release native state) and that's why we have to use WeakReference |
|
72 |
* to Font internally. |
|
73 |
* - Majority of Font2D objects are linked from various mapping arrays |
|
74 |
* (e.g. FontManager.localeFullNamesToFont). So, they are not collected. |
|
75 |
* This logic only works for fonts created with Font.createFont() |
|
76 |
* |
|
77 |
* Notes: |
|
78 |
* - Eventually we may consider releasing some of the scaler resources if |
|
79 |
* it was not used for a while but we do not want to be too aggressive on |
|
80 |
* this (and this is probably more important for Type1 fonts). |
|
81 |
*/ |
|
82 |
public abstract class FontScaler implements DisposerRecord { |
|
3928 | 83 |
|
84 |
private static FontScaler nullScaler = null; |
|
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
85 |
private static Constructor<? extends FontScaler> scalerConstructor = null; |
3928 | 86 |
|
87 |
//Find preferred font scaler |
|
88 |
// |
|
89 |
//NB: we can allow property based preferences |
|
90 |
// (theoretically logic can be font type specific) |
|
91 |
static { |
|
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
92 |
Class<? extends FontScaler> scalerClass = null; |
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
93 |
Class<?>[] arglst = new Class<?>[] {Font2D.class, int.class, |
3928 | 94 |
boolean.class, int.class}; |
95 |
||
96 |
try { |
|
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
97 |
@SuppressWarnings("unchecked") |
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
98 |
Class<? extends FontScaler> tmp = (Class<? extends FontScaler>) |
49310
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
99 |
((!FontUtilities.useT2K && !FontUtilities.useLegacy) ? |
23288
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
100 |
Class.forName("sun.font.FreetypeFontScaler") : |
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
101 |
Class.forName("sun.font.T2KFontScaler")); |
b7183846db97
8033624: Fix raw and unchecked lint warnings in sun.font
darcy
parents:
9759
diff
changeset
|
102 |
scalerClass = tmp; |
3928 | 103 |
} catch (ClassNotFoundException e) { |
49310
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
104 |
try { |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
105 |
@SuppressWarnings("unchecked") |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
106 |
Class<? extends FontScaler> tmp = (Class<? extends FontScaler>) |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
107 |
Class.forName("sun.font.FreetypeFontScaler"); |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
108 |
scalerClass = tmp; |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
109 |
} catch (ClassNotFoundException e1) { |
3928 | 110 |
scalerClass = NullFontScaler.class; |
49310
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
111 |
} |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
112 |
} finally { |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
113 |
if (FontUtilities.debugFonts()) { |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
114 |
System.out.println("Scaler class="+scalerClass); |
edbc57573a1c
8199789: Emit a warning message when t2k is selected via system property
prr
parents:
49234
diff
changeset
|
115 |
} |
3928 | 116 |
} |
117 |
||
118 |
//NB: rewrite using factory? constructor is ugly way |
|
119 |
try { |
|
120 |
scalerConstructor = scalerClass.getConstructor(arglst); |
|
121 |
} catch (NoSuchMethodException e) { |
|
122 |
//should not happen |
|
123 |
} |
|
124 |
} |
|
125 |
||
126 |
/* This is the only place to instantiate new FontScaler. |
|
127 |
* Therefore this is very convinient place to register |
|
128 |
* scaler with Disposer as well as trigger deregistring bad font |
|
129 |
* in case when scaler reports this. |
|
130 |
*/ |
|
131 |
public static FontScaler getScaler(Font2D font, |
|
132 |
int indexInCollection, |
|
133 |
boolean supportsCJK, |
|
134 |
int filesize) { |
|
135 |
FontScaler scaler = null; |
|
136 |
||
137 |
try { |
|
138 |
Object args[] = new Object[] {font, indexInCollection, |
|
139 |
supportsCJK, filesize}; |
|
140 |
scaler = scalerConstructor.newInstance(args); |
|
141 |
Disposer.addObjectRecord(font, scaler); |
|
142 |
} catch (Throwable e) { |
|
143 |
scaler = nullScaler; |
|
144 |
||
145 |
//if we can not instantiate scaler assume bad font |
|
146 |
//NB: technically it could be also because of internal scaler |
|
147 |
// error but here we are assuming scaler is ok. |
|
148 |
FontManager fm = FontManagerFactory.getInstance(); |
|
149 |
fm.deRegisterBadFont(font); |
|
150 |
} |
|
151 |
return scaler; |
|
152 |
} |
|
153 |
||
154 |
/* |
|
155 |
* At the moment it is harmless to create 2 null scalers so, technically, |
|
156 |
* syncronized keyword is not needed. |
|
157 |
* |
|
158 |
* But it is safer to keep it to avoid subtle problems if we will be adding |
|
159 |
* checks like whether scaler is null scaler. |
|
160 |
*/ |
|
161 |
public static synchronized FontScaler getNullScaler() { |
|
162 |
if (nullScaler == null) { |
|
163 |
nullScaler = new NullFontScaler(); |
|
164 |
} |
|
165 |
return nullScaler; |
|
166 |
} |
|
167 |
||
2 | 168 |
protected WeakReference<Font2D> font = null; |
169 |
protected long nativeScaler = 0; //used by decendants |
|
170 |
//that have native state |
|
171 |
protected boolean disposed = false; |
|
172 |
||
173 |
abstract StrikeMetrics getFontMetrics(long pScalerContext) |
|
174 |
throws FontScalerException; |
|
175 |
||
176 |
abstract float getGlyphAdvance(long pScalerContext, int glyphCode) |
|
177 |
throws FontScalerException; |
|
178 |
||
179 |
abstract void getGlyphMetrics(long pScalerContext, int glyphCode, |
|
180 |
Point2D.Float metrics) |
|
181 |
throws FontScalerException; |
|
182 |
||
183 |
/* |
|
184 |
* Returns pointer to native GlyphInfo object. |
|
185 |
* Callee is responsible for freeing this memory. |
|
186 |
* |
|
187 |
* Note: |
|
188 |
* currently this method has to return not 0L but pointer to valid |
|
189 |
* GlyphInfo object. Because Strike and drawing releated logic does |
|
190 |
* expect that. |
|
191 |
* In the future we may want to rework this to allow 0L here. |
|
192 |
*/ |
|
193 |
abstract long getGlyphImage(long pScalerContext, int glyphCode) |
|
194 |
throws FontScalerException; |
|
195 |
||
196 |
abstract Rectangle2D.Float getGlyphOutlineBounds(long pContext, |
|
197 |
int glyphCode) |
|
198 |
throws FontScalerException; |
|
199 |
||
200 |
abstract GeneralPath getGlyphOutline(long pScalerContext, int glyphCode, |
|
201 |
float x, float y) |
|
202 |
throws FontScalerException; |
|
203 |
||
204 |
abstract GeneralPath getGlyphVectorOutline(long pScalerContext, int[] glyphs, |
|
205 |
int numGlyphs, float x, float y) |
|
206 |
throws FontScalerException; |
|
207 |
||
208 |
/* Used by Java2D disposer to ensure native resources are released. |
|
209 |
Note: this method does not release any of created |
|
210 |
scaler context objects! */ |
|
211 |
public void dispose() {} |
|
212 |
||
213 |
/* At the moment these 3 methods are needed for Type1 fonts only. |
|
214 |
* For Truetype fonts we extract required info outside of scaler |
|
215 |
* on java layer. |
|
216 |
*/ |
|
217 |
abstract int getNumGlyphs() throws FontScalerException; |
|
218 |
abstract int getMissingGlyphCode() throws FontScalerException; |
|
219 |
abstract int getGlyphCode(char charCode) throws FontScalerException; |
|
220 |
||
221 |
/* This method returns table cache used by native layout engine. |
|
222 |
* This cache is essentially just small collection of |
|
223 |
* pointers to various truetype tables. See definition of TTLayoutTableCache |
|
224 |
* in the fontscalerdefs.h for more details. |
|
225 |
* |
|
226 |
* Note that tables themselves have same format as defined in the truetype |
|
227 |
* specification, i.e. font scaler do not need to perform any preprocessing. |
|
228 |
* |
|
229 |
* Probably it is better to have API to request pointers to each table |
|
230 |
* separately instead of requesting pointer to some native structure. |
|
231 |
* (then there is not need to share its definition by different |
|
232 |
* implementations of scaler). |
|
233 |
* However, this means multiple JNI calls and potential impact on performance. |
|
234 |
* |
|
235 |
* Note: return value 0 is legal. |
|
236 |
* This means tables are not available (e.g. type1 font). |
|
237 |
*/ |
|
238 |
abstract long getLayoutTableCache() throws FontScalerException; |
|
239 |
||
240 |
/* Used by the OpenType engine for mark positioning. */ |
|
241 |
abstract Point2D.Float getGlyphPoint(long pScalerContext, |
|
242 |
int glyphCode, int ptNumber) |
|
243 |
throws FontScalerException; |
|
244 |
||
245 |
abstract long getUnitsPerEm(); |
|
246 |
||
247 |
/* Returns pointer to native structure describing rasterization attributes. |
|
248 |
Format of this structure is scaler-specific. |
|
249 |
||
250 |
Callee is responsible for freeing scaler context (using free()). |
|
251 |
||
252 |
Note: |
|
253 |
Context is tightly associated with strike and it is actually |
|
254 |
freed when corresponding strike is being released. |
|
255 |
*/ |
|
256 |
abstract long createScalerContext(double[] matrix, |
|
7940
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
5506
diff
changeset
|
257 |
int aa, int fm, |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
5506
diff
changeset
|
258 |
float boldness, float italic, |
7d20d72dd3b9
6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents:
5506
diff
changeset
|
259 |
boolean disableHinting); |
2 | 260 |
|
261 |
/* Marks context as invalid because native scaler is invalid. |
|
262 |
Notes: |
|
263 |
- pointer itself is still valid and has to be released |
|
264 |
- if pointer to native scaler was cached it |
|
265 |
should not be neither disposed nor used. |
|
266 |
it is very likely it is already disposed by this moment. */ |
|
267 |
abstract void invalidateScalerContext(long ppScalerContext); |
|
268 |
} |