当我查看 FontMetric.getAscent() 的javadoc时,我看到:



但是我写了一个快速演示程序,我看到了:

每行文本的4条水平线是:

  • 基线位置降低了getDescent()
  • 基线位置
  • getAscent() 提高的
  • 基线位置getHeight()
  • 提高的
  • 基线位置

    注意getAscent()行和字符顶部之间的空格。我已经看过大多数字体和大小,并且始终存在这种差距。 (而字体下降看起来恰好。)有什么用?
    package com.example.fonts;
    
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.GraphicsEnvironment;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Arrays;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSpinner;
    import javax.swing.JTextPane;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    
    public class FontMetricsExample extends JFrame
    {
        static final int marg = 10;
        public FontMetricsExample()
        {
            super(FontMetricsExample.class.getSimpleName());
    
            JPanel panel = new JPanel(new BorderLayout());
            JPanel fontPanel = new JPanel(new BorderLayout());
            final JTextPane textSource = new JTextPane();
            textSource.setText("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"
                    +"abcdefghijklmnopqrstuvwxyz\n"
                    +"0123456789!@#$%^&*()[]{}");
            final SpinnerNumberModel fontSizeModel =
                  new SpinnerNumberModel(18, 4, 32, 1);
            final String fonts[] =
                  GraphicsEnvironment.getLocalGraphicsEnvironment()
                    .getAvailableFontFamilyNames();
            final JComboBox fontFamilyBox = new JComboBox(fonts);
            fontFamilyBox.setSelectedItem("Arial");
    
            final JPanel text = new JPanel() {
                @Override protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    String fontFamilyName =
                             fonts[fontFamilyBox.getSelectedIndex()];
                    int fontSize = fontSizeModel.getNumber().intValue();
                    Font f = new Font(fontFamilyName, 0, fontSize);
                    g.setFont(f);
                    FontMetrics fm = g.getFontMetrics();
                    int lineHeight = fm.getHeight();
                    String[] s0 = textSource.getText().split("\n");
                    int x0 = marg;
                    int y0 = getHeight()-marg-(marg+lineHeight)*s0.length;
                    for (int i = 0; i < s0.length; ++i)
                    {
                        y0 += marg+lineHeight;
                        String s = s0[i];
                        g.drawString(s, x0, y0);
                        int w = fm.stringWidth(s);
                        for (int yofs : Arrays.asList(
                                0,   // baseline
                                -fm.getHeight(),
                                -fm.getAscent(),
                                fm.getDescent()))
                        {
                            g.drawLine(x0,y0+yofs,x0+w,y0+yofs);
                        }
                    }
                }
            };
            final JSpinner fontSizeSpinner = new JSpinner(fontSizeModel);
            fontSizeSpinner.getModel().addChangeListener(
                   new ChangeListener() {
                @Override public void stateChanged(ChangeEvent e) {
                    text.repaint();
                }
            });
            text.setMinimumSize(new Dimension(200,100));
            text.setPreferredSize(new Dimension(400,150));
            ActionListener repainter = new ActionListener() {
                @Override public void actionPerformed(ActionEvent e) {
                    text.repaint();
                }
            };
            textSource.getDocument().addDocumentListener(new DocumentListener() {
                @Override public void changedUpdate(DocumentEvent e) {
                    text.repaint();
                }
                @Override public void insertUpdate(DocumentEvent e) {}
                @Override public void removeUpdate(DocumentEvent e) {}
            });
            fontFamilyBox.addActionListener(repainter);
    
            fontPanel.add(fontFamilyBox, BorderLayout.CENTER);
            fontPanel.add(fontSizeSpinner, BorderLayout.EAST);
            fontPanel.add(textSource, BorderLayout.SOUTH);
            panel.add(fontPanel, BorderLayout.NORTH);
            panel.add(text, BorderLayout.CENTER);
            setContentPane(panel);
            pack();
            setDefaultCloseOperation(EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            new FontMetricsExample().setVisible(true);
        }
    }
    

    最佳答案

    一个可能的原因是,该值考虑了带有diacritics的字母。

    例如,添加变音符ÄÖÜ表示其颤音更接近于上升(尽管它们仍未完全到达上升位置)。

    寻找上升的更一般定义,我发现the definition in Wikipedia:



    因此,即使在版式中似乎也没有精确的绝对定义。

  • 10-06 06:51