Community
Participate
Working Groups
Created attachment 191329 [details] Screenshot showing the difference between the two snippets. While trying to isolate a SWT-alone snippet to reproduce GEF bug #124506, I recognized that reusing a Transform object between different calls to GC#drawPath() leads to inconsistent painting. Consider the two snippets added below, which differ only by reusing vs. recreating a Transform that is used on the GC. While the snippet recreating a Transform between succeeding calls to drawPath() seems to paint the paths as desired, the one that recycles the Transform "looses" two of the painted paths. /******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package swt.bugs; import org.eclipse.draw2d.ColorConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Path; import org.eclipse.swt.graphics.Transform; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; public class RecreateTransformSnippet { private static final Display display = new Display(); private static final Color darkGreen = new Color(null, 0, 127, 0); private static final Color darkBlue = new Color(null, 0, 0, 127); private static final Color black = new Color(null, 0, 0, 0); private static Path path1; private static Path path2; private static Transform transform; public static void main(String[] args) { path1 = new Path(null); path1.moveTo(20, 5); path1.quadTo(40, 5, 50, 25); path1.quadTo(20, 25, 20, 45); path1.lineTo(0, 25); path1.close(); path2 = new Path(null); path2.moveTo(15, 30); path2.cubicTo(50, 0, 50, 30, 20, 60); path2.close(); final Shell shell = new Shell(display); shell.setText("Advanced Graphics"); shell.addListener(SWT.Paint, new Listener() { public void handleEvent(Event event) { GC gc = event.gc; drawPaths(0, gc, SWT.ON, 3, SWT.LINE_SOLID, darkBlue, darkBlue); drawPaths(1, gc, SWT.OFF, 0, SWT.LINE_DOT, ColorConstants.red, darkBlue); drawPaths(2, gc, SWT.DEFAULT, 1, SWT.LINE_DOT, darkBlue, darkBlue); drawPaths(3, gc, SWT.DEFAULT, 2, SWT.LINE_DOT, darkGreen, darkBlue); drawPaths(4, gc, SWT.ON, 2, SWT.LINE_DASHDOTDOT, black, darkBlue); } }); shell.setSize(200, 600); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } path1.dispose(); path2.dispose(); display.dispose(); } protected static void drawPaths(int i, GC gc, int antialias, int lineWidth, int lineSolid, Color foreground, Color background) { gc.setAntialias(antialias); gc.setLineWidth(lineWidth); gc.setLineStyle(lineSolid); gc.setForeground(foreground); gc.setBackground(background); transform = new Transform(gc.getDevice()); transform.translate(0, i * 100); gc.setTransform(transform); gc.drawPath(path1); gc.drawPath(path2); transform.dispose(); } } /******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package swt.bugs; import org.eclipse.draw2d.ColorConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Path; import org.eclipse.swt.graphics.Transform; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; public class RecycleTransformSnippet { private static final Display display = new Display(); private static final Color darkGreen = new Color(null, 0, 127, 0); private static final Color darkBlue = new Color(null, 0, 0, 127); private static final Color black = new Color(null, 0, 0, 0); private static Path path1; private static Path path2; private static Transform transform; public static void main(String[] args) { path1 = new Path(null); path1.moveTo(20, 5); path1.quadTo(40, 5, 50, 25); path1.quadTo(20, 25, 20, 45); path1.lineTo(0, 25); path1.close(); path2 = new Path(null); path2.moveTo(15, 30); path2.cubicTo(50, 0, 50, 30, 20, 60); path2.close(); final Shell shell = new Shell(display); shell.setText("Advanced Graphics"); shell.addListener(SWT.Paint, new Listener() { public void handleEvent(Event event) { GC gc = event.gc; transform = new Transform(gc.getDevice()); drawPaths(0, gc, SWT.ON, 3, SWT.LINE_SOLID, darkBlue, darkBlue); drawPaths(1, gc, SWT.OFF, 0, SWT.LINE_DOT, ColorConstants.red, darkBlue); drawPaths(2, gc, SWT.DEFAULT, 1, SWT.LINE_DOT, darkBlue, darkBlue); drawPaths(3, gc, SWT.DEFAULT, 2, SWT.LINE_DOT, darkGreen, darkBlue); drawPaths(4, gc, SWT.ON, 2, SWT.LINE_DASHDOTDOT, black, darkBlue); transform.dispose(); } }); shell.setSize(200, 600); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } path1.dispose(); path2.dispose(); display.dispose(); } protected static void drawPaths(int i, GC gc, int antialias, int lineWidth, int lineSolid, Color foreground, Color background) { gc.setAntialias(antialias); gc.setLineWidth(lineWidth); gc.setLineStyle(lineSolid); gc.setForeground(foreground); gc.setBackground(background); transform.translate(0, i * 100); gc.setTransform(transform); gc.drawPath(path1); gc.drawPath(path2); } }
I am sorry, but I overlooked that the snippets still depend on Draw2d's ColorConstants.red. You may of course simply remove this by declaring another local color constant as follows: private static final Color red = new Color(null, 255, 0, 0);
Forget about this one. In case the transform is not recycled, it should of course be: transform.translate(0, 100); instead of transform.translate(0, i*100);