triangulo rombo poligono graficos ejemplo drawline dibujar java java-8 graphics2d

rombo - Los gráficos de Java 8 fallan al trazar las coordenadas de subpíxeles en Linux



java 2d pdf (2)

Parece que los trazos en las coordenadas de subpíxeles se rompieron en Java 8.

Tengo tres conjuntos de casos, que se muestran en las capturas de pantalla (las columnas representan casos, las filas representan diferentes anchos de trazo):

Java 7u51 (escala 400%)

Java 8u60 (escala 400%)

  1. Rellenar y trazar en las mismas coordenadas. Funciona según lo previsto, el área trazada es más grande que el área de llenado.
  2. El trazo se reduce (por el ancho del trazo) y se centra (por la mitad del ancho) para estar dentro de los límites de la región de relleno. Esta parte está rota en Java 8 para trazo de 1px, donde la pintura se produce en una coordenada de sub-píxel (primera fila); El trazo de 3px no tiene este problema (tercera fila). Parece que 0.5 se redondea para el golpe de 1px.
  3. El rectángulo de relleno se encoge y se enfoca de la misma manera que en el caso 2. Necesito esto en los gráficos, que admiten el dibujo de subpíxeles, para que el relleno no se superponga cuando las celdas se superponen. Aquí puede ver que la operación de relleno redondea de 0.5 a 0, por lo que solo es un problema de trazo.

El código está abajo:

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); } } }

Como lo probé, Java 7 no tiene este problema (probado en 7u51), Windows (8u77) y Mac (8u60) también. Probado en Ubuntu (8u60 y 8u77) y Linux Mint (8u60) en diferentes máquinas y el error estaba aquí.

¿Alguien enfrentó tal problema? ¿Hay alguna solución general?

No puedo simplemente manejar el caso de 1px en lugares donde se utiliza el trazo. Es porque hay muchos lugares y estoy trabajando con diferentes implementaciones de Graphics2D y parece que, por lo que he usado, el problema se reproduce solo en SunGraphics2D . Esto significa que necesito usar instanceOf en estos lugares para no romper la lógica común.


De la discusión del informe de error :

Es un error de xrender -Dsun.java2d.xrender = false lo cura.

No he comprobado esta solución por mi cuenta ya que no recibí ninguna notificación del sistema de informe de errores, además de que se revisó. Y como era un problema exclusivo de Linux, se decidió esperar las correcciones oficiales ya que no había muchos usuarios de Linux entre nuestros clientes.


Le sugiero que amplíe Graphics2D y agregue medidas correccionales allí donde sea necesario.

De esa manera, puede mantener su flujo principal constante y agregar todos los demás errores "lógicos" que se pueden manejar donde sea necesario.

Esto le ahorra la sobrecarga de modificar archivos N y deshacer esos cambios si se soluciona, y mantener la lógica donde debería estar.