diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index ddaa6da5964..70f648acab0 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -986,30 +986,39 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); int imageZoom = getZoom(); - Rectangle src = DPIUtil.scaleUp(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), imageZoom); - Rectangle dest = DPIUtil.scaleUp(drawable, new Rectangle(destX, destY, destWidth, destHeight), imageZoom); - if (imageZoom != 100) { - /* - * This is a HACK! Due to rounding errors at fractional scale factors, - * the coordinates may be slightly off. The workaround is to restrict - * coordinates to the allowed bounds. - */ - Rectangle b = image.getBounds(imageZoom); - int errX = src.x + src.width - b.width; - int errY = src.y + src.height - b.height; - if (errX != 0 || errY != 0) { - if (errX <= imageZoom / 100 && errY <= imageZoom / 100) { - src.intersect(b); - } else { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); + float imageScaleFactor = 1f*destWidth/srcWidth; + int scaledImageZoom = Math.round(imageZoom*imageScaleFactor); + + image.applyUsingAnyHandle(scaledImageZoom, (imageHandle) -> { + Rectangle src = DPIUtil.scaleUp(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), scaledImageZoom); + Rectangle dest = DPIUtil.scaleUp(drawable, new Rectangle(destX, destY, destWidth, destHeight), imageZoom); + + if (scaledImageZoom != 100) { + /* + * This is a HACK! Due to rounding errors at fractional scale factors, + * the coordinates may be slightly off. The workaround is to restrict + * coordinates to the allowed bounds. + */ + Rectangle b = image.getBounds(scaledImageZoom); + int errX = src.x + src.width - b.width; + int errY = src.y + src.height - b.height; + if (errX != 0 || errY != 0) { + if (errX <= scaledImageZoom / 100 && errY <= scaledImageZoom / 100) { + src.intersect(b); + } else { + SWT.error (SWT.ERROR_INVALID_ARGUMENT); + } } } - } - drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false); + drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false, scaledImageZoom); + }); } void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { - int imageZoom = getZoom(); + drawImage(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, getZoom()); +} + +void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imageZoom) { if (data.gdipGraphics != 0) { //TODO - cache bitmap long [] gdipImage = srcImage.createGdipImage(imageZoom); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 272cedb319f..913aae033d7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -1832,6 +1832,22 @@ T applyUsingAnyHandle(Function function) { return function.apply(zoomLevelToImageHandle.values().iterator().next()); } +void applyUsingAnyHandle(int zoom, Consumer consumer) { + ImageHandle imageHandle = zoomLevelToImageHandle.get(zoom); + if (imageHandle!= null) { + consumer.accept(imageHandle.handle); + return; + } + + ImageHandle temporaryHandle = this.imageProvider.newImageHandle(zoom); + try { + consumer.accept(temporaryHandle.handle); + return; + } finally { + temporaryHandle.destroy(); + } +} + /** * Invokes platform specific functionality to allocate a new image. *