Skip to content

[GTK] [HiDPI] GC.fillGradientRectangle changes device scale #3107

@Phillipus

Description

@Phillipus

This is transferred from https://bugs.eclipse.org/bugs/show_bug.cgi?id=568864

Linux HiDPI GC.fillGradientRectangle changes device scale when drawing an image.

Linux Mint or Ubuntu latest versions
Hi-res display (200% scaling)

I am creating an SWT Image to a GC instance using GC.fillGradientRectangle() and drawing text to the same GC instance.

However, GC.fillGradientRectangle() changes the scale so any further drawing is not at the original scaling.

  • Run the attached snippet and look at the generated image
  • drawText() is called first and draws correctly
  • fillGradientRectangle() is then called
  • drawText() is then called again, but this time scaling is at 2x and so the text is double size
  • If fillGradientRectangle() is commented out, then drawing is at the correct scale

It seems that once GC#fillGradientRectangle() is called any drawing after that is at double scale.

Note these lines in GC#fillGradientRectangle():

long surface = Cairo.cairo_get_target(cairo);
if (surface != 0) {
float scaleFactor = DPIUtil.getDeviceZoom() / 100f;
Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
}

Perhaps the scale should be set back to its original setting after drawing the gradient?

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


public class GraphicsSnippet {

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        
        Image image = createImage(display);
        
        shell.addListener(SWT.Paint, event -> {
            GC gc = event.gc;
            gc.drawImage(image, 0, 0);
        });

        shell.setSize(400, 400);
        shell.open();

        while(!shell.isDisposed()) {
            if(!display.readAndDispatch()) display.sleep();
        }

        display.dispose();
        image.dispose();
    }
    
    private static Image createImage(Display display) {
        Image image = new Image(display, 400, 400);
        GC gc = new GC(image);
        
        // Draw some text
        gc.drawText("Hello World", 10, 0);
        
        // If this line is commented out, scaling is correct
        gc.fillGradientRectangle(10, 20, 20, 20, true);
        
        // Draw some more text, but now it is at 2x scale
        gc.drawText("Hello World", 10, 50);
        
        gc.dispose();
        
        return image;
    }
}

On Linux:

Image

On WIndows:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions