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/classes/sun/font/FileFont.java
38829 views
1
/*
2
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
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
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
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
*
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.
24
*/
25
26
package sun.font;
27
28
import java.lang.ref.Reference;
29
import java.awt.FontFormatException;
30
import java.awt.geom.GeneralPath;
31
import java.awt.geom.Point2D;
32
import java.awt.geom.Rectangle2D;
33
import java.io.File;
34
import java.nio.ByteBuffer;
35
import sun.java2d.Disposer;
36
import sun.java2d.DisposerRecord;
37
38
import java.io.IOException;
39
import java.security.AccessController;
40
import java.security.PrivilegedActionException;
41
import java.security.PrivilegedExceptionAction;
42
43
public abstract class FileFont extends PhysicalFont {
44
45
protected boolean useJavaRasterizer = true;
46
47
/* I/O and file operations are always synchronized on the font
48
* object. Two threads can be accessing the font and retrieving
49
* information, and synchronized only to the extent that filesystem
50
* operations require.
51
* A limited number of files can be open at a time, to limit the
52
* absorption of file descriptors. If a file needs to be opened
53
* when there are none free, then the synchronization of all I/O
54
* ensures that any in progress operation will complete before some
55
* other thread closes the descriptor in order to allocate another one.
56
*/
57
// NB consider using a RAF. FIS has finalize method so may take a
58
// little longer to be GC'd. We don't use this stream at all anyway.
59
// In fact why increase the size of a FileFont object if the stream
60
// isn't needed ..
61
//protected FileInputStream stream;
62
//protected FileChannel channel;
63
protected int fileSize;
64
65
protected FontScaler scaler;
66
67
/* The following variables are used, (and in the case of the arrays,
68
* only initialised) for select fonts where a native scaler may be
69
* used to get glyph images and metrics.
70
* glyphToCharMap is filled in on the fly and used to do a reverse
71
* lookup when a FileFont needs to get the charcode back from a glyph
72
* code so it can re-map via a NativeGlyphMapper to get a native glyph.
73
* This isn't a big hit in time, since a boolean test is sufficient
74
* to choose the usual default path, nor in memory for fonts which take
75
* the native path, since fonts have contiguous zero-based glyph indexes,
76
* and these obviously do all exist in the font.
77
*/
78
protected boolean checkedNatives;
79
protected boolean useNatives;
80
protected NativeFont[] nativeFonts;
81
protected char[] glyphToCharMap;
82
/*
83
* @throws FontFormatException - if the font can't be opened
84
*/
85
FileFont(String platname, Object nativeNames)
86
throws FontFormatException {
87
88
super(platname, nativeNames);
89
}
90
91
FontStrike createStrike(FontStrikeDesc desc) {
92
if (!checkedNatives) {
93
checkUseNatives();
94
}
95
return new FileFontStrike(this, desc);
96
}
97
98
protected boolean checkUseNatives() {
99
checkedNatives = true;
100
return useNatives;
101
}
102
103
/* This method needs to be accessible to FontManager if there is
104
* file pool management. It may be a no-op.
105
*/
106
protected abstract void close();
107
108
109
/*
110
* This is the public interface. The subclasses need to implement
111
* this. The returned block may be longer than the requested length.
112
*/
113
abstract ByteBuffer readBlock(int offset, int length);
114
115
public boolean canDoStyle(int style) {
116
return true;
117
}
118
119
void setFileToRemove(File file, CreatedFontTracker tracker) {
120
Disposer.addObjectRecord(this,
121
new CreatedFontFileDisposerRecord(file, tracker));
122
}
123
124
// MACOSX begin -- Make this static so that we can pass in CFont
125
static void setFileToRemove(Object font, File file, CreatedFontTracker tracker) {
126
Disposer.addObjectRecord(font,
127
new CreatedFontFileDisposerRecord(file, tracker));
128
}
129
// MACOSX - end
130
131
/* This is called when a font scaler is determined to
132
* be unusable (ie bad).
133
* We want to replace current scaler with NullFontScaler, so
134
* we never try to use same font scaler again.
135
* Scaler native resources could have already been disposed
136
* or they will be eventually by Java2D disposer.
137
* However, it should be safe to call dispose() explicitly here.
138
*
139
* For safety we also invalidate all strike's scaler context.
140
* So, in case they cache pointer to native scaler
141
* it will not ever be used.
142
*
143
* It also appears desirable to remove all the entries from the
144
* cache so no other code will pick them up. But we can't just
145
* 'delete' them as code may be using them. And simply dropping
146
* the reference to the cache will make the reference objects
147
* unreachable and so they will not get disposed.
148
* Since a strike may hold (via java arrays) native pointers to many
149
* rasterised glyphs, this would be a memory leak.
150
* The solution is :
151
* - to move all the entries to another map where they
152
* are no longer locatable
153
* - update FontStrikeDisposer to be able to distinguish which
154
* map they are held in via a boolean flag
155
* Since this isn't expected to be anything other than an extremely
156
* rare maybe it is not worth doing this last part.
157
*/
158
synchronized void deregisterFontAndClearStrikeCache() {
159
SunFontManager fm = SunFontManager.getInstance();
160
fm.deRegisterBadFont(this);
161
162
for (Reference strikeRef : strikeCache.values()) {
163
if (strikeRef != null) {
164
/* NB we know these are all FileFontStrike instances
165
* because the cache is on this FileFont
166
*/
167
FileFontStrike strike = (FileFontStrike)strikeRef.get();
168
if (strike != null && strike.pScalerContext != 0L) {
169
scaler.invalidateScalerContext(strike.pScalerContext);
170
}
171
}
172
}
173
if (scaler != null) {
174
scaler.disposeScaler();
175
}
176
scaler = FontScaler.getNullScaler();
177
}
178
179
StrikeMetrics getFontMetrics(long pScalerContext) {
180
try {
181
return getScaler().getFontMetrics(pScalerContext);
182
} catch (FontScalerException fe) {
183
scaler = FontScaler.getNullScaler();
184
return getFontMetrics(pScalerContext);
185
}
186
}
187
188
float getGlyphAdvance(long pScalerContext, int glyphCode) {
189
try {
190
return getScaler().getGlyphAdvance(pScalerContext, glyphCode);
191
} catch (FontScalerException fe) {
192
scaler = FontScaler.getNullScaler();
193
return getGlyphAdvance(pScalerContext, glyphCode);
194
}
195
}
196
197
void getGlyphMetrics(long pScalerContext, int glyphCode, Point2D.Float metrics) {
198
try {
199
getScaler().getGlyphMetrics(pScalerContext, glyphCode, metrics);
200
} catch (FontScalerException fe) {
201
scaler = FontScaler.getNullScaler();
202
getGlyphMetrics(pScalerContext, glyphCode, metrics);
203
}
204
}
205
206
long getGlyphImage(long pScalerContext, int glyphCode) {
207
try {
208
return getScaler().getGlyphImage(pScalerContext, glyphCode);
209
} catch (FontScalerException fe) {
210
scaler = FontScaler.getNullScaler();
211
return getGlyphImage(pScalerContext, glyphCode);
212
}
213
}
214
215
Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext, int glyphCode) {
216
try {
217
return getScaler().getGlyphOutlineBounds(pScalerContext, glyphCode);
218
} catch (FontScalerException fe) {
219
scaler = FontScaler.getNullScaler();
220
return getGlyphOutlineBounds(pScalerContext, glyphCode);
221
}
222
}
223
224
GeneralPath getGlyphOutline(long pScalerContext, int glyphCode, float x, float y) {
225
try {
226
return getScaler().getGlyphOutline(pScalerContext, glyphCode, x, y);
227
} catch (FontScalerException fe) {
228
scaler = FontScaler.getNullScaler();
229
return getGlyphOutline(pScalerContext, glyphCode, x, y);
230
}
231
}
232
233
GeneralPath getGlyphVectorOutline(long pScalerContext, int[] glyphs, int numGlyphs, float x, float y) {
234
try {
235
return getScaler().getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
236
} catch (FontScalerException fe) {
237
scaler = FontScaler.getNullScaler();
238
return getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
239
}
240
}
241
242
/* T1 & TT implementation differ so this method is abstract.
243
NB: null should not be returned here! */
244
protected abstract FontScaler getScaler();
245
246
protected long getUnitsPerEm() {
247
return getScaler().getUnitsPerEm();
248
}
249
250
private static class CreatedFontFileDisposerRecord
251
implements DisposerRecord {
252
253
File fontFile = null;
254
CreatedFontTracker tracker;
255
256
private CreatedFontFileDisposerRecord(File file,
257
CreatedFontTracker tracker) {
258
fontFile = file;
259
this.tracker = tracker;
260
}
261
262
public void dispose() {
263
java.security.AccessController.doPrivileged(
264
new java.security.PrivilegedAction() {
265
public Object run() {
266
if (fontFile != null) {
267
try {
268
if (tracker != null) {
269
tracker.subBytes((int)fontFile.length());
270
}
271
/* REMIND: is it possible that the file is
272
* still open? It will be closed when the
273
* font2D is disposed but could this code
274
* execute first? If so the file would not
275
* be deleted on MS-windows.
276
*/
277
fontFile.delete();
278
/* remove from delete on exit hook list : */
279
// FIXME: still need to be refactored
280
SunFontManager.getInstance().tmpFontFiles.remove(fontFile);
281
} catch (Exception e) {
282
}
283
}
284
return null;
285
}
286
});
287
}
288
}
289
290
protected String getPublicFileName() {
291
SecurityManager sm = System.getSecurityManager();
292
if (sm == null) {
293
return platName;
294
}
295
boolean canReadProperty = true;
296
297
try {
298
sm.checkPropertyAccess("java.io.tmpdir");
299
} catch (SecurityException e) {
300
canReadProperty = false;
301
}
302
303
if (canReadProperty) {
304
return platName;
305
}
306
307
final File f = new File(platName);
308
309
Boolean isTmpFile = Boolean.FALSE;
310
try {
311
isTmpFile = AccessController.doPrivileged(
312
new PrivilegedExceptionAction<Boolean>() {
313
public Boolean run() {
314
File tmp = new File(System.getProperty("java.io.tmpdir"));
315
try {
316
String tpath = tmp.getCanonicalPath();
317
String fpath = f.getCanonicalPath();
318
319
return (fpath == null) || fpath.startsWith(tpath);
320
} catch (IOException e) {
321
return Boolean.TRUE;
322
}
323
}
324
}
325
);
326
} catch (PrivilegedActionException e) {
327
// unable to verify whether value of java.io.tempdir will be
328
// exposed, so return only a name of the font file.
329
isTmpFile = Boolean.TRUE;
330
}
331
332
return isTmpFile ? "temp file" : platName;
333
}
334
}
335
336