2016-04-14 18 views
21

看来,抚摸上的子像素坐标中的Java成为破8Java的图形8抚摸子像素时毛刺坐标上的Linux

我有三套的情况下,对截图所示(列表示的情况下,行代表不同的笔划宽度):

爪哇7u51(400%比例)
Screenshot on Java 7u51 (400% scale)
爪哇8u60(400%比例)
Screenshot on Java 8u60 (400% scale)

  1. 在同一坐标上填充和描边。按照预期工作,抚摸面积大于填充面积。
  2. 抚摸缩小(按笔画宽度)并居中(按宽度的一半),使其位于填充区域的边界内。这部分在Java 8中被打破为1px的描边,其中绘画出现在子像素坐标(第一行)上; 3px笔画没有这个问题(第三行)。看起来0.5被四舍五入为1px行程。
  3. 填充矩形缩小与案例2的相同方式居中。我需要此支持子像素绘图的图形,以便在单元格重叠时进行非重叠填充。在这里你可以看到填充操作将从0.5减小到0,所以这只是一个问题。

的代码如下:

import static java.awt.BasicStroke.*; 

import java.awt.*; 
import java.awt.geom.*; 

import javax.swing.*; 

public class TestCase 
{ 
    public static void main(String[] args) 
    { 
     JFrame frame = new JFrame("Test case"); 
     frame.setSize(115, 115); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     frame.getContentPane().add(new TestPanel()); 

     frame.setVisible(true); 
    } 

    private static class TestPanel extends JPanel 
    { 
     TestPanel() 
     { 
      setOpaque(true); 
     } 

     @Override 
     protected void paintComponent(Graphics g) 
     { 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setColor(Color.white); 
      g2.fill(getBounds()); 

      Rectangle2D rect = new Rectangle2D.Double(); 
      Color background = new Color(0, 255, 255); 
      Color border = new Color(255, 0, 0, 128); 
      Stroke STROKE_1PX = new BasicStroke(1, CAP_SQUARE, JOIN_MITER); 
      Stroke STROKE_2PX = new BasicStroke(2, CAP_SQUARE, JOIN_MITER); 
      Stroke STROKE_3PX = new BasicStroke(3, CAP_SQUARE, JOIN_MITER); 
      g2.translate(10, 10); 

      /** 
      * Filling and stroking by original coordinates 
      */ 
      rect.setRect(0, 0, 25, 25); 
      g2.setColor(background); 
      g2.fill(rect); 
      g2.setColor(border); 
      g2.setStroke(STROKE_1PX); 
      g2.draw(rect); 
      g2.translate(0, 35); 
      g2.setColor(background); 
      g2.fill(rect); 
      g2.setColor(border); 
      g2.setStroke(STROKE_2PX); 
      g2.draw(rect); 
      g2.translate(0, 35); 
      g2.setColor(background); 
      g2.fill(rect); 
      g2.setColor(border); 
      g2.setStroke(STROKE_3PX); 
      g2.draw(rect); 

      /** 
      * Stroking is shrunk to be inside the filling rect 
      */ 
      g2.translate(35, -70); 
      rect.setRect(0, 0, 25, 25); 
      g2.setColor(background); 
      g2.fill(rect); 
      rect.setRect(0.5, 0.5, 24, 24); 
      g2.setColor(border); 
      g2.setStroke(STROKE_1PX); 
      g2.draw(rect); 
      g2.translate(0, 35); 
      rect.setRect(0, 0, 25, 25); 
      g2.setColor(background); 
      g2.fill(rect); 
      rect.setRect(1, 1, 23, 23); 
      g2.setColor(border); 
      g2.setStroke(STROKE_2PX); 
      g2.draw(rect); 
      g2.translate(0, 35); 
      rect.setRect(0, 0, 25, 25); 
      g2.setColor(background); 
      g2.fill(rect); 
      rect.setRect(1.5, 1.5, 22, 22); 
      g2.setColor(border); 
      g2.setStroke(STROKE_3PX); 
      g2.draw(rect); 

      /** 
      * Filling rect is additionally shrunk and centered 
      */ 
      g2.translate(35, -70); 
      rect.setRect(0.5, 0.5, 24, 24); 
      g2.setColor(background); 
      g2.fill(rect); 
      g2.setColor(border); 
      g2.setStroke(STROKE_1PX); 
      g2.draw(rect); 
      g2.translate(0, 35); 
      rect.setRect(1, 1, 23, 23); 
      g2.setColor(background); 
      g2.fill(rect); 
      g2.setColor(border); 
      g2.setStroke(STROKE_2PX); 
      g2.draw(rect); 
      g2.translate(0, 35); 
      rect.setRect(1.5, 1.5, 22, 22); 
      g2.setColor(background); 
      g2.fill(rect); 
      g2.setColor(border); 
      g2.setStroke(STROKE_3PX); 
      g2.draw(rect); 
     } 
    } 
} 

正如我测试,Java 7中不存在这个问题(试过7u51)时,Windows(8u77)和Mac(8u60)了。在不同的机器上尝试Ubuntu(8u60和8u77)和Linux Mint(8u60),并且错误在这里。

有没有人遇到过这样的问题?有没有一般的解决方法?

我不能简单地在使用笔触的地方处理1px的情况。这是因为有很多地方,我正在使用不同的Graphics2D实现,看来,从我使用的问题再现仅在SunGraphics2D。这意味着我需要在这些地方使用instanceOf来打破常见逻辑。

+1

StackOverflow不是一个错误报告机制。要报告Java的问题,请访问bugreport.java.com,并包括您的演示课程以及其他任何他们需要复制问题的内容。 – dimo414

+0

我投票结束这个问题,因为它是一个错误报告。 – dimo414

+4

我向bugtracker提交了错误,但我不希望很快看到修复。因为这是图形中的错误。几乎半年前我已经提交了另一个错误,但仍未收到有关进度的通知。 我宁愿需要一种解决方法来解决这个问题,直到解决问题。 –

回答

1

bug report讨论:

这是一个错误XRENDER = -Dsun.java2d.xrender虚假治愈它。

我自己没有检查过这个解决方案,因为除了它被审查之外,我没有收到任何来自bug报告系统的通知。由于这是Linux专用的问题,因此我们决定等待官方修复,因为我们的客户中并没有太多的Linux用户。

0

我建议你扩展Graphics2D并在需要的地方添加惩罚措施。

这样你可以保持主流程的一致性,并添加所有其他“逻辑”错误可以在需要处理的地方处理。

这可以节省修改N个文件的开销,并在修改后撤消这些更改,并将逻辑保留在应该在的位置。

+0

其实我正在使用不同的图形对象(渲染到不同的设备),这是隐式设置。我记得内部使用的SunGraphics2D无法扩展。 感谢你,我检查了Oracle员工的错误报告和解决方法。 –