Source Sans Pro 的 TTF 和 OTF 版本在 Swing (Nimbus L&F) 中显示不同
Posted
技术标签:
【中文标题】Source Sans Pro 的 TTF 和 OTF 版本在 Swing (Nimbus L&F) 中显示不同【英文标题】:TTF and OTF versions of Source Sans Pro are differently displayed in Swing (Nimbus L&F) 【发布时间】:2013-08-29 22:59:56 【问题描述】:ttf:
otf:
两者是相同的字体,但字体文件类型不同
我在 Windows 7 中运行 Java 7
根据 Adobe 的 Miguel Sousa 的说法,错误不在字体中 https://github.com/adobe/source-sans-pro/issues/32#issuecomment-23319673
我只是将默认字体设置为新字体。 TTF 版本运行没有任何问题
Font font_o = Font.createFont(Font.TRUETYPE_FONT, fonts.class.getResourceAsStream("fonts/TTF/SourceSansPro-Regular.ttf"));
//Font font_o = Font.createFont(Font.TRUETYPE_FONT, fonts.class.getResourceAsStream("fonts/OTF/SourceSansPro-Regular.otf"));
Font font_n=font_o.deriveFont(Font.PLAIN, UIManager.getLookAndFeelDefaults().getFont("defaultFont").getSize());
UIManager.getLookAndFeelDefaults().put("defaultFont",font_n);
为什么lineheight会有差异?
【问题讨论】:
不,你误会了什么。确保不是,我在这里删除我的答案以避免进一步讨论 我到底误解了什么?我这里试了ttf版本:看起来不错,然后又试了otf版本(注释掉ttf版本)lokks不一样,看上面2张图看“O”上面的空格 我明白了,但我试图避免对我这边的方法进行任何调试,仅此而已:-) 在 FontForge 中两个版本 (otf, ttf) 确实是一样的,看起来一样,似乎是一个 Java Swing (Nimbus L&F) 错误 如果它也被其他 Java 用户复制,这将是一个错误,所以让我们看看社区怎么说,也许我们必须为此提交错误报告。我会不断更新这个 *** 问题,以便其他用户将来知道forums.oracle.com/thread/2573652 【参考方案1】:结论(forums.oracle.com/thread/2573652 与他的帖子一样多,没什么特别的)
不是 Java,也不是 Nimbus 错误,这个错误在 Font 中,您可以在 Metal、Win、WinClassic 和 Nimbus Laf 中看到,OTF_Font 在字形上方缺少 2 个像素
。窗户。
。金属 。
。雨云。
。经典的 。
Java6 上的 WinXp
。相对 。
此代码将帮助您找到两种字体之间的差异(并将所有差异报告给作者)
从 (java.awt.font.)TextAttribute 为具体字体返回所有可用属性
您可以从(几乎)所有 TextAttributes 中获取详细属性
有输出
java.awt.font.TextAttribute(family)
java.awt.font.TextAttribute(weight)
java.awt.font.TextAttribute(width)
java.awt.font.TextAttribute(posture)
java.awt.font.TextAttribute(size)
java.awt.font.TextAttribute(transform)
java.awt.font.TextAttribute(superscript)
java.awt.font.TextAttribute(char_replacement)
java.awt.font.TextAttribute(foreground)
java.awt.font.TextAttribute(background)
java.awt.font.TextAttribute(underline)
java.awt.font.TextAttribute(strikethrough)
java.awt.font.TextAttribute(run_direction)
java.awt.font.TextAttribute(bidi_embedding)
java.awt.font.TextAttribute(justification)
java.awt.font.TextAttribute(input method highlight)
java.awt.font.TextAttribute(input method underline)
java.awt.font.TextAttribute(swap_colors)
java.awt.font.TextAttribute(numeric_shaping)
java.awt.font.TextAttribute(kerning)
java.awt.font.TextAttribute(ligatures)
java.awt.font.TextAttribute(tracking)
来自代码 Nimbus L&F
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class SystemFontDisplayer
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame("Nimbus UIDeafaults and Font");
private JComboBox fontsBox;
private javax.swing.Timer timer = null;
private JButton testButton = new JButton("testButton");
private JTextField testTextField = new JTextField("testTextField", JLabel.CENTER);
private JLabel testLabel = new JLabel("testLabel");
private Font font1, font2;
private JMenuBar menuBar1 = new JMenuBar();
private JMenu menu1= new JMenu("Menu 1");
private JMenu menu2= new JMenu("Menu 2");
private JMenuItem menuItem1= new JMenuItem("MenuItem 1");
private JMenuItem menuItem2= new JMenuItem("MenuItem 2");
public SystemFontDisplayer()
try
font1 = Font.createFont(Font.TRUETYPE_FONT, SystemFontDisplayer.class.getResourceAsStream("/Images/SourceSansPro-Regular.ttf"));
font2 = Font.createFont(Font.TRUETYPE_FONT, SystemFontDisplayer.class.getResourceAsStream("/Images/SourceSansPro-Regular.otf"));
catch (FontFormatException ex)
Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex);
catch (IOException ex)
Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//ge.registerFont(font1);
ge.registerFont(font2);
String[] fontFamilyNames = ge.getAvailableFontFamilyNames(Locale.getDefault());
fontsBox = new JComboBox(fontFamilyNames);
fontsBox.setSelectedItem(0);
fontsBox.setRenderer(new ComboRenderer());
fontsBox.addItemListener(new ItemListener()
@Override
public void itemStateChanged(ItemEvent e)
if (e.getStateChange() == ItemEvent.SELECTED)
final String fontName = fontsBox.getSelectedItem().toString();
fontsBox.setFont(new Font(fontName, Font.PLAIN, 16));
start();
);
fontsBox.setSelectedItem(0);
fontsBox.getEditor().selectAll();
menu1.add(menuItem1);
menuBar1.add(menu1);
menu2.add(menuItem2);
menuBar1.add(menu2);
frame.setJMenuBar(menuBar1);
frame.setLayout(new GridLayout(4, 0, 5, 5));
frame.add(fontsBox);
frame.add(testButton);
frame.add(testTextField);
frame.add(testLabel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(200, 105);
frame.pack();
java.awt.EventQueue.invokeLater(new Runnable()
@Override
public void run()
fontsBox.setPopupVisible(true);
fontsBox.setPopupVisible(false);
);
frame.setVisible(true);
private void start()
timer = new javax.swing.Timer(250, updateCol());
timer.setRepeats(false);
timer.start();
public Action updateCol()
return new AbstractAction("text load action")
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e)
final Font fnt = new Font(fontsBox.getSelectedItem().toString(), Font.PLAIN, 16);
try
LookAndFeel lnf = UIManager.getLookAndFeel().getClass().newInstance();
final FontUIResource res = new FontUIResource(fnt);
UIDefaults uiDefaults = lnf.getDefaults();
uiDefaults.put("defaultFont", res);
UIManager.getLookAndFeel().uninitialize();
UIManager.setLookAndFeel(lnf);
catch (InstantiationException ex)
Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex);
catch (IllegalAccessException ex)
Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex);
catch (UnsupportedLookAndFeelException ex)
Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex);
UIDefaults defaults = UIManager.getDefaults();
final FontUIResource res = new FontUIResource(fnt);
Object[] obj = res.getAvailableAttributes();
for (Object objs : obj)
System.out.println(objs); //returns java.awt.font.TextAttribute
defaults.put("defaultFont", res);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
;
public static void main(String arg[])
try
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels())
if ("Nimbus".equals(laf.getName()))
UIManager.setLookAndFeel(laf.getClassName());
catch (Exception e)
e.printStackTrace();
java.awt.EventQueue.invokeLater(new Runnable()
@Override
public void run()
SystemFontDisplayer systemFontDisplayer = new SystemFontDisplayer();
);
private class ComboRenderer extends BasicComboBoxRenderer
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
final Object fntObj = value;
final String fontFamilyName = (String) fntObj;
setFont(new Font(fontFamilyName, Font.PLAIN, 16));
return this;
来自代码 Oldies L&Fs
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class SystemFontDisplayer extends JFrame
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame("Nimbus UIDeafaults and Font");
private JComboBox fontsBox;
private javax.swing.Timer timer = null;
private JButton testButton = new JButton("testButton");
private JTextField testTextField = new JTextField("testTextField");
private JLabel testLabel = new JLabel("testLabel");
private Font font1, font2;
private JMenuBar menuBar1 = new JMenuBar();
private JMenu menu1 = new JMenu("Menu 1");
private JMenu menu2 = new JMenu("Menu 2");
private JMenuItem menuItem1 = new JMenuItem("MenuItem 1");
private JMenuItem menuItem2 = new JMenuItem("MenuItem 2");
public SystemFontDisplayer()
try
font1 = Font.createFont(Font.TRUETYPE_FONT, SystemFontDisplayer.class.getResourceAsStream("/Images/SourceSansPro-Regular.ttf"));
font2 = Font.createFont(Font.TRUETYPE_FONT, SystemFontDisplayer.class.getResourceAsStream("/Images/SourceSansPro-Regular.otf"));
catch (FontFormatException ex)
Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex);
catch (IOException ex)
Logger.getLogger(SystemFontDisplayer.class.getName()).log(Level.SEVERE, null, ex);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//ge.registerFont(font1);
ge.registerFont(font2);
String[] fontFamilyNames = ge.getAvailableFontFamilyNames(Locale.getDefault());
fontsBox = new JComboBox(fontFamilyNames);
fontsBox.setSelectedItem(0);
fontsBox.setRenderer(new ComboRenderer());
fontsBox.addItemListener(new ItemListener()
@Override
public void itemStateChanged(ItemEvent e)
if (e.getStateChange() == ItemEvent.SELECTED)
final String fontName = fontsBox.getSelectedItem().toString();
fontsBox.setFont(new Font(fontName, Font.PLAIN, 16));
start();
);
fontsBox.setSelectedItem(0);
fontsBox.getEditor().selectAll();
menu1.add(menuItem1);
menuBar1.add(menu1);
menu2.add(menuItem2);
menuBar1.add(menu2);
frame.setJMenuBar(menuBar1);
frame.setLayout(new GridLayout(4, 0, 20, 20));
frame.add(fontsBox);
frame.add(testButton);
frame.add(testTextField);
frame.add(testLabel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(200, 105);
frame.pack();
java.awt.EventQueue.invokeLater(new Runnable()
@Override
public void run()
fontsBox.setPopupVisible(true);
fontsBox.setPopupVisible(false);
);
frame.setVisible(true);
private void start()
timer = new javax.swing.Timer(750, updateCol());
timer.setRepeats(false);
timer.start();
public Action updateCol()
return new AbstractAction("text load action")
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e)
final Font fnt = new Font(fontsBox.getSelectedItem().toString(), Font.PLAIN, 12);
final FontUIResource res = new FontUIResource(fnt);
UIManager.getLookAndFeelDefaults().put("Button.font", res);
UIManager.getLookAndFeelDefaults().put("TextField.font", res);
UIManager.getLookAndFeelDefaults().put("Label.font", res);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
;
public static void main(String arg[])
/*try
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
catch (Exception e)
e.printStackTrace();
*/
java.awt.EventQueue.invokeLater(new Runnable()
@Override
public void run()
SystemFontDisplayer systemFontDisplayer = new SystemFontDisplayer();
);
private class ComboRenderer extends BasicComboBoxRenderer
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
final Object fntObj = value;
final String fontFamilyName = (String) fntObj;
setFont(new Font(fontFamilyName, Font.PLAIN, 16));
return this;
更多详情见Visual Font Designer by @ Darryl Burke
【讨论】:
这如何帮助我比较 Adobe Source Sans Pro 的 otf 和 ttf 版本?此外,它不会将属性的值打印到控制台,而是将哪些属性存在,您是否查看了 Github 问题?1) how does this help me to compare the otf and ttf version of Adobe Source Sans Pro?
---> 每个字体都有很多属性,其中之一是插入、空边框、用于显示更高 Unicode 字形的可用空间2) Also it does not print the values of the attributes to the console but just which attributes exist
---> 再次您可以从所有属性中获取详细属性 3)@ Darryl Burke 的 Visual Font Designer 原因,不要在我的回答中重新发明*** 4) did you take a look at the Github issue?
---> OpenSource 的标准答案 ...
不,你误解了一些东西。我正在使用 Adobe 的 Source Sans Pro 字体。我正在使用这种字体的 otf 或 ttf 版本。只有 otf 字体有一些问题(行高?),但 Adobe 的 Miguel 说它们都是一样的。您可以从列表中选择一种字体版本(ttf 还是 otf?),但您不能比较它们或在 otf 和 ttf 版本之间选择直接比较它们。
你已经知道我已经提交了一个不存在的问题 - 这很奇怪 - 它应该存在,因为我有一个错误 ID ... =(这对 Oracle 和 Java 来说非常令人失望和这个问题/答案没有解决所有问题的答案。
这一切都让我们一无所获,Adobe 说这不是字体错误,Oracle 什么也没说,所以对我来说这是一个 Java 错误以上是关于Source Sans Pro 的 TTF 和 OTF 版本在 Swing (Nimbus L&F) 中显示不同的主要内容,如果未能解决你的问题,请参考以下文章
scss GoogleFonts - Source Sans Pro