2016-04-14 88 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員工的錯誤報告和解決方法。 –