Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,16 @@ public Image(Device device, Image srcImage, int flag) {
if (flag != SWT.IMAGE_DISABLE) transparentPixel = srcImage.transparentPixel;

long imageSurface = srcImage.surface;
int width = this.width = srcImage.width;
int height = this.height = srcImage.height;
this.width = srcImage.width;
this.height = srcImage.height;
int format = Cairo.cairo_surface_get_content(imageSurface) == Cairo.CAIRO_CONTENT_COLOR ? Cairo.CAIRO_FORMAT_RGB24 : Cairo.CAIRO_FORMAT_ARGB32;
boolean hasAlpha = format == Cairo.CAIRO_FORMAT_ARGB32;
surface = Cairo.cairo_image_surface_create(format, width, height);
int dataWidth = DPIUtil.pointToPixel(this.width, DPIUtil.getDeviceZoom());
int dataHeight= DPIUtil.pointToPixel(this.height, DPIUtil.getDeviceZoom());
surface = Cairo.cairo_image_surface_create(format, dataWidth, dataHeight);
if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
if (DPIUtil.getDeviceZoom() != currentDeviceZoom) {
double scaleFactor = DPIUtil.getDeviceZoom() / 100f;
Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
}
double scaleFactor = DPIUtil.getDeviceZoom() / 100f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
double scaleFactor = DPIUtil.getDeviceZoom() / 100f;
double[] scaleX = new double[1];
double[] scaleY = new double[1];
Cairo.cairo_surface_get_device_scale(imageSurface, scaleX, scaleY);

Copy link
Member

@akurtakov akurtakov Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is copy of the image it's best to fetch the scale (cairo gives separate x/y scale factors) of the image copied.

Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
Comment on lines +289 to +290
Copy link
Contributor

@akoch-yatta akoch-yatta Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is setting the scale still necessary? I don't get what the purpose is when the surface already has the correct size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is necessary. Otherwise it will look like this:
image

In my understanding, you need to do two things (which are the two places I adapted):

  1. Give the correct size in pixels to the surface; by now we used the size in points, which led to have the expected size at 200% zoom
  2. Tell Cairo at what scale that surface is used to ensure that coordinates are properly transformed; this is basically the same we have to do in SWT with point/pixel conversion. If you leave that out, you have a surface of double the size (when device zoom is 200) but since you treat all coordinates as 100%, it will paint at half scale to the top-left area of the surface.

Copy link
Contributor

@arunjose696 arunjose696 Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not able to understand a slight detail on how the images were drawn fully (although blurrily scaled) before, as the height and width of the surface was in points I would expect to the surface to have only data in half width and height or the image to be partially cut off, when the zoom is 200%

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because the surface scale was usually set to 1 as currentDeviceZoom and DPIUtil.getDeviceZoom() were equal. I don't know why the check was there at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Cairo.cairo_surface_set_device_scale(surface, scaleFactor, scaleFactor);
Cairo.cairo_surface_set_device_scale(surface, scaleX[0], scaleY[0]);

long cairo = Cairo.cairo_create(surface);
if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_SOURCE);
Expand All @@ -306,9 +306,9 @@ public Image(Device device, Image srcImage, int flag) {
switch (flag) {
case SWT.IMAGE_DISABLE: {
byte[] line = new byte[stride];
for (int y=0; y<height; y++) {
for (int y=0; y<dataHeight; y++) {
C.memmove(line, data + (y * stride), stride);
for (int x = 0, offset = 0; x < width; x++, offset += 4) {
for (int x = 0, offset = 0; x < dataWidth; x++, offset += 4) {
int a = line[offset + oa] & 0xFF;
int r = line[offset + or] & 0xFF;
int g = line[offset + og] & 0xFF;
Expand Down Expand Up @@ -339,9 +339,9 @@ public Image(Device device, Image srcImage, int flag) {
}
case SWT.IMAGE_GRAY: {
byte[] line = new byte[stride];
for (int y=0; y<height; y++) {
for (int y=0; y<dataHeight; y++) {
C.memmove(line, data + (y * stride), stride);
for (int x=0, offset = 0; x<width; x++, offset += 4) {
for (int x=0, offset = 0; x<dataWidth; x++, offset += 4) {
int a = line[offset + oa] & 0xFF;
int r = line[offset + or] & 0xFF;
int g = line[offset + og] & 0xFF;
Expand Down
Loading