2013-05-16 140 views
8

我试图在Swing应用程序中使用OpenDyslexic作为字体选项。但令人惊讶的是,OpenDyslexic看起来比同尺寸的其他任何字体都大得多,即使它在其他应用程序中看起来正常。我尝试了一些其他OpenType字体,并且它们看起来并不特别大或小。为什么OpenDyslexic在Java中如此之大,以及我如何让Java正常地调整它的大小,所以我不必特殊说明OpenDyslexic的大小?为什么这个字体在Java中如此之大?

对于所有操作系统上的Oracle JRE(我试过1.7.0_11,1.7.0_15和最新的1.7.0_21),当Java使用Font.createFont加载字体文件时,字体太大。然而,当我安装字体到操作系统中,该行为是在所有3个平台上的不同:

  • 在Linux中,安装的字体~/.fonts没有什么好处。截图在安装字体和安装之后看起来是一样的。
  • 在Windows中,安装字体修复了字体字形,但字体的间距仍然太大!见下面的截图。
  • 在OS X中,安装字体修复了它!它看起来像在OS X上一个正常大小的字体

更新:有趣的是,OpenJDK的(无论是7u21 Ubuntu的软件包在Linux和OS X的obuildfactory编译)不表现出错误。在OpenJDK上,15pt OpenDyslexic'm'的宽度为15px,因为它应该是当从文件创建字体和操作系统处理字体时。该错误位于最新的Oracle JRE中,但不在最新的OpenJDK中。

这是我的示例程序。请注意,要尝试它,您需要将OpenDyslexic文件放入资源/中。或者,将OpenDyslexic安装到您的系统中并取出registerFonts()呼叫。

SansSerif is normal sizeOpenDyslexic is huge at the same point sizeAfter installing OpenDyslexic on Windows, it looks stupidAfter installing font on OS X: perfect!

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Font; 
import java.awt.FontFormatException; 
import java.awt.GraphicsEnvironment; 
import java.io.IOException; 
import java.io.InputStream; 
import java.lang.reflect.InvocationTargetException; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.Locale; 

import javax.swing.DefaultComboBoxModel; 
import javax.swing.DefaultListCellRenderer; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.WindowConstants; 
import javax.swing.event.ListDataEvent; 
import javax.swing.event.ListDataListener; 

public class FontFrame { 
    /** 
    * Register extra fonts from resources. If you already have it installed on 
    * the computer, you can skip this. 
    */ 
    private static void registerFonts() { 
     String[] resources = { 
      "OpenDyslexic-Regular.otf", 
      "OpenDyslexic-Italic.otf", 
      "OpenDyslexic-Bold.otf", 
      "OpenDyslexic-BoldItalic.otf" 
     }; 
     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     for (String filename: resources) { 
      InputStream stream = FontFrame.class.getResourceAsStream("resources/" + filename); 
      try { 
       Font font = Font.createFont(Font.TRUETYPE_FONT, stream); 
       ge.registerFont(font); 
      } catch (FontFormatException | IOException e) { 
       throw new IllegalStateException(e); 
      } 
     } 
    } 
    private static void createUI(boolean allFonts) { 
     final JTextArea textArea = new JTextArea(
       "Font created to help dyslexic readers. " + 
       "Bottom heavy and unique character shapes help " + 
       "prevent letters and numbers from being confused."); 
     textArea.setWrapStyleWord(true); 
     textArea.setLineWrap(true); 
     final DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(); 
     if (allFonts) { 
      GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
      HashSet<Object> seenFamilies = new HashSet<>(); 
      Font[] fonts = ge.getAllFonts(); 
      for (Font font: fonts) { 
       String familyName = font.getFamily(Locale.ENGLISH); 
       if (seenFamilies.contains(familyName)) 
        continue; 
       seenFamilies.add(familyName); 
       model.addElement(familyName); 
      } 
     } else { 
      model.addElement("SansSerif"); 
      model.addElement("OpenDyslexic"); 
     } 

     final int fontSize = 15; 
     textArea.setFont(new Font("SansSerif", Font.PLAIN, fontSize)); 
     model.addListDataListener(new ListDataListener() { 
      @Override public void intervalRemoved(ListDataEvent e) {} 
      @Override public void intervalAdded(ListDataEvent e) {} 
      @Override public void contentsChanged(ListDataEvent e) { 
       if (e.getIndex0() == -1 && e.getIndex1() == -1) { 
        SwingUtilities.invokeLater(new Runnable() { @Override public void run() { 
         String selectedFamily = (String) model.getSelectedItem(); 
         Font font = new Font(selectedFamily, Font.PLAIN, fontSize); 
         textArea.setFont(font); 
        }}); 
       } 
      } 
     }); 
     JComboBox<String> familyChooser = new JComboBox<>(model); 
     familyChooser.setMaximumRowCount(50); 
     familyChooser.setRenderer(new DefaultListCellRenderer() { 
      private static final long serialVersionUID = 1L; 
      public Component getListCellRendererComponent(JList<?> list, 
        Object value, int index, boolean isSelected, 
        boolean cellHasFocus) { 
       Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
       String familyName = (String) value; 
       Font font = new Font(familyName, Font.PLAIN, fontSize); 
       comp.setFont(font); 
       return comp; 
      } 
     }); 

     JPanel jpanel = new JPanel(); 
     jpanel.setLayout(new BorderLayout()); 
     jpanel.add(familyChooser, BorderLayout.NORTH); 
     jpanel.add(textArea, BorderLayout.CENTER); 
     JFrame jframe = new JFrame(); 
     jframe.getContentPane().add(jpanel); 
     jframe.setSize(300, 300); 
     jframe.invalidate(); 
     jframe.setVisible(true); 
     jframe.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
    } 
    public static void main(String[] args) throws InvocationTargetException, InterruptedException { 
     registerFonts(); 
     final boolean allFonts = Arrays.asList(args).contains("--all"); 
     SwingUtilities.invokeAndWait(new Runnable() { 
      @Override public void run() { 
       createUI(allFonts); 
      } 
     }); 
    } 
} 
+0

[你可以测试](http://tips4java.wordpress.com/2008/11/30/visual-font-designer/)如果属实,由Darryl Burke – mKorbel

+0

@mKorbel制作,字体看起来一样在可视化字体设计器演示中,就像在查看已安装的字体时一样。在OS X上看起来不错,但在其他平台上看起来很糟糕。 (请注意,我已经更新了这个问题来描述在不同平台上安装字体。) – yonran

回答

1

并不是每一个Java版本支持的OpenType(参见this overview)。如果你可以没有一些OpenType功能,最简单的解决方案就是将字体文件转换为TTF。似乎有几个free online options来帮助你,如果这解决了你的问题,你仍然可以投资专业软件来获得更好的结果。

+0

但是,您链接的网页声称Windows上的Java支持OpenType(TrueType和PostScript变体),而Windows实际上看起来最糟糕。 – yonran

+0

由于这不是官方声明,因此OTF可能会导致问题。这些问题的具体化可能还取决于其他因素,如操作系统版本。 //另一方面,我个人只有PS字体的问题,并且转换它们就是解决方案。是否有其他原因阻止你尝试?例如,我没有阅读OpenDyslexic许可证...... – Tilo

+0

感谢Tilo。将字体从otf转换为ttf后,它在所有平台上都具有正确的大小,无论是在安装时还是从字体文件加载时。 – yonran

相关问题