Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/font/NativeFont.java
32287 views
1
/*
2
* Copyright (c) 2003, 2006, 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.awt.Font;
29
import java.awt.FontFormatException;
30
import java.awt.GraphicsEnvironment;
31
import java.awt.font.FontRenderContext;
32
import java.awt.geom.GeneralPath;
33
import java.awt.geom.Point2D;
34
import java.awt.geom.Rectangle2D;
35
import java.io.UnsupportedEncodingException;
36
import java.lang.ref.WeakReference;
37
import java.util.Locale;
38
39
/*
40
* Ideally there would be no native fonts used, and this class would be
41
* unneeded and removed. Presently it is still needed until such time
42
* as font configuration files (or the implementation equivalent) can have
43
* all references to fonts that are not handled via Java 2D removed.
44
* Currently there are two cases where this class is needed, both on
45
* Unix, primarily Solaris, but useful on Linux too if fonts have moved.
46
* 1. Some legacy F3 fonts are still referenced so that AWT "X/Motif"
47
* can get dingbats and symbols from them. This can be dispensed with when
48
* either AWT is based on 2D, or when the X font path is known to always
49
* contain a Type1 or TrueType font that can be used in font configuration
50
* files to replace the F3 fonts.
51
* 2. When location of font files by 2D fails, because of some system
52
* configuration problem, it is desirable to have a fall back to some
53
* functionality that lessens the immediate impact on users. Being able
54
* to perform limited operations by using bitmaps from X11 helps here.
55
*/
56
57
public class NativeFont extends PhysicalFont {
58
59
String encoding;
60
61
private int numGlyphs = -1;
62
boolean isBitmapDelegate;
63
PhysicalFont delegateFont;
64
65
/**
66
* Verifies native font is accessible.
67
* @throws FontFormatException - if the font can't be located.
68
*/
69
public NativeFont(String platName, boolean bitmapDelegate)
70
throws FontFormatException {
71
super(platName, null);
72
73
/* This is set true if this is an instance of a NativeFont
74
* created by some other font, to get native bitmaps.
75
* The delegating font will call this font only for "basic"
76
* cases - ie non-rotated, uniform scale, monochrome bitmaps.
77
* If this is false, then this instance may need to itself
78
* delegate to another font for non-basic cases. Since
79
* NativeFonts are used in that way only for symbol and dingbats
80
* we know its safe to delegate these to the JRE's default
81
* physical font (Lucida Sans Regular).
82
*/
83
isBitmapDelegate = bitmapDelegate;
84
85
if (GraphicsEnvironment.isHeadless()) {
86
throw new FontFormatException("Native font in headless toolkit");
87
}
88
fontRank = Font2D.NATIVE_RANK;
89
initNames();
90
if (getNumGlyphs() == 0) {
91
throw new FontFormatException("Couldn't locate font" + platName);
92
}
93
}
94
95
private void initNames() throws FontFormatException {
96
/* Valid XLFD has exactly 14 "-" chars.
97
* First run over the string to verify have at least this many
98
* At the same time record the locations of the hyphens
99
* so we can just pick the right substring later on
100
*/
101
int[] hPos = new int[14];
102
int hyphenCnt = 1;
103
int pos = 1;
104
105
String xlfd = platName.toLowerCase(Locale.ENGLISH);
106
if (xlfd.startsWith("-")) {
107
while (pos != -1 && hyphenCnt < 14) {
108
pos = xlfd.indexOf('-', pos);
109
if (pos != -1) {
110
hPos[hyphenCnt++] = pos;
111
pos++;
112
}
113
}
114
}
115
116
if (hyphenCnt == 14 && pos != -1) {
117
118
/* Capitalise words in the Family name */
119
String tmpFamily = xlfd.substring(hPos[1]+1, hPos[2]);
120
StringBuilder sBuffer = new StringBuilder(tmpFamily);
121
char ch = Character.toUpperCase(sBuffer.charAt(0));
122
sBuffer.replace(0, 1, String.valueOf(ch));
123
for (int i=1;i<sBuffer.length()-1; i++) {
124
if (sBuffer.charAt(i) == ' ') {
125
ch = Character.toUpperCase(sBuffer.charAt(i+1));
126
sBuffer.replace(i+1, i+2, String.valueOf(ch));
127
}
128
}
129
familyName = sBuffer.toString();
130
131
String tmpWeight = xlfd.substring(hPos[2]+1, hPos[3]);
132
String tmpSlant = xlfd.substring(hPos[3]+1, hPos[4]);
133
134
String styleStr = null;
135
136
if (tmpWeight.indexOf("bold") >= 0 ||
137
tmpWeight.indexOf("demi") >= 0) {
138
style |= Font.BOLD;
139
styleStr = "Bold";
140
}
141
142
if (tmpSlant.equals("i") ||
143
tmpSlant.indexOf("italic") >= 0) {
144
style |= Font.ITALIC;
145
146
if (styleStr == null) {
147
styleStr = "Italic";
148
} else {
149
styleStr = styleStr + " Italic";
150
}
151
}
152
else if (tmpSlant.equals("o") ||
153
tmpSlant.indexOf("oblique") >= 0) {
154
style |= Font.ITALIC;
155
if (styleStr == null) {
156
styleStr = "Oblique";
157
} else {
158
styleStr = styleStr + " Oblique";
159
}
160
}
161
162
if (styleStr == null) {
163
fullName = familyName;
164
} else {
165
fullName = familyName + " " + styleStr;
166
}
167
168
encoding = xlfd.substring(hPos[12]+1);
169
if (encoding.startsWith("-")) {
170
encoding = xlfd.substring(hPos[13]+1);
171
}
172
if (encoding.indexOf("fontspecific") >= 0) {
173
if (tmpFamily.indexOf("dingbats") >= 0) {
174
encoding = "dingbats";
175
} else if (tmpFamily.indexOf("symbol") >= 0) {
176
encoding = "symbol";
177
} else {
178
encoding = "iso8859-1";
179
}
180
}
181
} else {
182
throw new FontFormatException("Bad native name " + platName);
183
// familyName = "Unknown";
184
// fullName = "Unknown";
185
// style = Font.PLAIN;
186
// encoding = "iso8859-1";
187
}
188
}
189
190
/* Wildcard all the size fields in the XLFD and retrieve a list of
191
* XLFD's that match.
192
* We only look for scaleable fonts, so we can just replace the 0's
193
* with *'s and see what we get back
194
* No matches means even the scaleable version wasn't found. This is
195
* means the X font path isn't set up for this font at all.
196
* One match means only the scaleable version we started with was found
197
* -monotype-arial-bold-i-normal--0-0-0-0-p-0-iso8859-1
198
* Two matches apparently means as well as the above, a scaleable
199
* specified for 72 dpi is found, not that there are bitmaps : eg
200
* -monotype-arial-bold-i-normal--0-0-72-72-p-0-iso8859-1
201
* So require at least 3 matches (no need to parse) to determine that
202
* there are external bitmaps.
203
*/
204
static boolean hasExternalBitmaps(String platName) {
205
/* Turn -monotype-arial-bold-i-normal--0-0-0-0-p-0-iso8859-1
206
* into -monotype-arial-bold-i-normal--*-*-*-*-p-*-iso8859-1
207
* by replacing all -0- substrings with -*-
208
*/
209
StringBuilder sb = new StringBuilder(platName);
210
int pos = sb.indexOf("-0-");
211
while (pos >=0) {
212
sb.replace(pos+1, pos+2, "*");
213
pos = sb.indexOf("-0-", pos);
214
};
215
String xlfd = sb.toString();
216
byte[] bytes = null;
217
try {
218
bytes = xlfd.getBytes("UTF-8");
219
} catch (UnsupportedEncodingException e) {
220
bytes = xlfd.getBytes();
221
}
222
return haveBitmapFonts(bytes);
223
}
224
225
public static boolean fontExists(String xlfd) {
226
byte[] bytes = null;
227
try {
228
bytes = xlfd.getBytes("UTF-8");
229
} catch (UnsupportedEncodingException e) {
230
bytes = xlfd.getBytes();
231
}
232
return fontExists(bytes);
233
}
234
235
private static native boolean haveBitmapFonts(byte[] xlfd);
236
private static native boolean fontExists(byte[] xlfd);
237
238
public CharToGlyphMapper getMapper() {
239
if (mapper == null) {
240
if (isBitmapDelegate) {
241
/* we are a delegate */
242
mapper = new NativeGlyphMapper(this);
243
} else {
244
/* we need to delegate */
245
SunFontManager fm = SunFontManager.getInstance();
246
delegateFont = fm.getDefaultPhysicalFont();
247
mapper = delegateFont.getMapper();
248
}
249
}
250
return mapper;
251
}
252
253
FontStrike createStrike(FontStrikeDesc desc) {
254
if (isBitmapDelegate) {
255
return new NativeStrike(this, desc);
256
} else {
257
if (delegateFont == null) {
258
SunFontManager fm = SunFontManager.getInstance();
259
delegateFont = fm.getDefaultPhysicalFont();
260
}
261
/* If no FileFont's are found, delegate font may be
262
* a NativeFont, so we need to avoid recursing here.
263
*/
264
if (delegateFont instanceof NativeFont) {
265
return new NativeStrike((NativeFont)delegateFont, desc);
266
}
267
FontStrike delegate = delegateFont.createStrike(desc);
268
return new DelegateStrike(this, desc, delegate);
269
}
270
}
271
272
public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
273
return null;
274
}
275
276
native StrikeMetrics getFontMetrics(long pScalerContext);
277
278
native float getGlyphAdvance(long pContext, int glyphCode);
279
280
Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext,
281
int glyphCode) {
282
return new Rectangle2D.Float(0f, 0f, 0f, 0f);
283
}
284
285
public GeneralPath getGlyphOutline(long pScalerContext,
286
int glyphCode,
287
float x,
288
float y) {
289
return null;
290
}
291
292
native long getGlyphImage(long pScalerContext, int glyphCode);
293
294
native long getGlyphImageNoDefault(long pScalerContext, int glyphCode);
295
296
void getGlyphMetrics(long pScalerContext, int glyphCode,
297
Point2D.Float metrics) {
298
throw new RuntimeException("this should be called on the strike");
299
}
300
301
public GeneralPath getGlyphVectorOutline(long pScalerContext,
302
int[] glyphs, int numGlyphs,
303
float x, float y) {
304
return null;
305
}
306
307
private native int countGlyphs(byte[] platformNameBytes, int ptSize);
308
309
public int getNumGlyphs() {
310
if (numGlyphs == -1) {
311
byte[] bytes = getPlatformNameBytes(8);
312
numGlyphs = countGlyphs(bytes, 8);
313
}
314
return numGlyphs;
315
}
316
317
PhysicalFont getDelegateFont() {
318
if (delegateFont == null) {
319
SunFontManager fm = SunFontManager.getInstance();
320
delegateFont = fm.getDefaultPhysicalFont();
321
}
322
return delegateFont;
323
}
324
325
/* Specify that the dpi is 72x72, as this corresponds to JDK's
326
* default user space. These are the 10th and 11th fields in the XLFD.
327
* ptSize in XLFD is in 10th's of a point so multiply by 10,
328
* Replace the 9th field in the XLFD (ie after the 8th hyphen)
329
* with this pt size (this corresponds to the field that's "%d" in the
330
* font configuration files). Wild card the other numeric fields.
331
* ie to request 12 pt Times New Roman italic font, use an XLFD like :
332
* -monotype-times new roman-regular-i---*-120-72-72-p-*-iso8859-1
333
*/
334
byte[] getPlatformNameBytes(int ptSize) {
335
int[] hPos = new int[14];
336
int hyphenCnt = 1;
337
int pos = 1;
338
339
while (pos != -1 && hyphenCnt < 14) {
340
pos = platName.indexOf('-', pos);
341
if (pos != -1) {
342
hPos[hyphenCnt++] = pos;
343
pos++;
344
}
345
}
346
String sizeStr = Integer.toString((int)Math.abs(ptSize)*10);
347
StringBuilder sb = new StringBuilder(platName);
348
/* work backwards so as to not invalidate the positions. */
349
sb.replace(hPos[11]+1, hPos[12], "*");
350
351
sb.replace(hPos[9]+1, hPos[10], "72");
352
353
sb.replace(hPos[8]+1, hPos[9], "72");
354
355
/* replace the 3 lines above with the next 3 lines to get the 1.4.2
356
* behaviour
357
*/
358
// sb.replace(hPos[11]+1, hPos[12], "0");
359
// sb.replace(hPos[9]+1, hPos[10], "0");
360
// sb.replace(hPos[8]+1, hPos[9], "0");
361
362
sb.replace(hPos[7]+1, hPos[8], sizeStr);
363
364
sb.replace(hPos[6]+1, hPos[7], "*");
365
366
/* replace the 1 line above with the next line to get the 1.4.2
367
* behaviour
368
*/
369
// sb.replace(hPos[6]+1, hPos[7], "0");
370
371
/* comment out this block to the the 1.4.2 behaviour */
372
if (hPos[0] == 0 && hPos[1] == 1) {
373
/* null foundry name : some linux font configuration files have
374
* symbol font entries like this and its just plain wrong.
375
* Replace with a wild card. (Although those fonts should be
376
* located via disk access rather than X11).
377
*/
378
sb.replace(hPos[0]+1, hPos[1], "*");
379
}
380
381
String xlfd = sb.toString();
382
byte[] bytes = null;
383
try {
384
bytes = xlfd.getBytes("UTF-8");
385
} catch (UnsupportedEncodingException e) {
386
bytes = xlfd.getBytes();
387
}
388
return bytes;
389
}
390
391
public String toString() {
392
return " ** Native Font: Family="+familyName+ " Name="+fullName+
393
" style="+style+" nativeName="+platName;
394
}
395
}
396
397