2013-05-16 14 views
8

Próbuję użyć OpenDyslexic jako opcji czcionki w aplikacji Swing. Jednak, co zaskakujące, OpenDyslexic wygląda znacznie lepiej niż jakakolwiek inna czcionka w tym samym rozmiarze, mimo że wygląda normalnie w innych aplikacjach. Wypróbowałem kilka innych czcionek OpenType i nie wyglądają one szczególnie na duże lub małe. Dlaczego OpenDyslexic jest tak duży w Javie i jak mogę Javy dostosować go do rozmiaru normalnie, więc nie muszę w specjalnym przypadku wielkości OpenDyslexic?Dlaczego ta czcionka jest tak duża w Javie?

Na Oracle JRE (próbowałem 1.7.0_11, 1.7.0_15 i najnowszy 1.7.0_21) na wszystkich systemach, czcionka jest zbyt duża, gdy Java ładuje plik czcionki za pomocą Font.createFont. Jednak, gdy zainstalować czcionki do systemu operacyjnego, zachowanie różni się na wszystkich 3 platformach:

  • W Linuksie zainstalowaniu czcionki ~/.fonts ma nic dobrego. Zrzut ekranu wygląda tak samo przed zainstalowaniem czcionki i po jej zainstalowaniu.
  • W systemie Windows zainstalowanie czcionki powoduje naprawę czcionki glyphs, ale odstępjest wciąż zbyt duży! Zobacz zrzut ekranu poniżej.
  • W OS X, instalacja czcionki rozwiązuje go! Wygląda jak normalny wielkości czcionki na OS X.

aktualizacji: Co ciekawe, OpenJDK (zarówno 7u21 pakiet Ubuntu Linuksa i obuildfactory build na OS X) robi nie wystawowa bug. 15-calowy OpenDyslexic "m" ma szerokość 15 pikseli na OpenJDK, tak jak powinno być, zarówno gdy czcionka jest tworzona z pliku, jak i gdy czcionka jest obsługiwana przez system operacyjny. Błąd znajduje się w najnowszej wersji Oracle JRE, ale nie w najnowszym OpenJDK.

Oto mój przykładowy program. Zauważ, że aby go wypróbować, musisz umieścić pliki OpenDyslexic w zasobach /. Alternatywnie zainstaluj OpenDyslexic w swoim systemie i usuń połączenie 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

[możesz przetestować] (http://tips4java.wordpress.com/2008/11/30/visual-font-designer/) jeśli jest prawdziwy, napisany przez Darryl Burke – mKorbel

+0

@mKorbel, czcionka wygląda tak samo w programie Visual Font Designer Demo, tak jak podczas sprawdzania zainstalowanej czcionki. Na OS X wygląda dobrze, ale na innych platformach wygląda źle. (Zauważ, że zaktualizowałem to pytanie, aby opisać instalowanie czcionki na różnych platformach.) – yonran

Odpowiedz

1

Nie każda wersja Java obsługuje OpenType (por this overview). Jeśli możesz żyć bez niektórych funkcji OpenType, najprostszym rozwiązaniem będzie konwersja pliku czcionki na TTF. Wygląda na to, że jest tam kilka free online options, które pomogą ci w tym, a jeśli to rozwiąże Twój problem, możesz nadal inwestować w profesjonalne oprogramowanie, aby uzyskać lepsze wyniki.

+0

Jednak strona, którą łączysz, twierdzi, że Java na Windows obsługuje OpenType (oba odmiany TrueType i PostScript), a Windows wyglądał najgorzej. – yonran

+0

Ponieważ nie jest to oficjalne oświadczenie, dla mnie rozwiązaniem byłoby to, że OTF może powodować problemy. Konkretna reifikacja tych problemów może również zależeć od innych czynników, takich jak wersja systemu operacyjnego. // Z drugiej strony, osobiście miałem problemy tylko z czcionkami PS, a ich konwersja była rozwiązaniem. Czy istnieją inne powody, które uniemożliwiają próbowanie tego? Na przykład nie czytałem licencji OpenDyslexic ... – Tilo

+0

Dzięki Tilo.Po konwersji czcionki z otf na ttf ma poprawny rozmiar na wszystkich platformach, zarówno po zainstalowaniu, jak i po załadowaniu z pliku czcionki. – yonran

Powiązane problemy