Версии TTF и OTF Source Sans Pro по-разному отображаются в Swing (Nimbus L&F)

ttf: ttf

otf: otf

оба - один и тот же шрифт, но разные типы файлов шрифтов

Я использую Java 7 в Windows 7

По словам Мигеля Соуза из Adobe, ошибка отсутствует в шрифтах 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);

Почему разница в высоте линии?


person Daniel Ruf    schedule 27.08.2013    source источник
comment
нет, вы что-то неправильно поняли. будьте уверены, что нет, я удаляю свой ответ здесь, чтобы избежать дальнейшего обсуждения   -  person mKorbel    schedule 27.08.2013
comment
и что именно я неправильно понял? Я попробовал версию ttf здесь: выглядит отлично, затем попробовал версию otf (комментируя версию ttf), локки не совпадают, см. 2 изображения выше и пространство над O   -  person Daniel Ruf    schedule 27.08.2013
comment
Я это вижу, но стараюсь избегать какой-либо отладки методов со своей стороны, ничего другого :-)   -  person mKorbel    schedule 27.08.2013
comment
В FontForge обе версии (otf, ttf) действительно одинаковы и выглядят одинаково, похоже, это ошибка Java Swing (Nimbus L&F)   -  person Daniel Ruf    schedule 27.08.2013
comment
если он также воспроизводится другими пользователями Java, это будет ошибкой, поэтому давайте посмотрим, что говорит сообщество, и, возможно, нам придется отправить отчет об ошибке для этого. Я буду обновлять этот вопрос о stackoverflow, чтобы другие пользователи знали в будущем forum.oracle.com/thread/2573652   -  person Daniel Ruf    schedule 27.08.2013
comment
Я отлажен, что все доступно из TextAttribute, это ошибка (слишком лениво создавать скриншоты раньше)   -  person mKorbel    schedule 27.08.2013
comment
Я не думаю, что Java использует то же средство визуализации шрифтов для TTF, что и шрифты OTF. Я не могу найти никаких веских доказательств этого, но посмотрите, например, второй ответ на этот вопрос. Похоже, что поиск в Google поддерживает идею о том, что не все функции шрифтов OTF поддерживаются Java. Другими словами, рендеринг шрифтов OTF может быть не таким хорошим.   -  person bobby_light    schedule 27.08.2013
comment
@bobby_light mindprod.com/jgloss/opentype.html для Linux и других операционных систем, которые вам необходимо используйте otf, в настоящее время это лучший вариант для поддержки большинства платформ   -  person Daniel Ruf    schedule 27.08.2013


Ответы (1)


вывод (forum.oracle.com/thread/2573652 similair, сколько его постов нет, ничего особенного)


  • неправда, что ошибка Java или Nimbus, эта ошибка в шрифте, вы можете видеть, что в Metal, Win, WinClassic и Nimbus Laf в OTF_Font отсутствуют 2 пикселя над глифом

введите описание изображения здесь. Windows. введите описание изображения здесь

введите описание изображения здесь. Металл. введите описание изображения здесь

введите описание изображения здесь. Нимбус. введите описание изображения здесь

введите описание изображения здесь. Классический. введите описание изображения здесь


WinXp на Java6

введите описание изображения здесь. против . введите описание изображения здесь


  • этот код поможет вам найти различия между двумя шрифтами (и сообщить обо всех различиях автору)

  • возвращает все доступные атрибуты из (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&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 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;
        }
    }
}

