Skip to content

Commit f0614e2

Browse files
committed
Introduce mechanism for choosing the best available PNG
Introduce Optional
1 parent 6ea3e8d commit f0614e2

File tree

7 files changed

+183
-116
lines changed

7 files changed

+183
-116
lines changed

bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/JSVGRasterizer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ private BufferedImage renderSVG(SVGDocument svgDocument, int zoom) {
102102

103103
private BufferedImage renderSVG(SVGDocument svgDocument, int width, int height) {
104104
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
105-
float scalingFactorX = width / svgDocument.size().width;
106-
float scalingFactorY = height / svgDocument.size().height;
107-
Graphics2D g = configureRenderingOptions(scalingFactorX, scalingFactorY, image);
105+
float widthScalingFactor = width / svgDocument.size().width;
106+
float heightScalingFactor = height / svgDocument.size().height;
107+
Graphics2D g = configureRenderingOptions(widthScalingFactor, heightScalingFactor, image);
108108
svgDocument.render(null, g);
109109
g.dispose();
110110
return image;
@@ -120,10 +120,10 @@ private int calculateTargetHeight(float scalingFactor, FloatSize sourceImageSize
120120
return (int) Math.round(sourceImageHeight * scalingFactor);
121121
}
122122

123-
private Graphics2D configureRenderingOptions(float scalingFactorX, float scalingFactorY, BufferedImage image) {
123+
private Graphics2D configureRenderingOptions(float widthScalingFactor, float heightScalingFactor, BufferedImage image) {
124124
Graphics2D g = image.createGraphics();
125125
g.setRenderingHints(RENDERING_HINTS);
126-
g.scale(scalingFactorX, scalingFactorY);
126+
g.scale(widthScalingFactor, heightScalingFactor);
127127
return g;
128128
}
129129

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ ImageData loadByTargetSize(InputStream stream, int targetWidth, int targetHeight
171171
return image;
172172
}
173173

174-
175174
static boolean canLoadAtZoom(InputStream stream, int fileZoom, int targetZoom) {
176175
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
177176
return FileFormat.canLoadAtZoom(new ElementAtZoom<>(stream, fileZoom), targetZoom);
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
package org.eclipse.swt.graphics;
22

3+
import java.util.*;
4+
35
/**
46
* @since 3.131
57
*/
68
public interface SizeAwareImageDataProvider extends ImageDataProvider {
79

8-
ImageData getImageData(int targetWidth, int targetHeight);
10+
Optional<ImageData> getImageData(int targetWidth, int targetHeight);
911

10-
//TODO If we remove this a lambda is not possible anymore
11-
@Override
12-
default ImageData getImageData(int zoom) {
13-
throw new UnsupportedOperationException();
14-
};
1512
}
Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.eclipse.swt.graphics;
22

3+
import java.util.*;
4+
35
/**
46
* @since 3.131
57
*/
@@ -9,12 +11,6 @@ public interface SizeAwareImageFileNameProvider extends ImageFileNameProvider {
911
* Returns the image file path most suitable for rendering at the given target size.
1012
*
1113
*/
12-
//TODO: Optional
13-
String getImagePath(int targetWidth, int targetHeight);
14+
Optional<String> getImagePath(int targetWidth, int targetHeight);
1415

15-
//TODO zoom erlauben + in Lambdas implementieren.
16-
@Override
17-
default String getImagePath(int zoom) {
18-
throw new UnsupportedOperationException();
19-
};
2016
}

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

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -294,24 +294,6 @@ public static ElementAtZoom<ImageData> validateAndGetImageDataAtZoom(ImageDataPr
294294
return imageDataAtZoom;
295295
}
296296

297-
public static ImageData validateAndGetImageDataAtTargetSize(ImageDataProvider provider, int targetWidth, int targetHeight) {
298-
if (provider == null) {
299-
SWT.error(SWT.ERROR_NULL_ARGUMENT);
300-
}
301-
if (provider instanceof SizeAwareImageDataProvider sizeAwareProvider) {
302-
ImageData imageDataAtTargetSize = getElementAtTargetSize((x, z) -> sizeAwareProvider.getImageData(x, z), targetWidth, targetHeight);
303-
if (imageDataAtTargetSize == null) {
304-
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
305-
": ImageDataProvider [" + provider + "] returns null ImageData at 100% zoom.");
306-
}
307-
return imageDataAtTargetSize;
308-
} else {
309-
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
310-
": ImageDataProvider [" + provider + "] is not capable of loading image data at a specific target size.");
311-
}
312-
return null;
313-
}
314-
315297
/**
316298
* Gets the image file path that are appropriate for the specified zoom level
317299
* together with the zoom level at which the image data are. If there is an
@@ -332,24 +314,6 @@ public static ElementAtZoom<String> validateAndGetImagePathAtZoom(ImageFileNameP
332314
return imagePathAtZoom;
333315
}
334316

335-
public static String validateAndGetImagePathAtTargetSize(ImageFileNameProvider provider, int targetWidth, int targetHeight) {
336-
if (provider == null) {
337-
SWT.error(SWT.ERROR_NULL_ARGUMENT);
338-
}
339-
if (provider instanceof SizeAwareImageFileNameProvider sizeAwareProvider) {
340-
String imagePathAtTargetSize = getElementAtTargetSize((x, z) -> sizeAwareProvider.getImagePath(x, z), targetWidth, targetHeight);
341-
if (imagePathAtTargetSize == null) {
342-
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
343-
": ImageFileNameProvider [" + provider + "] returns null filename at 100% zoom.");
344-
}
345-
return imagePathAtTargetSize;
346-
} else {
347-
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
348-
": ImageFileNameProvider [" + provider + "] is not capable of determining a image path for a specific target size.");
349-
}
350-
return null;
351-
}
352-
353317
private static <T> ElementAtZoom<T> getElementAtZoom(Function<Integer, T> elementForZoomProvider, int zoom) {
354318
T dataAtOriginalZoom = elementForZoomProvider.apply(zoom);
355319
if (dataAtOriginalZoom != null) {
@@ -376,33 +340,6 @@ private static <T> ElementAtZoom<T> getElementAtZoom(Function<Integer, T> elemen
376340
return null;
377341
}
378342

379-
private static <T> T getElementAtTargetSize(BiFunction<Integer, Integer, T> elementForZoomProvider, int targetWidth, int targetHeight) {
380-
T dataAtOriginalZoom = elementForZoomProvider.apply(targetWidth, targetHeight);
381-
if (dataAtOriginalZoom != null) {
382-
return dataAtOriginalZoom;
383-
}
384-
//TODO Dieser Mechanismus sollte bei PNGs in Image liegen und die ImageData entsprechend laden.
385-
if (targetWidth >= 16 && targetWidth <= 24) {
386-
T dataAt150Percent = elementForZoomProvider.apply(24, 24);
387-
if (dataAt150Percent != null) {
388-
return dataAt150Percent;
389-
}
390-
}
391-
if (targetWidth > 16) {
392-
T dataAt200Percent = elementForZoomProvider.apply(32, 32);
393-
if (dataAt200Percent != null) {
394-
return dataAt200Percent;
395-
}
396-
}
397-
if (targetWidth != 16) {
398-
T dataAt100Percent = elementForZoomProvider.apply(16, 16);
399-
if (dataAt100Percent != null) {
400-
return dataAt100Percent;
401-
}
402-
}
403-
return null;
404-
}
405-
406343
public static int getNativeDeviceZoom() {
407344
return nativeDeviceZoom;
408345
}

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

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,11 +2396,69 @@ protected ElementAtZoom<ImageData> loadImageData(int zoom) {
23962396

23972397
@Override
23982398
protected ImageData loadImageData(int targetWidth, int targetHeight) {
2399-
String fileForTargetSize = DPIUtil.validateAndGetImagePathAtTargetSize(provider, targetWidth, targetHeight);
2400-
ImageData imageDataAtZoom = ImageDataLoader.loadByTargetSize(fileForTargetSize, targetWidth, targetWidth);
2399+
Optional<String> fileForTargetSize = validateAndGetImagePathAtTargetSize(provider, targetWidth, targetHeight);
2400+
ImageData imageDataAtZoom = ImageDataLoader.loadByTargetSize(fileForTargetSize.get(), targetWidth, targetWidth);
24012401
return imageDataAtZoom;
24022402
}
24032403

2404+
private Optional<String> validateAndGetImagePathAtTargetSize(ImageFileNameProvider provider, int targetWidth, int targetHeight) {
2405+
if (provider == null) {
2406+
SWT.error(SWT.ERROR_NULL_ARGUMENT);
2407+
}
2408+
2409+
if (provider instanceof SizeAwareImageFileNameProvider sizeAwareProvider) {
2410+
Optional<String> imagePathAtTargetSize = getElementAtTargetSize(sizeAwareProvider::getImagePath,
2411+
targetWidth, targetHeight);
2412+
2413+
if (imagePathAtTargetSize.isEmpty()) {
2414+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
2415+
": ImageFileNameProvider [" + provider + "] returns no filename at 100% zoom.");
2416+
}
2417+
2418+
return imagePathAtTargetSize;
2419+
} else {
2420+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, ": ImageFileNameProvider [" + provider
2421+
+ "] is not capable of determining an image path for a specific target size.");
2422+
return Optional.empty();
2423+
}
2424+
}
2425+
2426+
private Optional<String> getElementAtTargetSize(BiFunction<Integer, Integer, Optional<String>> elementForZoomProvider,
2427+
int targetWidth, int targetHeight) {
2428+
2429+
Rectangle originalSize = getBounds(100);
2430+
int originalWidth = originalSize.width;
2431+
int originalHeight = originalSize.height;
2432+
2433+
Optional<String> dataAtOriginalZoom = elementForZoomProvider.apply(targetWidth, targetHeight);
2434+
if (dataAtOriginalZoom != null) {
2435+
ImageData data = ImageDataLoader.loadByTargetSize(dataAtOriginalZoom.get(), targetWidth, targetWidth);
2436+
if (data.width == targetWidth && data.height == targetHeight) {
2437+
return dataAtOriginalZoom;
2438+
}
2439+
}
2440+
2441+
if (targetWidth >= originalWidth && targetWidth <= originalWidth * 1.5) {
2442+
Optional<String> dataAt150Percent = elementForZoomProvider.apply((int) Math.round(originalWidth * 1.5), (int) Math.round(originalHeight * 1.5));
2443+
if (dataAt150Percent != null) {
2444+
return dataAt150Percent;
2445+
}
2446+
}
2447+
if (targetWidth > originalWidth) {
2448+
Optional<String> dataAt200Percent = elementForZoomProvider.apply(originalWidth * 2, originalHeight * 2);
2449+
if (dataAt200Percent != null) {
2450+
return dataAt200Percent;
2451+
}
2452+
}
2453+
if (targetWidth != originalWidth) {
2454+
Optional<String> dataAt100Percent = elementForZoomProvider.apply(originalWidth, originalHeight);
2455+
if (dataAt100Percent != null) {
2456+
return dataAt100Percent;
2457+
}
2458+
}
2459+
return null;
2460+
}
2461+
24042462
@Override
24052463
public int hashCode() {
24062464
return Objects.hash(provider, styleFlag, transparentPixel);
@@ -2622,9 +2680,60 @@ protected ElementAtZoom<ImageData> loadImageData(int zoom) {
26222680

26232681
@Override
26242682
protected ImageData loadImageData(int targetWidth, int targetHeight) {
2625-
return DPIUtil.validateAndGetImageDataAtTargetSize(provider, targetWidth, targetHeight);
2683+
return validateAndGetImageDataAtTargetSize(targetWidth, targetHeight).get();
2684+
}
2685+
2686+
private Optional<ImageData> validateAndGetImageDataAtTargetSize(int targetWidth, int targetHeight) {
2687+
if (provider == null) {
2688+
SWT.error(SWT.ERROR_NULL_ARGUMENT);
2689+
}
2690+
Optional<ImageData> imageDataAtTargetSize = getElementAtTargetSize((x, z) -> ((SizeAwareImageDataProvider) provider).getImageData(x, z), targetWidth, targetHeight);
2691+
if (imageDataAtTargetSize == null) {
2692+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
2693+
": ImageDataProvider [" + provider + "] returns null ImageData at 100% zoom.");
2694+
}
2695+
return imageDataAtTargetSize;
2696+
}
2697+
2698+
private Optional<ImageData> getElementAtTargetSize(BiFunction<Integer, Integer, Optional<ImageData>> elementForZoomProvider, int targetWidth, int targetHeight) {
2699+
Rectangle originalSize = getBounds(100);
2700+
int originalWidth = originalSize.width;
2701+
int originalHeight = originalSize.height;
2702+
2703+
Optional<ImageData> dataAtOriginalZoom = elementForZoomProvider.apply(targetWidth, targetHeight);
2704+
if (dataAtOriginalZoom.isPresent()) {
2705+
ImageData imageData = dataAtOriginalZoom.get();
2706+
if (imageData.width == targetWidth && imageData.height == targetHeight) {
2707+
return dataAtOriginalZoom;
2708+
}
2709+
}
2710+
2711+
if (targetWidth >= originalWidth && targetWidth <= originalWidth * 1.5) {
2712+
Optional<ImageData> dataAt150Percent = elementForZoomProvider.apply((int) Math.round(originalWidth * 1.5),
2713+
(int) Math.round(originalHeight * 1.5));
2714+
if (dataAt150Percent.isPresent()) {
2715+
return dataAt150Percent;
2716+
}
2717+
}
2718+
2719+
if (targetWidth > originalWidth) {
2720+
Optional<ImageData> dataAt200Percent = elementForZoomProvider.apply(originalWidth * 2, originalHeight * 2);
2721+
if (dataAt200Percent.isPresent()) {
2722+
return dataAt200Percent;
2723+
}
2724+
}
2725+
2726+
if (targetWidth != originalWidth) {
2727+
Optional<ImageData> dataAt100Percent = elementForZoomProvider.apply(originalWidth, originalHeight);
2728+
if (dataAt100Percent.isPresent()) {
2729+
return dataAt100Percent;
2730+
}
2731+
}
2732+
2733+
return Optional.empty();
26262734
}
26272735

2736+
26282737
@Override
26292738
ImageDataProviderWrapper createCopy(Image image) {
26302739
return image.new ImageDataProviderWrapper(provider);

0 commit comments

Comments
 (0)