Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在给定字体大小和dpi屏幕分辨率的情况下,Java2d/AWT文本呈现的奇怪大小/边界?_Java_Fonts_Size_Awt_Dpi - Fatal编程技术网

在给定字体大小和dpi屏幕分辨率的情况下,Java2d/AWT文本呈现的奇怪大小/边界?

在给定字体大小和dpi屏幕分辨率的情况下,Java2d/AWT文本呈现的奇怪大小/边界?,java,fonts,size,awt,dpi,Java,Fonts,Size,Awt,Dpi,我刚开始在屏幕上直接使用Java2D/AWT呈现文本。从本质上讲,它是有效的,但我很难理解AWT报告并在屏幕上呈现的结果的像素大小/尺寸 参数: 文本为“这是一个字形测试” 字体是java.awt.Font[family=Dialog,name=sans,style=plain,size=72](pt) 屏幕分辨率96 dpi 平台是x86-64 Linux X11,带有Java 8 屏幕分辨率由Toolkit.getDefaultToolkit().getScreenResolution(

我刚开始在屏幕上直接使用Java2D/AWT呈现文本。从本质上讲,它是有效的,但我很难理解AWT报告并在屏幕上呈现的结果的像素大小/尺寸

参数:

  • 文本为“这是一个字形测试”
  • 字体是java.awt.Font[family=Dialog,name=sans,style=plain,size=72](pt)
  • 屏幕分辨率96 dpi
  • 平台是x86-64 Linux X11,带有Java 8
屏幕分辨率由Toolkit.getDefaultToolkit().getScreenResolution()以编程方式确定,并与xdpyinfo相对应

fontMetrics.get…()graphics.drawString()drawGlyphVector()的结果都与这些有点奇怪的结果值一致:

  • 边界是java.awt.geom.Rectangle2D$Float[x=0.0,y=-71.55469,w=448.0,h=55.875]
  • 字体上升:45像素
  • 字体下降:12像素
  • 字体高度:57像素
如果我将字体大小从72更改为192磅,结果是一致的:java.awt.geom.Rectangle2D$Float[x=0.0,y=-190.8125,w=1208.0,h=149.0],上升:119,下降:31,高度:150。如果我更改字体面,则只有宽度更改,而高度保持不变。(这正是我所期望的。)

我假设AWT使用DTP度量,其中1 pt始终为1/72英寸。在96 dpi屏幕上,96个像素将构成一英寸(物理)。(提供的屏幕dpi值不一定准确反映实际物理设备的值,但这在这里并不重要。)因此,72 pt==1 in应转换为96。我希望在得到的尺寸值(或它们的组合)中找到接近96的东西,很可能是高度值,但它们似乎都不接近

问题

  • 有人能重现类似于我的价值观吗?还是它们非常不典型
  • 如何计算边界高度/字体高度?(我预计字体高度为96像素,72像素)
  • 或者:在Java中,字体大小参数的解释(单位)是什么
  • 正是由于AWT中的舍入或其他不准确错误,使得界限。h度量值、高度度量值、上升+下降不同,还是这种差异是有价值的信息
  • 我是否遗漏了其他相关参数?(此处不涉及仿射变换。)
  • 是否有一种安全(跨平台)的方法可以在96 dpi设备和72 pt字体大小上使字体高度可靠地达到96 px?(将字体大小乘以常量值是否可以接受?)

    • 问题解决:是我的错

      更准确地说:我实际上不是通过简单的
      newfont(Font.DIALOG,Font.PLAIN,72))
      或类似方法初始化Font对象,而是使用
      newfont(Map attributes)
      构造函数。那张地图上有各种各样的字体属性,都是从我的配置中预设的。因为一个变量预设了错误的值,它实际上包含了一个
      map.put(上标,上标_SUPER)(在我的实际代码中没有这里显示的那么清楚)

      因此,这些奇怪的边界实际上是字体一直被创建为其较小的上标变体的结果。否则,边界/创建的文本大小将更接近我的预期:

      对话框,样式=普通,大小=72],高度:84,上升:67,下降:17,边界:java.awt.geom.Rectangle2D$Float[x=0.0,y=-66.83203,w=681.0,h=83.8125]

      虽然它们的尺寸与目标尺寸不完全相同,但它们更接近目标尺寸。感谢用户1803551的MCVE建议,使我走上正轨。为了完整起见,这里是(省略):

      公共最终类TextRenderTest扩展了WindowAdapter{
      int-fontSource;
      静态私有最终字符串TESTTEXT=“这是一个glyph测试”;
      静态公共void main(字符串[]args){new TextRenderTest().main();}
      空干管(){
      帧帧=新帧(“文本渲染测试”){
      @替代公共空白绘制(图形g){
      FontMetrics fm;
      字体;
      g、 setFont(fontSource++%2==0?createFont():新字体(Font.DIALOG,Font.PLAIN,72));
      g、 抽绳(TESTTEXT,16,96);
      fm=g.getFontMetrics();
      System.out.println(
      “DPI:+Toolkit.getDefaultToolkit().getScreenResolution()+
      ,字体:“+g.getFont()+”,字体高度:“+fm.getHeight()+
      ,上升:“+fm.getAscent()+”,下降:“+fm.getDescent()+
      ,边界:“+fm.getStringBounds(TESTTEXT,g));};
      框架立根(64,32,800,280);
      frame.setVisible(true);
      frame.addWindowListener(此);
      }
      静态专用字体createFont(){
      HashMap-map=新的HashMap(9,1.0f);
      map.put(FAMILY,“sans”);
      map.put(重量,500);
      map.put(宽度,1);
      map.put(大小72);
      
      map.put(上标,上标_SUPER)5944不太可能没有,特别是因为它已经存在了很长一段时间,而且Javadoc可以非常复杂。
      public final class TextRenderTest extends WindowAdapter {
      
      int fontSource;
      static private final String TESTTEXT = "This is a glyph test";
      static public void  main (String [] args) { new TextRenderTest ().main (); }
      
      void main () {
       Frame frame = new Frame ("Text render test") {
          @Override public void paint (Graphics g) {
           FontMetrics    fm;
           Font           font;
              g.setFont (fontSource++ % 2 == 0 ? createFont () : new Font (Font.DIALOG, Font.PLAIN, 72));
              g.drawString (TESTTEXT, 16, 96);
              fm = g.getFontMetrics ();
              System.out.println (
                  "DPI: "      + Toolkit.getDefaultToolkit ().getScreenResolution () +
                  ", font: "   + g.getFont ()    + ", font height: " + fm.getHeight () +
                  ", ascent: " + fm.getAscent () + ", descent: "     + fm.getDescent () +
                  ", bounds: " + fm.getStringBounds (TESTTEXT, g)); } };
          frame.setBounds (64, 32, 800, 280);
          frame.setVisible (true);
          frame.addWindowListener (this);
      }
      static private Font createFont () {
       HashMap <TextAttribute,Object> map = new HashMap<TextAttribute,Object> (9, 1.0f);
          map.put (FAMILY, "sans");
          map.put (WEIGHT, 500);
          map.put (WIDTH, 1);
          map.put (SIZE, 72);
          map.put (SUPERSCRIPT, SUPERSCRIPT_SUPER);   // <-- Something like this was the fault
          return new Font (map);
      }
      @Override public void windowClosing (WindowEvent event) { event.getWindow ().dispose (); }
      }