person mKorbel    schedule 27.08.2013
comment
Как это помогает мне сравнивать версии Adobe Source Sans Pro в форматах otf и ttf? Кроме того, он не выводит значения атрибутов на консоль, а только какие атрибуты существуют, вы смотрели на проблему Github? - person Daniel Ruf; 27.08.2013
comment
1) how does this help me to compare the otf and ttf version of Adobe Source Sans Pro? --- ›у каждого шрифта есть много атрибутов, один из них - вставки, пустые границы, доступное пространство для отображения более высокого из символов Юникода 2) Also it does not print the values of the attributes to the console but just which attributes exist ---› снова вы можете получить подробные свойства из всех атрибутов 3) причина для визуального шрифта Дизайнер @ Darryl Burke, и не изобретайте велосипед в моем ответе здесь 4) did you take a look at the Github issue? --- ›стандартный ответ для OpenSource ... - person mKorbel; 27.08.2013
comment
нет, вы что-то неправильно поняли. Я использую шрифт Source Sans Pro от Adobe. И я использую версию этого шрифта otf или ttf. Только шрифт otf имеет некоторые проблемы (высота строки?), Но Мигель от Adobe говорит, что они оба одинаковы. Вы можете просто выбрать одну версию шрифта из списка (ttf или otf?), Но вы не можете сравнивать их или выбирать между версиями otf и ttf для прямого сравнения. - person Daniel Ruf; 27.08.2013
comment
что ты нашел? В FontForge 2 файла шрифтов и метрики одинаковы, так что нет 2px missinbg. Вы думали об ошибке Swing? Какой текстовый атрибут отличается при сравнении обеих версий одного и того же шрифта? - person Daniel Ruf; 27.08.2013
comment
не знаю, никогда раньше не возникало, если это функция или ошибка, но лучше будет протестировать с другим шрифтом Otf, держу пари, что с тем же выводом в WinXP и на Java6 придется подождать несколько минут - person mKorbel; 27.08.2013
comment
WinXp / Java с той же проблемой, хе-хе-хе кто-то говорит об ошибке в Java7_025, - person mKorbel; 27.08.2013
comment
возможно, есть проблема только с Otf Fonts, нужно протестировать с другим Otf Font, но из-за моей бесконечной лени и интереса к - person mKorbel; 27.08.2013
comment
вы можете использовать три, тестировать с отдельными методами из SwingUtilities http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html, каждый возвращает -2 пикселя для FONT_SIZE.16 - person mKorbel; 27.08.2013
comment
позвольте нам продолжить обсуждение в чате - person Daniel Ruf; 27.08.2013
comment
@Daniel Ruf, см. Ответ (код внутри основного текста) Эндрю Томпсона - person mKorbel; 02.12.2013
comment
Понятия не имею, только вид с вертолета, похоже, что координаты исправлены в представлении, возможно, программно добавлен один / два пикселя, все же / но я бы добавил еще 1-2 (сверху) - person mKorbel; 02.12.2013
comment
код выложен в теле? ты про гиперссылку? Кажется, проблема решена, но почему? шрифт ttf становится немного размытым, но шрифт otf исправлен и выглядит нормально. что вы имеете в виду под видом с вертолета? это выглядит нормально / прямо здесь, не нужно добавлять дополнительные пиксели вверху - person Daniel Ruf; 02.12.2013
comment
вы должны уведомить автора кода о том, что, возможно, он сможет исправить проблему с этим шрифтом в своем коде, его тест будет быстрее, поскольку наши комментарии здесь - person mKorbel; 02.12.2013
comment
Можете ли вы взглянуть на это и ответить на комментарии Мигеля Соузы? github.com/adobe/source-sans-pro/issues/ - person Daniel Ruf; 05.12.2013
comment
1. это будет принято как официальная ошибка в случае, если только один из JComponents вызван другой компоновкой, ошибка может быть в том случае, если JTextField (затем JComboBox тоже), например, есть, но в Java7 (все еще не официальный) с (java .swing.) Просмотр для JTextComponents, есть разница между документами API и исходным двоичным кодом, - person mKorbel; 05.12.2013
comment
2. а) шрифт можно зарегистрировать в собственной ОС, б) шрифт можно зарегистрировать только в JVM, необходимо проверить, есть ли какие-то различия, - person mKorbel; 05.12.2013
comment
3. Нет никакой разницы между Java6 и Java7, как показано в моем ответе здесь, и для различных стандартных LookAndFeels в различных версиях WinOS, есть важный факт, что ядро ​​визуализации сильно отличается для WinXP и для Win7 / 8, тогда мои ответы это не ошибка Java - person mKorbel; 05.12.2013
comment
4. большая часть ошибок Java доступна только из SystemLookAndFeels (WindowsLook ...) или WindowsClassicLook ..., результат такой же, как и для Nimbus (только один другой алгоритм рендеринга в Swing API) - person mKorbel; 05.12.2013
comment
5. Мой вопрос (не воспринимайте его как «пламенную войну») заключается в том, почему одна часть шрифта отображается правильно (после преобразования шрифта, исправлена), а вторая - нет, есть возможность вычислить требуемый прямоугольник из SwingUtilities. (LayoutCompoundLabel, ei ), но по умолчанию нет прямого способа получить эту высоту (все о том, как computeStringWidth), это значение получено из Font и не доступно напрямую из deriveFont for Graphics, - person mKorbel; 05.12.2013
comment
6. Если есть какой-либо другой вывод, я могу злоупотребить своей репутацией, чтобы задать здесь вопрос о том, как получить, установить и управлять требуемой высотой для шрифтов из графики, потому что для JComponents в BasicXxxUI все о paint / paintText, но я ' Я думаю, что макет этого шрифта в Графиках будет такой же, как и для JComponents. - person mKorbel; 05.12.2013
comment
ответьте, пожалуйста, на Github, это лучше для всех ;-) - person Daniel Ruf; 05.12.2013
comment
github.com/adobe/source-sans-pro/issues/ какие-нибудь новости / обновления? - person Daniel Ruf; 20.12.2013
comment
не я тестировал другие шрифты, часть из них с подобным и неправильным смещением, BugParade (все после слияния - с именами Oracle, но ошибки остаются с Sun) is официальная база данных ошибок Java, - person mKorbel; 20.12.2013
comment
вы уже знаете, что я зарегистрировал проблему, которой не существует - что очень странно - она ​​должна существовать, поскольку у меня есть идентификатор ошибки ... = (это очень разочаровывает Oracle и Java, и на этот вопрос нет ответа / ответ, который решает все проблемы. - person Daniel Ruf; 20.12.2013
comment
все это ни к чему не приводит, Adobe говорит, что это не ошибка шрифта, Oracle ничего не говорит, так что для меня это ошибка Java - person Daniel Ruf; 01.02.2014