Skip to content

Commit 052a7f4

Browse files
authored
Merge branch 'eclipse-platform:master' into master
2 parents e55c406 + 216f1ad commit 052a7f4

File tree

21 files changed

+382
-172
lines changed

21 files changed

+382
-172
lines changed

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,10 @@ public static ImageData autoScaleImageData (Device device, final ImageData image
150150
int height = imageData.height;
151151
int scaledWidth = Math.round (width * scaleFactor);
152152
int scaledHeight = Math.round (height * scaleFactor);
153+
int defaultZoomLevel = 100;
153154
boolean useSmoothScaling = isSmoothScalingEnabled() && imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK;
154155
if (useSmoothScaling) {
155-
Image original = new Image (device, (ImageDataProvider) zoom -> imageData);
156+
Image original = new Image(device, (ImageDataProvider) zoom -> (zoom == defaultZoomLevel) ? imageData : null);
156157
ImageGcDrawer drawer = new ImageGcDrawer() {
157158
@Override
158159
public void drawOn(GC gc, int imageWidth, int imageHeight) {
@@ -166,7 +167,7 @@ public int getGcStyle() {
166167
}
167168
};
168169
Image resultImage = new Image (device, drawer, scaledWidth, scaledHeight);
169-
ImageData result = resultImage.getImageData (100);
170+
ImageData result = resultImage.getImageData (defaultZoomLevel);
170171
original.dispose ();
171172
resultImage.dispose ();
172173
return result;

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

Lines changed: 103 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -491,13 +491,38 @@ public void copyArea (Image image, int x, int y) {
491491
storeAndApplyOperationForExistingHandle(new CopyAreaToImageOperation(image, x, y));
492492
}
493493

494-
private class CopyAreaToImageOperation extends Operation {
495-
private final Image image;
494+
private abstract class ImageOperation extends Operation {
495+
private Image image;
496+
497+
ImageOperation(Image image) {
498+
setImage(image);
499+
image.addOnDisposeListener(this::setCopyOfImage);
500+
}
501+
502+
private void setImage(Image image) {
503+
this.image = image;
504+
}
505+
506+
private void setCopyOfImage(Image image) {
507+
if (!GC.this.isDisposed()) {
508+
Image copiedImage = new Image(image.device, image, SWT.IMAGE_COPY);
509+
setImage(copiedImage);
510+
registerForDisposal(copiedImage);
511+
}
512+
}
513+
514+
protected Image getImage() {
515+
return image;
516+
}
517+
518+
}
519+
520+
private class CopyAreaToImageOperation extends ImageOperation {
496521
private final int x;
497522
private final int y;
498523

499524
CopyAreaToImageOperation(Image image, int x, int y) {
500-
this.image = image;
525+
super(image);
501526
this.x = x;
502527
this.y = y;
503528
}
@@ -507,7 +532,7 @@ void apply() {
507532
int zoom = getZoom();
508533
int scaledX = Win32DPIUtils.pointToPixel(drawable, this.x, zoom);
509534
int scaledY = Win32DPIUtils.pointToPixel(drawable, this.y, zoom);
510-
copyAreaInPixels(this.image, scaledX, scaledY);
535+
copyAreaInPixels(getImage(), scaledX, scaledY);
511536
}
512537
}
513538

@@ -1013,18 +1038,17 @@ public void drawImage (Image image, int x, int y) {
10131038
storeAndApplyOperationForExistingHandle(new DrawImageOperation(image, new Point(x, y)));
10141039
}
10151040

1016-
private class DrawImageOperation extends Operation {
1017-
private final Image image;
1041+
private class DrawImageOperation extends ImageOperation {
10181042
private final Point location;
10191043

10201044
DrawImageOperation(Image image, Point location) {
1021-
this.image = image;
1045+
super(image);
10221046
this.location = location;
10231047
}
10241048

10251049
@Override
10261050
void apply() {
1027-
drawImageInPixels(this.image, Win32DPIUtils.pointToPixel(drawable, this.location, getZoom()));
1051+
drawImageInPixels(getImage(), Win32DPIUtils.pointToPixel(drawable, this.location, getZoom()));
10281052
}
10291053

10301054
private void drawImageInPixels(Image image, Point location) {
@@ -1081,13 +1105,12 @@ void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight,
10811105
storeAndApplyOperationForExistingHandle(new DrawImageToImageOperation(srcImage, new Rectangle(srcX, srcY, srcWidth, srcHeight), new Rectangle(destX, destY, destWidth, destHeight), simple));
10821106
}
10831107

1084-
private class DrawScalingImageToImageOperation extends Operation {
1085-
private final Image image;
1108+
private class DrawScalingImageToImageOperation extends ImageOperation {
10861109
private final Rectangle source;
10871110
private final Rectangle destination;
10881111

10891112
DrawScalingImageToImageOperation(Image image, Rectangle source, Rectangle destination) {
1090-
this.image = image;
1113+
super(image);
10911114
this.source = source;
10921115
this.destination = destination;
10931116
}
@@ -1096,7 +1119,7 @@ private class DrawScalingImageToImageOperation extends Operation {
10961119
void apply() {
10971120
int gcZoom = getZoom();
10981121
int srcImageZoom = calculateZoomForImage(gcZoom, source.width, source.height, destination.width, destination.height);
1099-
drawImage(image, source.x, source.y, source.width, source.height, destination.x, destination.y, destination.width, destination.height, gcZoom, srcImageZoom);
1122+
drawImage(getImage(), source.x, source.y, source.width, source.height, destination.x, destination.y, destination.width, destination.height, gcZoom, srcImageZoom);
11001123
}
11011124

11021125
private Collection<Integer> getAllCurrentMonitorZooms() {
@@ -1154,22 +1177,21 @@ private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHei
11541177
drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false, scaledImageZoom);
11551178
}
11561179

1157-
private class DrawImageToImageOperation extends Operation {
1158-
private final Image image;
1180+
private class DrawImageToImageOperation extends ImageOperation {
11591181
private final Rectangle source;
11601182
private final Rectangle destination;
11611183
private final boolean simple;
11621184

11631185
DrawImageToImageOperation(Image image, Rectangle source, Rectangle destination, boolean simple) {
1164-
this.image = image;
1186+
super(image);
11651187
this.source = source;
11661188
this.destination = destination;
11671189
this.simple = simple;
11681190
}
11691191

11701192
@Override
11711193
void apply() {
1172-
drawImage(image, source.x, source.y, source.width, source.height, destination.x, destination.y, destination.width, destination.height, simple, getZoom());
1194+
drawImage(getImage(), source.x, source.y, source.width, source.height, destination.x, destination.y, destination.width, destination.height, simple, getZoom());
11731195
}
11741196
}
11751197

@@ -1958,14 +1980,20 @@ private class DrawPathOperation extends Operation {
19581980
@Override
19591981
void apply() {
19601982
Path path = new Path(device, pathData);
1961-
long pathHandle = path.getHandle(getZoom());
1962-
if (pathHandle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1963-
initGdip();
1964-
checkGC(DRAW);
1965-
long gdipGraphics = data.gdipGraphics;
1966-
Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend);
1967-
Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, pathHandle);
1968-
Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend);
1983+
try {
1984+
long pathHandle = path.getHandle(getZoom());
1985+
if (pathHandle == 0)
1986+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1987+
initGdip();
1988+
checkGC(DRAW);
1989+
long gdipGraphics = data.gdipGraphics;
1990+
Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend);
1991+
Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, pathHandle);
1992+
Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset,
1993+
Gdip.MatrixOrderPrepend);
1994+
} finally {
1995+
path.dispose();
1996+
}
19691997
}
19701998
}
19711999

@@ -3272,13 +3300,18 @@ private class FillPathOperation extends Operation {
32723300
@Override
32733301
void apply() {
32743302
Path path = new Path(device, pathData);
3275-
long pathHandle = path.getHandle(getZoom());
3276-
if (pathHandle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3277-
initGdip();
3278-
checkGC(FILL);
3279-
int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate;
3280-
Gdip.GraphicsPath_SetFillMode(pathHandle, mode);
3281-
Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, pathHandle);
3303+
try {
3304+
long pathHandle = path.getHandle(getZoom());
3305+
if (pathHandle == 0)
3306+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3307+
initGdip();
3308+
checkGC(FILL);
3309+
int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate;
3310+
Gdip.GraphicsPath_SetFillMode(pathHandle, mode);
3311+
Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, pathHandle);
3312+
} finally {
3313+
path.dispose();
3314+
}
32823315
}
32833316
}
32843317

@@ -4629,7 +4662,9 @@ private class SetBackgroundOperation extends Operation {
46294662
private final Color color;
46304663

46314664
SetBackgroundOperation(Color color) {
4632-
this.color = color;
4665+
RGB rgb = color.getRGB();
4666+
this.color = new Color(color.getDevice(), rgb);
4667+
registerForDisposal(this.color);
46334668
}
46344669

46354670
@Override
@@ -4676,6 +4711,7 @@ private class SetBackgroundPatternOperation extends Operation {
46764711

46774712
SetBackgroundPatternOperation(Pattern pattern) {
46784713
this.pattern = pattern == null ? null : pattern.copy();
4714+
registerForDisposal(this.pattern);
46794715
}
46804716

46814717
@Override
@@ -4938,7 +4974,8 @@ private class SetFontOperation extends Operation {
49384974
private final Font font;
49394975

49404976
SetFontOperation(Font font) {
4941-
this.font = font;
4977+
this.font = new Font(font.getDevice(), font.getFontData());
4978+
registerForDisposal(this.font);
49424979
}
49434980

49444981
@Override
@@ -4973,7 +5010,9 @@ private class SetForegroundOperation extends Operation {
49735010
private final Color color;
49745011

49755012
SetForegroundOperation(Color color) {
4976-
this.color = color;
5013+
RGB rgb = color.getRGB();
5014+
this.color = new Color(color.getDevice(), rgb);
5015+
registerForDisposal(this.color);
49775016
}
49785017

49795018
@Override
@@ -5019,6 +5058,7 @@ private class SetForegroundPatternOperation extends Operation {
50195058

50205059
SetForegroundPatternOperation(Pattern pattern) {
50215060
this.pattern = pattern == null ? null : pattern.copy();
5061+
registerForDisposal(this.pattern);
50225062
}
50235063

50245064
@Override
@@ -5604,6 +5644,7 @@ private class SetTransformOperation extends Operation {
56045644
float[] elements = new float[6];
56055645
transform.getElements(elements);
56065646
this.transform = new Transform(device, elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);
5647+
registerForDisposal(this.transform);
56075648
} else {
56085649
this.transform = null;
56095650
}
@@ -5876,8 +5917,36 @@ private void createGcHandle(Drawable drawable, GCData newData, int nativeZoom) {
58765917
}
58775918
}
58785919

5920+
5921+
@Override
5922+
public void dispose() {
5923+
super.dispose();
5924+
disposeOperations();
5925+
}
5926+
5927+
private void disposeOperations() {
5928+
for (Operation op : operations) {
5929+
op.disposeAll();
5930+
}
5931+
operations.clear();
5932+
}
5933+
58795934
private abstract class Operation {
5935+
private final List<Resource> disposables = new ArrayList<>();
58805936
abstract void apply();
5937+
5938+
protected void registerForDisposal(Resource resource) {
5939+
if (resource != null) {
5940+
disposables.add(resource);
5941+
}
5942+
}
5943+
5944+
void disposeAll() {
5945+
for (Resource r : disposables) {
5946+
r.dispose();
5947+
}
5948+
disposables.clear();
5949+
}
58815950
}
58825951
}
58835952

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ public final class Image extends Resource implements Drawable {
139139

140140
private Map<Integer, ImageHandle> zoomLevelToImageHandle = new HashMap<>();
141141

142+
private List<Consumer<Image>> onDisposeListeners;
143+
142144
private Image (Device device, int type, long handle, int nativeZoom) {
143145
super(device);
144146
this.type = type;
@@ -610,10 +612,33 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
610612
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
611613
": ImageDataProvider [" + imageDataProvider + "] returns null ImageData at 100% zoom.");
612614
}
615+
if (Device.strictChecks) {
616+
validateLinearScaling(imageDataProvider);
617+
}
613618
init();
614619
this.device.registerResourceWithZoomSupport(this);
615620
}
616621

622+
private void validateLinearScaling(ImageDataProvider provider) {
623+
final int baseZoom = 100;
624+
final int scaledZoom = 200;
625+
final int scaleFactor = scaledZoom / baseZoom;
626+
ImageData baseImageData = provider.getImageData(baseZoom);
627+
ImageData scaledImageData = provider.getImageData(scaledZoom);
628+
629+
if (scaledImageData == null) {
630+
return;
631+
}
632+
633+
if (scaledImageData.width != scaleFactor * baseImageData.width
634+
|| scaledImageData.height != scaleFactor * baseImageData.height) {
635+
System.err.println(String.format(
636+
"***WARNING: ImageData should be linearly scaled across zooms but size is (%d, %d) at 100%% and (%d, %d) at 200%%.",
637+
baseImageData.width, baseImageData.height, scaledImageData.width, scaledImageData.height));
638+
new Error().printStackTrace(System.err);
639+
}
640+
}
641+
617642
/**
618643
* The provided ImageGcDrawer will be called on demand whenever a new variant of the
619644
* Image for an additional zoom is required. Depending on the OS-specific implementation
@@ -997,6 +1022,21 @@ public static void drawScaled(GC gc, Image original, int width, int height, floa
9971022
return null;
9981023
}
9991024

1025+
void addOnDisposeListener(Consumer<Image> onDisposeListener) {
1026+
if (onDisposeListeners == null) {
1027+
onDisposeListeners = new ArrayList<>();
1028+
}
1029+
onDisposeListeners.add(onDisposeListener);
1030+
}
1031+
1032+
@Override
1033+
public void dispose() {
1034+
if (onDisposeListeners != null) {
1035+
onDisposeListeners.forEach(listener -> listener.accept(this));
1036+
}
1037+
super.dispose();
1038+
}
1039+
10001040
@Override
10011041
void destroy () {
10021042
device.deregisterResourceWithZoomSupport(this);

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5480,7 +5480,7 @@ LRESULT WM_SETCURSOR (long wParam, long lParam) {
54805480
if (control == null) return null;
54815481
Cursor cursor = control.findCursor ();
54825482
if (cursor != null) {
5483-
OS.SetCursor (Cursor.win32_getHandle(cursor, getNativeZoom()));
5483+
OS.SetCursor (Cursor.win32_getHandle(cursor, DPIUtil.getZoomForAutoscaleProperty(getNativeZoom())));
54845484
return LRESULT.ONE;
54855485
}
54865486
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Sash.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,19 +320,21 @@ LRESULT WM_LBUTTONUP (long wParam, long lParam) {
320320
dragging = false;
321321
RECT rect = new RECT ();
322322
OS.GetWindowRect (handle, rect);
323-
int width = rect.right - rect.left;
324-
int height = rect.bottom - rect.top;
323+
int widthInPixels = rect.right - rect.left;
324+
int heightInPixels = rect.bottom - rect.top;
325325

326326
/* The event must be sent because doit flag is used */
327327
Event event = new Event ();
328-
event.setBounds(Win32DPIUtils.pixelToPoint(new Rectangle(lastX, lastY, width, height), getZoom()));
329-
drawBand (lastX, lastY, width, height);
328+
event.setBounds(Win32DPIUtils.pixelToPoint(new Rectangle(lastX, lastY, widthInPixels, heightInPixels), getZoom()));
329+
drawBand (lastX, lastY, widthInPixels, heightInPixels);
330330
sendSelectionEvent (SWT.Selection, event, true);
331331
if (isDisposed ()) return result;
332332
Rectangle bounds = event.getBounds();
333333
if (event.doit) {
334334
if ((style & SWT.SMOOTH) != 0) {
335-
setBounds (bounds.x, bounds.y, width, height);
335+
int xInPixels = Win32DPIUtils.pointToPixel(bounds.x, getZoom());
336+
int yInPixels = Win32DPIUtils.pointToPixel(bounds.y, getZoom());
337+
setBoundsInPixels (xInPixels, yInPixels, widthInPixels, heightInPixels);
336338
// widget could be disposed at this point
337339
}
338340
}

0 commit comments

Comments
 (0)