Skip to content

Commit 033a892

Browse files
committed
[win32] Choose best Image handle drawing with GC
This commit adapts the drawImage method in GC in the windows implementation for copying and (probably) scaling an area from a source image into the GC target. With the Image supporting multiple handles now, the handle from the source image is no longer chosen by the zoom context of the GC but from the target size, e.g. if an image should be drawn with a scale of 2 on a 100% monitor, it might provide better results to use an image handle fitting for 200%.
1 parent 4df99ba commit 033a892

File tree

1 file changed

+37
-7
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+37
-7
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -985,31 +985,61 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei
985985
if (image == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
986986
if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
987987

988-
int imageZoom = getZoom();
989-
Rectangle src = DPIUtil.scaleUp(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), imageZoom);
988+
int gcZoom = getZoom();
989+
int srcImageZoom = calculateZoomForImage(gcZoom, srcWidth, srcHeight, destWidth, destHeight);
990+
drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, gcZoom, srcImageZoom);
991+
}
992+
993+
private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int destWidth, int destHeight) {
994+
if (srcWidth == 1 && srcHeight == 1) {
995+
// One pixel images can use the GC zoom
996+
return gcZoom;
997+
}
998+
if (destWidth == srcWidth && destHeight == srcHeight) {
999+
// unscaled images can use the GC zoom
1000+
return gcZoom;
1001+
}
1002+
if (gcZoom > 175) {
1003+
// big images can use the GC zoom
1004+
return gcZoom;
1005+
}
1006+
1007+
float imageScaleFactor = 1f*destWidth/srcWidth;
1008+
if (gcZoom*imageScaleFactor > 175) {
1009+
return 200;
1010+
}
1011+
return gcZoom;
1012+
}
1013+
1014+
private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY,
1015+
int destWidth, int destHeight, int imageZoom, int scaledImageZoom) {
1016+
Rectangle src = DPIUtil.scaleUp(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), scaledImageZoom);
9901017
Rectangle dest = DPIUtil.scaleUp(drawable, new Rectangle(destX, destY, destWidth, destHeight), imageZoom);
991-
if (imageZoom != 100) {
1018+
if (scaledImageZoom != 100) {
9921019
/*
9931020
* This is a HACK! Due to rounding errors at fractional scale factors,
9941021
* the coordinates may be slightly off. The workaround is to restrict
9951022
* coordinates to the allowed bounds.
9961023
*/
997-
Rectangle b = image.getBounds(imageZoom);
1024+
Rectangle b = image.getBounds(scaledImageZoom);
9981025
int errX = src.x + src.width - b.width;
9991026
int errY = src.y + src.height - b.height;
10001027
if (errX != 0 || errY != 0) {
1001-
if (errX <= imageZoom / 100 && errY <= imageZoom / 100) {
1028+
if (errX <= scaledImageZoom / 100 && errY <= scaledImageZoom / 100) {
10021029
src.intersect(b);
10031030
} else {
10041031
SWT.error (SWT.ERROR_INVALID_ARGUMENT);
10051032
}
10061033
}
10071034
}
1008-
drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false);
1035+
drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false, scaledImageZoom);
10091036
}
10101037

10111038
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
1012-
int imageZoom = getZoom();
1039+
drawImage(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, getZoom());
1040+
}
1041+
1042+
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imageZoom) {
10131043
if (data.gdipGraphics != 0) {
10141044
//TODO - cache bitmap
10151045
long [] gdipImage = srcImage.createGdipImage(imageZoom);

0 commit comments

Comments
 (0)