Skip to content

Commit e236cad

Browse files
committed
8357672: Extreme font sizes can cause font substitution
Backport-of: a4eb15195ceeadf311fe81e622a54f4733b90df2
1 parent bbbe85c commit e236cad

File tree

3 files changed

+102
-12
lines changed

3 files changed

+102
-12
lines changed

src/java.desktop/share/classes/sun/font/FileFontStrike.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ public class FileFontStrike extends PhysicalStrike {
202202
this.disposer = new FontStrikeDisposer(fileFont, desc);
203203
initGlyphCache();
204204
pScalerContext = NullFontScaler.getNullScalerContext();
205-
SunFontManager.getInstance().deRegisterBadFont(fileFont);
206205
return;
207206
}
208207
/* First, see if native code should be used to create the glyph.

src/java.desktop/share/native/libfontmanager/freetypeScaler.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,6 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
500500

501501
if (context == NULL) {
502502
free(context);
503-
invalidateJavaScaler(env, scaler, NULL);
504503
return (jlong) 0;
505504
}
506505
(*env)->GetDoubleArrayRegion(env, matrix, 0, 4, dmat);

test/jdk/java/awt/FontMetrics/ExtremeFontSizeTest.java

Lines changed: 102 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,16 +24,19 @@
2424
import java.awt.Font;
2525
import java.awt.FontMetrics;
2626
import java.awt.Graphics2D;
27+
import java.awt.GraphicsEnvironment;
2728
import java.awt.Rectangle;
2829
import java.awt.font.FontRenderContext;
2930
import java.awt.font.GlyphVector;
3031
import java.awt.geom.AffineTransform;
3132
import java.awt.geom.Rectangle2D;
3233
import java.awt.image.BufferedImage;
34+
import java.util.HashMap;
35+
import java.util.Map;
3336

3437
/*
3538
* @test
36-
* @bug 8328896
39+
* @bug 8328896 8357672
3740
* @summary test that using very large font sizes used don't break later uses
3841
*/
3942

@@ -49,34 +52,106 @@ public class ExtremeFontSizeTest {
4952
static double[] scales = { 1.0, 900.0};
5053
static boolean[] fms = { false, true };
5154

55+
static class Key {
56+
int fontSize;
57+
double scale;
58+
boolean fm;
59+
String str;
60+
61+
62+
Key(int fs, double sc, boolean f, String s) {
63+
fontSize = fs;
64+
scale = sc;
65+
fm = f;
66+
str = s;
67+
}
68+
69+
public boolean equals(Object o) {
70+
return
71+
(o instanceof Key k) &&
72+
this.fontSize == k.fontSize &&
73+
this.scale == k.scale &&
74+
this.fm == k.fm &&
75+
this.str.equals(k.str);
76+
}
77+
78+
public int hashCode() {
79+
return fontSize + (int)scale + (fm ? 1 : 0) + str.hashCode();
80+
}
81+
}
82+
83+
static class Value {
84+
int height;
85+
double strBounds;
86+
Rectangle pixelBounds;
87+
Rectangle2D visualBounds;
88+
89+
Value(int h, double sb, Rectangle pb, Rectangle2D vb) {
90+
height = h;
91+
strBounds = sb;
92+
pixelBounds = pb;
93+
visualBounds = vb;
94+
}
95+
96+
public boolean equals(Object o) {
97+
return
98+
(o instanceof Value v) &&
99+
this.height == v.height &&
100+
this.strBounds == v.strBounds &&
101+
this.pixelBounds.equals(v.pixelBounds) &&
102+
this.visualBounds.equals(v.visualBounds);
103+
}
104+
105+
public int hashCode() {
106+
return height + (int)strBounds + pixelBounds.hashCode() + visualBounds.hashCode();
107+
}
108+
}
109+
110+
static Map<Key, Value> metricsMap = new HashMap<Key, Value>();
111+
52112
public static void main(String[] args) {
113+
Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
114+
for (Font f : fonts) {
115+
font = f.deriveFont(Font.PLAIN, 12);
116+
System.out.println("Test font : " + font);
117+
if (font.canDisplayUpTo(testString) != -1) {
118+
System.out.println("Skipping since cannot display test string");
119+
continue;
120+
}
121+
metricsMap = new HashMap<Key, Value>();
122+
testFont();
123+
}
124+
}
125+
126+
static void testFont() {
53127

54128
/* run tests validating bounds etc are non-zero
55129
* then run with extreme scales for which zero is allowed - but not required
56130
* then run the first tests again to be sure they are still reasonable.
57131
*/
58-
runTests();
59-
test(5_000_000, 10_000, false, testString, false);
60-
test(5_000_000, 10_000, true, testString, false);
61-
test(0, 0.00000001, false, testString, false);
62-
runTests();
132+
runTests(true, false);
133+
test(5_000_000, 10_000, false, testString, false, false, false);
134+
test(5_000_000, 10_000, true, testString, false, false, false);
135+
test(0, 0.00000001, false, testString, false, false, false);
136+
runTests(false, true);
63137

64138
if (failed) {
65139
throw new RuntimeException("Test failed. Check stdout log.");
66140
}
67141
}
68142

69-
static void runTests() {
143+
static void runTests(boolean add, boolean check) {
70144
for (int fontSize : fontSizes) {
71145
for (double scale : scales) {
72146
for (boolean fm : fms) {
73-
test(fontSize, scale, fm, testString, true);
147+
test(fontSize, scale, fm, testString, true, add, check);
74148
}
75149
}
76150
}
77151
}
78152

79-
static void test(int size, double scale, boolean fm, String str, boolean checkAll) {
153+
static void test(int size, double scale, boolean fm, String str,
154+
boolean checkAll, boolean add, boolean check) {
80155

81156
AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
82157
FontRenderContext frc = new FontRenderContext(at, false, fm);
@@ -114,5 +189,22 @@ static void test(int size, double scale, boolean fm, String str, boolean checkAl
114189
System.out.println(" *** RESULTS NOT AS EXPECTED *** ");
115190
}
116191
System.out.println();
192+
193+
Key k = null;
194+
Value v = null;
195+
if (add || check) {
196+
k = new Key(size, scale, fm, str);
197+
v = new Value(height, width, pixelBounds, visualBounds);
198+
}
199+
if (add) {
200+
metricsMap.put(k, v);
201+
}
202+
if (check) {
203+
Value vmap = metricsMap.get(k);
204+
if (!v.equals(vmap)) {
205+
failed = true;
206+
System.out.println("Values differ");
207+
}
208+
}
117209
}
118210
}

0 commit comments

Comments
 (0)