Open tmssngr opened 1 month ago
IMHO consistent behavior on the different platforms is important, especially because we are working on the Skija-implementation.
Do you have a reproducer and maybe screenshots for the issue?
Thank you for reporting it @tmssngr ! Can you please provide a Snippet where one can see the quality of the images with and without interpolation? Can you also provide more details about the zooming (I assume you meant the display zoom on your Linux system)?
IMHO consistent behavior on the different platforms is important, especially because we are working on the Skija-implementation.
Just to be on the same page here, since you mentioned Skija: you're talking about the official SWT implementation for Linux, right? Otherwise, you're in the wrong repo 😅
I mean to draw an image scaled, e.g. by a factor of 10, so each pixel can be seen. I do not mean the monitor zoom level.
Just to be on the same page here, since you mentioned Skija: you're talking about the official SWT implementation for Linux, right? Otherwise, you're in the wrong repo
The purpose of the initiative31-project is to minimize the effort to implement and test something for different platforms. This means to have the same defaults for drawing on each platform, at least all obviously noticable (maybe the type of antialiasing can be platform specific). I don't want to have later the discussion that initiative31 broke the compatibility because it changed the default interpolation. IMHO this change (unification of the defaults) needs to be introduced as early as possible here in the official SWT project.
I mean to draw an image scaled, e.g. by a factor of 10, so each pixel can be seen. I do not mean the monitor zoom level.
So far I understood. Still I would prefer to have a proper reproducer to understand how the image is drawn, along with some screenshots to compare that one is able to reproduce the issue as described. There are many ways to scale and draw an image that we need to know how it is done when facing the described issue. E.g., is it just by using the according function in GC
taking different source and destination sizes triggering the resizing, or is it something elseß
Please try this snippet and specify an image path as first program argument.
import java.io.*;
import java.nio.file.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
public class ScaledImageTest {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
return;
}
final Display display = new Display();
try {
final Image image;
try (InputStream inputStream = Files.newInputStream(Paths.get(args[0]))) {
final ImageData imageData = new ImageData(inputStream);
image = new Image(display, imageData);
}
final Rectangle bounds = image.getBounds();
final Shell shell = new Shell(display);
shell.addListener(SWT.Paint, event
-> event.gc.drawImage(image, 0, 0, bounds.width, bounds.height,
0, 0, 10 * bounds.width, 10 * bounds.height));
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
finally {
display.dispose();
}
}
}
On Windows 11 I'm getting this crispy result:
and on Linux (Fedora 42 KDE) I'm getting this blurry blob:
Thank you! Looks "interesting". So it's really the GC operation doing the scaling. It's probably not a regression but existing behavior since ever? Since the GC operations rather directly map to OS operations, might be that this is basically OS behavior, so one would have to work around that inside SWT. Did you use a monitor zoom of 100% in both cases?
IMHO it is no OS behavior, but an SWT default. The zoom on Linux was 100% (default) and on Windows 150%.
I think, it makes sense to have the same default on all platforms. If this will break something for someone, then a different platform broke it anyway.
IMHO it is no OS behavior, but an SWT default.
Do you refer to the interpolation method? The interpolation is done by the OS (more precisely in GDIP/Cairo). In my impression, SWT has adapted the best fitting OS-side options for the options provided in SWT (i.e., DEFAULT, NONE, LOW, HIGH), but the OS-side options they are mapped to will unlikely produce equal results.
The case you show seems as if GTK is using some smooth scaling method (Cairo.CAIRO_FILTER_GOOD
) whereas Windows by default seems to use nearest neighbour interpolation. But since Windows is just using InterpolationModeDefault
without any clarification what that means, that may have also changed between OS versions.
So unless you want to implement image scaling completely inside SWT, I don't think you can really achieve fully consistent results across OSes here. Maybe the demonstrated situation (the default case) is something that can be better aligned. Then one should try to figure out for every OS what is currently done by default to detect the OS that is the "outlier" in terms of default behavior.
On Linux the GC defaults to Cairo.CAIRO_FILTER_GOOD
. Do we want to test every little detail on each platform, or do we want to avoid to have to do that? If we want to avoid that, we have to define one common default which produces the obviously equal result on all platforms. If on Windows we also would have gotten the blurry result, that I would have tried to set some non-default value. So I didn't notice and a customer had to complain about blurred result, I had to test on that specific platform to see he was right. That time can be avoided with a common default.
The interesting part is, that when setting any other (non-default) interpolation option on GTK, I'm getting always the same nearest-neighbor-result.
Describe the bug When drawing a bitmap zoomed on Windows I will be able to see each pixel crystal clear. On Linux I'm getting pixel puree.
To Reproduce Draw a bitmap largely zoomed.
Expected behavior The interpolation default should be the same on every platform.
Workaround Invoke
gc.setInterpolation(SWT.NONE);
.