OpenJDKとOracleJDKとのフォントの違いに気づいています。私はこれをフォントに絞り込んだ。それらはOpenJDKによって今まで以上にわずかに幅広くレンダリングされています...上のスクリーンショットの注意深い目視検査は、文字の幅が同じであることを示していますが、唯一の違いは間隔です。また、すべての文字A-Za-z0-9のフォントメトリックのプログラムによるチェックでこれを確認しました。OpenJDKとOracleJDKのフォントが若干広い
例えば文字列 "ダイアログ - 無地" 12ptのでは、OpenJDKの中に広い
- 125pxです - 私のビルド8u131-B11 OpenJDKの中に広い
- 125pxの - RedHatのディスクから株式RPM -
- 120ピクセル幅の1.8u45-B13 OracleJDKに - OracleのWebサイト
から8u131-B11リリース私は、この上の情報のために広く検索しJava_Runtime_Environment_fontsから-Dawt.useSystemAAFontSettings
、-Dswing.useSystemFontSettings
、-Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel
を含む様々なオプションを見つけました。私はこれらのすべてを変更しようとしましたが、結果は変わりません。
さらなる調査では、sun.font.FontScaler
が見つかりました。これは、異なる基礎となるフォントスケーラを使用しています。これは-Dsun.java2d.font.scaler=t2k
のシステムプロパティをチェックするsun.font.FontUtilities
で部分的に設定可能ですが、これを設定しても差はありません。
私の質問:FreetypeFontScaler
は、T2KFontScalerと同様の方法で動作するように設定することができますか?
if (FontUtilities.isOpenJDK) {
scalerClass = Class.forName("sun.font.FreetypeFontScaler");
} else {
scalerClass = Class.forName("sun.font.T2KFontScaler");
}
この
は異なる結果を返すsun.font.FontStrike.getGlyphMetrics(int)
にかかわらず、これをトレースした私は
public class FontTester {
public static void main(String[] args) throws Exception {
System.out.println(String.format("java.home=%s", System.getProperty("java.home")));
String family = Font.DIALOG;
int style = Font.PLAIN;
describeFont(new Font(family, style, 12));
JFrame frame = new JFrame();
frame.setSize(800, 600);
frame.add(new DemoPanel());
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
private static class DemoPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
String family = Font.DIALOG;
int style = Font.PLAIN;
Font font = new Font(family, style, 20);
g.setFont(font);
String str = family + " - " + name(font) + " ";
Rectangle2D bounds = g.getFontMetrics().getStringBounds(str, g);
str += String.format("%f x %f", bounds.getWidth(), bounds.getHeight());
g.drawString(str, 10, 50);
}
private String name(Font font) {
List<String> attrs = new ArrayList<>();
if (font.isBold()) {
attrs.add("bold");
}
if (font.isItalic()) {
attrs.add("italic");
}
if (font.isPlain()) {
attrs.add("plain");
}
return String.join(",", attrs);
}
}
private static void describeFont(Font font) throws Exception {
Method method = Font.class.getDeclaredMethod("getFont2D");
method.setAccessible(true);
Font2D font2d = (Font2D) method.invoke(font);
System.out.print(String.format("%s: ", font));
describeFont2D(font2d);
}
private static void describeFont2D(Font2D font) {
if (font instanceof CompositeFont) {
CompositeFont cf = (CompositeFont) font;
for (int i = 0; i < cf.getNumSlots(); i++) {
PhysicalFont pf = cf.getSlotFont(i);
describeFont2D(pf);
break;
}
} else {
System.out.print(String.format("-> %s \n", font));
}
}
}
さらにより調査を使用してきたテストプログラムです。グリフID 39(「D」)のための事前のX値(T2KFontScalerを介して)OracleのJDKを使用して14.0pxとして返されるが15.0px私は使用される「修正」である把握する(FreetypeFontScaler経由)OpenJDKの
を使用してfontbox TurbファイルLiberationSans-Regular.ttf内のHMTXテーブルからGlyph-ID 39の進化X値を抽出するためのJavaパーサー。値は1479のフォントデザイン単位で、20ptのフォントサイズで14.44pxに対応します。 「i」の次の文字には違いありません
- グリフID 76.これはfontboxによると4.44である、と私はさらにこれを絞り込むまし
T2KScalerとFreetypeScaler
の両方で4として返さ標準の「非分数」メトリックが使用されている場合に使用される丸め/計算。フラクショナルメトリックが有効な場合、OracleとOpen JDKの両方が同じように動作しますが、幅は依然としてOracleの非小数点の場合よりもはるかに小さくなります。g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
私は、フォント・レンダリング・ライブラリがOracle JavaとほとんどのOpenJDKビルド(http://mail.openjdk.java.net/pipermail/discuss/2017-November/004621)で異なるため、実現しようとしていることは不可能だと思います。 html – alexkasko
ほとんどの場合そうではありませんが、DIALOGは論理フォントであるため、最初に特定の非JDKフォントをチェックするか、フォントが本当に同じかどうかを調べるほうがよいでしょう。 –