Java上下颠倒的文字-是BUG还是特性?

7

当我在使用Java字体类和Swing时,将字体大小设置为负数。

我发现这使文本被倒置绘制。这是一个bug还是一个特性?有人能解释一下为什么会出现这种行为吗?

试一试:

import java.awt.Font;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class UpsideDown extends JFrame{

    public UpsideDown(){
        setSize(500,500);
        setContentPane(new Panel());
        setVisible(true);
    }

    public class Panel extends JPanel{
        public void paintComponent(Graphics g){
            Font f = new Font("Sans-Serif", Font.PLAIN, -50);
            g.setFont(f);
            g.drawString("Upside Down", 400, 100);
        }
    }

    public static void main(String args[]){
        new UpsideDown();
    }
}

Upside Down


对于矢量字体,坐标是根据字体大小作为方程的一部分计算的。 - Thorbjørn Ravn Andersen
@ThorbjørnRavnAndersen 带有 WTE“不是 bug”的前缀 - 我认为这就是一个答案。 - Andrew Thompson
2个回答

6

看起来是这样发生的:

  1. Swing将字体高度向下绘制,因为它将字体大小乘以字体的字形高度。 -50 * glyph_height 是负数,所以向下而不是向上绘制。
  2. 它还将字形(即字母)的宽度向左绘制,同样是因为它将您的字体大小乘以字体指定的字形宽度。

虽然从技术上讲是正确的,但它可能被标记为“无效操作”或“未定义行为”,因为没有所谓的“负字体大小”。与RGB颜色进行比较:如果某些实现允许您设置红色的负值,会怎么样? - Jongware
@Jongware,这可能会成为一个问题,因为图形驱动程序通常只使用每种颜色的一个字节。这将导致您的图形驱动程序崩溃,或者将red = -1包装到red = 255 :) - PurkkaKoodari
是的,但这是因为 RGB 是以这种方式实现的(幸运的是你加了“通常”)。如果“字体大小”存储在无符号类型中,您也不会遇到此问题。 - Jongware
@Jongware 很不幸,Java没有无符号原始类型,并且编码人员没有在“Font”构造函数中添加检查。 - PurkkaKoodari

3

这是一个特性。

在Swing中,几乎所有的量都是代数量,意味着它们可以是负数,并且可以参与代数计算,可能会改变它们的符号,就像当你乘以-1时一样。例如,矩形的宽度可以是负数,这是完全可以的。字体也不例外。

无论如何,请尝试在家中进行以下操作:

  • 取任何一个绘制2D图形的代码片段,在Graphics2D图形上下文中绘制。(即重写paintComponent(Graphics g)方法并以Graphics2D g2 = (Graphics2D)g;开始)。例如,您可能有一个绘制图表的组件,如下所示:

enter image description here

  • Before the drawing operations, insert the following two lines:

              g2.scale( -1.0, -1.0 );
              g2.translate( -getWidth(), -getHeight() );
    
  • Now check the result. It will all be perfectly up-side down, like this:

在这里输入图片描述

不难发现,如果你将x轴的比例放大两倍而y轴不变,所有东西都会被拉长,包括文本中的字符,如下图所示:

在这里输入图片描述

这展示了Swing中的所有内容,甚至到字符字形的个体坐标,都是代数量。

这种方法赋予了很大的自由度。如果你想倒置图形但保持文字正常,一种方法是将字体大小设置为负数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接