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/FontFamily.java
38829 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.io.File;
29
import java.awt.Font;
30
import java.io.IOException;
31
import java.util.Collection;
32
import java.util.HashMap;
33
import java.util.concurrent.ConcurrentHashMap;
34
import java.util.Locale;
35
36
public class FontFamily {
37
38
private static ConcurrentHashMap<String, FontFamily>
39
familyNameMap = new ConcurrentHashMap<String, FontFamily>();
40
private static HashMap<String, FontFamily> allLocaleNames;
41
42
protected String familyName;
43
protected Font2D plain;
44
protected Font2D bold;
45
protected Font2D italic;
46
protected Font2D bolditalic;
47
protected boolean logicalFont = false;
48
protected int familyRank;
49
50
public static FontFamily getFamily(String name) {
51
return familyNameMap.get(name.toLowerCase(Locale.ENGLISH));
52
}
53
54
public static String[] getAllFamilyNames() {
55
return null;
56
}
57
58
/* Only for use by FontManager.deRegisterBadFont(..).
59
* If this was the only font in the family, the family is removed
60
* from the map
61
*/
62
static void remove(Font2D font2D) {
63
64
String name = font2D.getFamilyName(Locale.ENGLISH);
65
FontFamily family = getFamily(name);
66
if (family == null) {
67
return;
68
}
69
if (family.plain == font2D) {
70
family.plain = null;
71
}
72
if (family.bold == font2D) {
73
family.bold = null;
74
}
75
if (family.italic == font2D) {
76
family.italic = null;
77
}
78
if (family.bolditalic == font2D) {
79
family.bolditalic = null;
80
}
81
if (family.plain == null && family.bold == null &&
82
family.plain == null && family.bold == null) {
83
familyNameMap.remove(name);
84
}
85
}
86
87
public FontFamily(String name, boolean isLogFont, int rank) {
88
logicalFont = isLogFont;
89
familyName = name;
90
familyRank = rank;
91
familyNameMap.put(name.toLowerCase(Locale.ENGLISH), this);
92
}
93
94
/* Create a family for created fonts which aren't listed in the
95
* main map.
96
*/
97
FontFamily(String name) {
98
logicalFont = false;
99
familyName = name;
100
familyRank = Font2D.DEFAULT_RANK;
101
}
102
103
public String getFamilyName() {
104
return familyName;
105
}
106
107
public int getRank() {
108
return familyRank;
109
}
110
111
private boolean isFromSameSource(Font2D font) {
112
if (!(font instanceof FileFont)) {
113
return false;
114
}
115
116
FileFont existingFont = null;
117
if (plain instanceof FileFont) {
118
existingFont = (FileFont)plain;
119
} else if (bold instanceof FileFont) {
120
existingFont = (FileFont)bold;
121
} else if (italic instanceof FileFont) {
122
existingFont = (FileFont)italic;
123
} else if (bolditalic instanceof FileFont) {
124
existingFont = (FileFont)bolditalic;
125
}
126
// A family isn't created until there's a font.
127
// So if we didn't find a file font it means this
128
// isn't a file-based family.
129
if (existingFont == null) {
130
return false;
131
}
132
File existDir = (new File(existingFont.platName)).getParentFile();
133
134
FileFont newFont = (FileFont)font;
135
File newDir = (new File(newFont.platName)).getParentFile();
136
if (existDir != null) {
137
try {
138
existDir = existDir.getCanonicalFile();
139
} catch (IOException ignored) {}
140
}
141
if (newDir != null) {
142
try {
143
newDir = newDir.getCanonicalFile();
144
} catch (IOException ignored) {}
145
}
146
return java.util.Objects.equals(newDir, existDir);
147
}
148
149
/*
150
* We want a family to be of the same width and prefer medium/normal width.
151
* Once we find a particular width we accept more of the same width
152
* until we find one closer to normal when we 'evict' all existing fonts.
153
* So once we see a 'normal' width font we evict all members that are not
154
* normal width and then accept only new ones that are normal width.
155
*
156
* Once a font passes the width test we subject it to the weight test.
157
* For Plain we target the weight the closest that is <= NORMAL (400)
158
* For Bold we target the weight that is closest to BOLD (700).
159
*
160
* In the future, rather than discarding these fonts, we should
161
* extend the family to include these so lookups on these properties
162
* can locate them, as presently they will only be located by full name
163
* based lookup.
164
*/
165
166
private int familyWidth = 0;
167
private boolean preferredWidth(Font2D font) {
168
169
int newWidth = font.getWidth();
170
171
if (familyWidth == 0) {
172
familyWidth = newWidth;
173
return true;
174
}
175
176
if (newWidth == familyWidth) {
177
return true;
178
}
179
180
if (Math.abs(Font2D.FWIDTH_NORMAL - newWidth) <
181
Math.abs(Font2D.FWIDTH_NORMAL - familyWidth))
182
{
183
if (FontUtilities.debugFonts()) {
184
FontUtilities.getLogger().info(
185
"Found more preferred width. New width = " + newWidth +
186
" Old width = " + familyWidth + " in font " + font +
187
" nulling out fonts plain: " + plain + " bold: " + bold +
188
" italic: " + italic + " bolditalic: " + bolditalic);
189
}
190
familyWidth = newWidth;
191
plain = bold = italic = bolditalic = null;
192
return true;
193
} else if (FontUtilities.debugFonts()) {
194
FontUtilities.getLogger().info(
195
"Family rejecting font " + font +
196
" of less preferred width " + newWidth);
197
}
198
return false;
199
}
200
201
private boolean closerWeight(Font2D currFont, Font2D font, int style) {
202
if (familyWidth != font.getWidth()) {
203
return false;
204
}
205
206
if (currFont == null) {
207
return true;
208
}
209
210
if (FontUtilities.debugFonts()) {
211
FontUtilities.getLogger().info(
212
"New weight for style " + style + ". Curr.font=" + currFont +
213
" New font="+font+" Curr.weight="+ + currFont.getWeight()+
214
" New weight="+font.getWeight());
215
}
216
217
int newWeight = font.getWeight();
218
switch (style) {
219
case Font.PLAIN:
220
case Font.ITALIC:
221
return (newWeight <= Font2D.FWEIGHT_NORMAL &&
222
newWeight > currFont.getWeight());
223
224
case Font.BOLD:
225
case Font.BOLD|Font.ITALIC:
226
return (Math.abs(newWeight - Font2D.FWEIGHT_BOLD) <
227
Math.abs(currFont.getWeight() - Font2D.FWEIGHT_BOLD));
228
229
default:
230
return false;
231
}
232
}
233
234
public void setFont(Font2D font, int style) {
235
236
if (FontUtilities.isLogging()) {
237
String msg;
238
if (font instanceof CompositeFont) {
239
msg = "Request to add " + font.getFamilyName(null) +
240
" with style " + style + " to family " + familyName;
241
} else {
242
msg = "Request to add " + font +
243
" with style " + style + " to family " + this;
244
}
245
FontUtilities.getLogger().info(msg);
246
}
247
/* Allow a lower-rank font only if its a file font
248
* from the exact same source as any previous font.
249
*/
250
if ((font.getRank() > familyRank) && !isFromSameSource(font)) {
251
if (FontUtilities.isLogging()) {
252
FontUtilities.getLogger()
253
.warning("Rejecting adding " + font +
254
" of lower rank " + font.getRank() +
255
" to family " + this +
256
" of rank " + familyRank);
257
}
258
return;
259
}
260
261
switch (style) {
262
263
case Font.PLAIN:
264
if (preferredWidth(font) && closerWeight(plain, font, style)) {
265
plain = font;
266
}
267
break;
268
269
case Font.BOLD:
270
if (preferredWidth(font) && closerWeight(bold, font, style)) {
271
bold = font;
272
}
273
break;
274
275
case Font.ITALIC:
276
if (preferredWidth(font) && closerWeight(italic, font, style)) {
277
italic = font;
278
}
279
break;
280
281
case Font.BOLD|Font.ITALIC:
282
if (preferredWidth(font) && closerWeight(bolditalic, font, style)) {
283
bolditalic = font;
284
}
285
break;
286
287
default:
288
break;
289
}
290
}
291
292
public Font2D getFontWithExactStyleMatch(int style) {
293
294
switch (style) {
295
296
case Font.PLAIN:
297
return plain;
298
299
case Font.BOLD:
300
return bold;
301
302
case Font.ITALIC:
303
return italic;
304
305
case Font.BOLD|Font.ITALIC:
306
return bolditalic;
307
308
default:
309
return null;
310
}
311
}
312
313
/* REMIND: if the callers of this method are operating in an
314
* environment in which not all fonts are registered, the returned
315
* font may be a algorithmically styled one, where in fact if loadfonts
316
* were executed, a styled font may be located. Our present "solution"
317
* to this is to register all fonts in a directory and assume that this
318
* registered all the styles of a font, since they would all be in the
319
* same location.
320
*/
321
public Font2D getFont(int style) {
322
323
switch (style) {
324
325
case Font.PLAIN:
326
return plain;
327
328
case Font.BOLD:
329
if (bold != null) {
330
return bold;
331
} else if (plain != null && plain.canDoStyle(style)) {
332
return plain;
333
} else {
334
return null;
335
}
336
337
case Font.ITALIC:
338
if (italic != null) {
339
return italic;
340
} else if (plain != null && plain.canDoStyle(style)) {
341
return plain;
342
} else {
343
return null;
344
}
345
346
case Font.BOLD|Font.ITALIC:
347
if (bolditalic != null) {
348
return bolditalic;
349
} else if (bold != null && bold.canDoStyle(style)) {
350
return bold;
351
} else if (italic != null && italic.canDoStyle(style)) {
352
return italic;
353
} else if (plain != null && plain.canDoStyle(style)) {
354
return plain;
355
} else {
356
return null;
357
}
358
default:
359
return null;
360
}
361
}
362
363
/* Only to be called if getFont(style) returns null
364
* This method will only return null if the family is completely empty!
365
* Note that it assumes the font of the style you need isn't in the
366
* family. The logic here is that if we must substitute something
367
* it might as well be from the same family.
368
*/
369
Font2D getClosestStyle(int style) {
370
371
switch (style) {
372
/* if you ask for a plain font try to return a non-italic one,
373
* then a italic one, finally a bold italic one */
374
case Font.PLAIN:
375
if (bold != null) {
376
return bold;
377
} else if (italic != null) {
378
return italic;
379
} else {
380
return bolditalic;
381
}
382
383
/* if you ask for a bold font try to return a non-italic one,
384
* then a bold italic one, finally an italic one */
385
case Font.BOLD:
386
if (plain != null) {
387
return plain;
388
} else if (bolditalic != null) {
389
return bolditalic;
390
} else {
391
return italic;
392
}
393
394
/* if you ask for a italic font try to return a bold italic one,
395
* then a plain one, finally an bold one */
396
case Font.ITALIC:
397
if (bolditalic != null) {
398
return bolditalic;
399
} else if (plain != null) {
400
return plain;
401
} else {
402
return bold;
403
}
404
405
case Font.BOLD|Font.ITALIC:
406
if (italic != null) {
407
return italic;
408
} else if (bold != null) {
409
return bold;
410
} else {
411
return plain;
412
}
413
}
414
return null;
415
}
416
417
/* Font may have localized names. Store these in a separate map, so
418
* that only clients who use these names need be affected.
419
*/
420
static synchronized void addLocaleNames(FontFamily family, String[] names){
421
if (allLocaleNames == null) {
422
allLocaleNames = new HashMap<String, FontFamily>();
423
}
424
for (int i=0; i<names.length; i++) {
425
allLocaleNames.put(names[i].toLowerCase(), family);
426
}
427
}
428
429
public static synchronized FontFamily getLocaleFamily(String name) {
430
if (allLocaleNames == null) {
431
return null;
432
}
433
return allLocaleNames.get(name.toLowerCase());
434
}
435
436
public static FontFamily[] getAllFontFamilies() {
437
Collection<FontFamily> families = familyNameMap.values();
438
return families.toArray(new FontFamily[0]);
439
}
440
441
public String toString() {
442
return
443
"Font family: " + familyName +
444
" plain="+plain+
445
" bold=" + bold +
446
" italic=" + italic +
447
" bolditalic=" + bolditalic;
448
449
}
450
451
}
452
453