gef-classic icon indicating copy to clipboard operation
gef-classic copied to clipboard

Line artefacts on Canvas at Windows 200% scaling

Open Phillipus opened this issue 2 years ago • 7 comments
trafficstars

Windows 11 at hi-dpi scaling.

Spurious lines are drawn on a Draw2d canvas if the canvas is dragged to the edges of the monitor and dragged back again. In the following screenshot I dragged Archi to the bottom of the screen so it overlaps then dragged it back to centre of the screen again. Those horizontal lines that span the diagram and palette are the unwanted artefacts.

screenshot

Snippet to reproduce:

import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class CanvasTest {

    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        shell.setSize(300, 300);

        FigureCanvas fc = new FigureCanvas(shell);
        RectangleFigure root = new RectangleFigure();
        root.setBackgroundColor(new Color(null, 255, 255, 255));
        fc.getLightweightSystem().getRootFigure().add(root);
        
        shell.open();
        while(!shell.isDisposed()) {
            if(!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
}

Run the snippet and drag the window to the edges of the screen so it overlaps the screen and drag it back to the centre of the screen.

lines

Phillipus avatar Jun 09 '23 21:06 Phillipus

The class of interest is org.eclipse.draw2d.FigureCanvas and this line:

static final int DEFAULT_STYLES = SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL;

If I remove SWT.NO_BACKGROUND like this:

static final int DEFAULT_STYLES = SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL;

Then the lines are eliminated.

Phillipus avatar Jun 09 '23 21:06 Phillipus

Note the JavaDoc for SWT.NO_BACKGROUND:

This style might be used as an alternative to "double-buffering" in order to reduce flicker.

A ScrollingGraphicalViewer creates a FigureCanvas like this:

new FigureCanvas(parent, getLightweightSystem())

And that calls the constructor:

public FigureCanvas(Composite parent, LightweightSystem lws) {
    this(parent, SWT.DOUBLE_BUFFERED, lws);
}

So, in this case, FigureCanvas uses both SWT.NO_BACKGROUND and SWT.DOUBLE_BUFFERED

Phillipus avatar Jun 09 '23 22:06 Phillipus

I got a better result by hacking into FigureCanvas so that if SWT.DOUBLE_BUFFERED and SWT.NO_BACKGROUND are used then only use SWT.DOUBLE_BUFFERED:

private static int checkStyle(int style) {
    if((style & SWT.DOUBLE_BUFFERED) != 0 && (style & SWT.NO_BACKGROUND) != 0) {
        style = style & ~SWT.NO_BACKGROUND;
    }
    
    if ((style & REQUIRED_STYLES) != REQUIRED_STYLES)
        throw new IllegalArgumentException(
                "Required style missing on FigureCanvas"); //$NON-NLS-1$
    if ((style & ~ACCEPTED_STYLES) != 0)
        throw new IllegalArgumentException(
                "Invalid style being set on FigureCanvas"); //$NON-NLS-1$
    return style;
}

But there are still lines on the palette and on Zest nodes.

Phillipus avatar Jun 10 '23 10:06 Phillipus

We noticed some shadow lines in 4diac IDE on windows on resizing elements (in our case Draw2d elements inside a canvas) when the sizes of the elements where not correct or some elements where drawn outside of the sizes. Could it be an off by one or a rounding error during drawing? And by that that some clipping masks are set wrong?

azoitl avatar Jun 10 '23 12:06 azoitl

It's only happening on Windows at 200% scale. I tried to narrow it down to pure SWT but I can't reproduce it without using a org.eclipse.draw2d.LightweightSystem so there's something going on further down the line, perhaps in org.eclipse.draw2d.DeferredUpdateManager.

Phillipus avatar Jun 10 '23 12:06 Phillipus

It's only happening on Windows at 200% scale. I tried to narrow it down to pure SWT but I can't reproduce it without using a org.eclipse.draw2d.LightweightSystem so there's something going on further down the line, perhaps in org.eclipse.draw2d.DeferredUpdateManager.

What I noticed is that on Windows redrawing is done differently. That's the reason I mentioned it.

azoitl avatar Jun 10 '23 13:06 azoitl

This issue is stale because it has been open for 90 days with no activity.

github-actions[bot] avatar Dec 08 '23 02:12 github-actions[bot]

This issue was closed because it has been inactive for 180 days since being marked as stale.

github-actions[bot] avatar Jun 06 '24 01:06 github-actions[bot]