Skip to content

Commit 26f1fe9

Browse files
committed
Enable Loading of SVGs in arbitrary sized for ImageDataProvider
1 parent 1e6e9a9 commit 26f1fe9

File tree

3 files changed

+77
-36
lines changed

3 files changed

+77
-36
lines changed

bundles/org.eclipse.jface/.settings/org.eclipse.jdt.core.prefs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ org.eclipse.jdt.core.compiler.problem.deadCode=warning
4646
org.eclipse.jdt.core.compiler.problem.deprecation=warning
4747
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
4848
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
49-
org.eclipse.jdt.core.compiler.problem.discouragedReference=error
49+
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
5050
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
5151
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
5252
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

bundles/org.eclipse.jface/src/org/eclipse/jface/resource/FileImageDescriptor.java

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@
3232
import org.eclipse.core.runtime.IStatus;
3333
import org.eclipse.core.runtime.Status;
3434
import org.eclipse.jface.internal.InternalPolicy;
35+
import org.eclipse.jface.resource.URLImageDescriptor.SourceAtZoom;
3536
import org.eclipse.jface.util.Policy;
3637
import org.eclipse.swt.SWT;
3738
import org.eclipse.swt.SWTException;
3839
import org.eclipse.swt.graphics.Device;
3940
import org.eclipse.swt.graphics.Image;
4041
import org.eclipse.swt.graphics.ImageData;
4142
import org.eclipse.swt.graphics.ImageFileNameProvider;
43+
import org.eclipse.swt.graphics.ImageLoader;
44+
import org.eclipse.swt.internal.DPIUtil.ElementAtZoom;
45+
import org.eclipse.swt.internal.NativeImageLoader;
4246

4347
/**
4448
* An image descriptor that loads its image information from a file.
@@ -53,16 +57,16 @@ public String getImagePath(int zoom) {
5357
if (zoom == 100) {
5458
return getFilePath(name, logIOException);
5559
}
56-
String xName = getxName(name, zoom);
60+
SourceAtZoom<String> xName = getxName(name, zoom);
5761
if (xName != null) {
58-
String xResult = getFilePath(xName, logIOException);
62+
String xResult = getFilePath(xName.source(), logIOException);
5963
if (xResult != null) {
6064
return xResult;
6165
}
6266
}
63-
String xPath = getxPath(name, zoom);
67+
SourceAtZoom<String> xPath = getxPath(name, zoom);
6468
if (xPath != null) {
65-
String xResult = getFilePath(xPath, logIOException);
69+
String xResult = getFilePath(xPath.source(), logIOException);
6670
if (xResult != null) {
6771
return xResult;
6872
}
@@ -121,12 +125,15 @@ public boolean equals(Object o) {
121125
* {@link ImageDescriptor#createImage(boolean, Device)} as of version
122126
* 3.4 so that the SWT OS optimized loading can be used.
123127
*/
128+
@SuppressWarnings("restriction")
124129
@Override
125130
public ImageData getImageData(int zoom) {
126-
InputStream in = getStream(zoom);
127-
if (in != null) {
128-
try (BufferedInputStream stream = new BufferedInputStream(in)) {
129-
return new ImageData(stream);
131+
SourceAtZoom<InputStream> inputStreamAtZoom = getStream(zoom);
132+
if (inputStreamAtZoom != null) {
133+
try (BufferedInputStream stream = new BufferedInputStream(inputStreamAtZoom.source())) {
134+
ElementAtZoom<ImageData> imageData = NativeImageLoader
135+
.load(new ElementAtZoom<>(stream, inputStreamAtZoom.zoom()), new ImageLoader(), zoom).get(0);
136+
return imageData.element();
130137
} catch (SWTException e) {
131138
if (e.code != SWT.ERROR_INVALID_IMAGE) {
132139
throw e;
@@ -147,17 +154,17 @@ public ImageData getImageData(int zoom) {
147154
* @return the buffered stream on the file or <code>null</code> if the
148155
* file cannot be found
149156
*/
150-
private InputStream getStream(int zoom) {
157+
private SourceAtZoom<InputStream> getStream(int zoom) {
151158
if (zoom == 100) {
152-
return getStream(name);
159+
return getStream(new SourceAtZoom<>(name, 100));
153160
}
154161

155-
InputStream xstream = getStream(getxName(name, zoom));
162+
SourceAtZoom<InputStream> xstream = getStream(getxName(name, zoom));
156163
if (xstream != null) {
157164
return xstream;
158165
}
159166

160-
InputStream xpath = getStream(getxPath(name, zoom));
167+
SourceAtZoom<InputStream> xpath = getStream(getxPath(name, zoom));
161168
if (xpath != null) {
162169
return xpath;
163170
}
@@ -173,21 +180,22 @@ private InputStream getStream(int zoom) {
173180
* @return an {@link InputStream} to read from, or <code>null</code> if fileName
174181
* does not denotes an existing resource
175182
*/
176-
private InputStream getStream(String fileName) {
183+
private SourceAtZoom<InputStream> getStream(SourceAtZoom<String> fileName) {
177184
if (fileName != null) {
185+
// TODO DO we need to close these?
178186
if (location != null) {
179-
return location.getResourceAsStream(fileName);
187+
return new SourceAtZoom<>(location.getResourceAsStream(fileName.source()), fileName.zoom());
180188
}
181189
try {
182-
return new FileInputStream(fileName);
190+
return new SourceAtZoom<>(new FileInputStream(fileName.source()), fileName.zoom());
183191
} catch (FileNotFoundException e) {
184192
return null;
185193
}
186194
}
187195
return null;
188196
}
189197

190-
static String getxPath(String name, int zoom) {
198+
static SourceAtZoom<String> getxPath(String name, int zoom) {
191199
Matcher matcher = XPATH_PATTERN.matcher(name);
192200
if (matcher.find()) {
193201
try {
@@ -197,24 +205,29 @@ static String getxPath(String name, int zoom) {
197205
int desiredHeight = Math.round((zoom / 100f) * currentHeight);
198206
String lead = name.substring(0, matcher.start(1));
199207
String tail = name.substring(matcher.end(2));
200-
return lead + desiredWidth + "x" + desiredHeight + tail; //$NON-NLS-1$
208+
String xPath = lead + desiredWidth + "x" + desiredHeight + tail; //$NON-NLS-1$
209+
return new SourceAtZoom<>(xPath, desiredHeight);
201210
} catch (RuntimeException e) {
202211
// should never happen but if then we can't use the alternative name...
203212
}
204213
}
205214
return null;
206215
}
207216

208-
static String getxName(String name, int zoom) {
217+
static SourceAtZoom<String> getxName(String name, int zoom) {
209218
int dot = name.lastIndexOf('.');
210219
if (dot != -1 && (zoom == 150 || zoom == 200)) {
211220
String lead = name.substring(0, dot);
212221
String tail = name.substring(dot);
213222
if (InternalPolicy.DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x_PNG_FOR_GIF && ".gif".equalsIgnoreCase(tail)) { //$NON-NLS-1$
214223
tail = ".png"; //$NON-NLS-1$
215224
}
216-
String x = zoom == 150 ? "@1.5x" : "@2x"; //$NON-NLS-1$ //$NON-NLS-2$
217-
return lead + x + tail;
225+
String x = "@2x";//$NON-NLS-1$
226+
if (zoom == 150) {
227+
x = "@1.5x"; //$NON-NLS-1$
228+
return new SourceAtZoom<>(lead + x + tail, 150);
229+
}
230+
return new SourceAtZoom<>(lead + x + tail, 200);
218231
}
219232
return null;
220233
}

bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
import org.eclipse.swt.graphics.ImageData;
4040
import org.eclipse.swt.graphics.ImageDataProvider;
4141
import org.eclipse.swt.graphics.ImageFileNameProvider;
42+
import org.eclipse.swt.graphics.ImageLoader;
43+
import org.eclipse.swt.internal.DPIUtil.ElementAtZoom;
44+
import org.eclipse.swt.internal.NativeImageLoader;
4245

4346
/**
4447
* An ImageDescriptor that gets its information from a URL. This class is not
@@ -63,16 +66,16 @@ public String getImagePath(int zoom) {
6366
if (zoom == 100) {
6467
return getFilePath(tempURL, logIOException);
6568
}
66-
URL xUrl = getxURL(tempURL, zoom);
69+
SourceAtZoom<URL> xUrl = getxURL(tempURL, zoom);
6770
if (xUrl != null) {
68-
String xResult = getFilePath(xUrl, logIOException);
71+
String xResult = getFilePath(xUrl.source(), logIOException);
6972
if (xResult != null) {
7073
return xResult;
7174
}
7275
}
73-
String xpath = FileImageDescriptor.getxPath(url, zoom);
76+
SourceAtZoom<String> xpath = FileImageDescriptor.getxPath(url, zoom);
7477
if (xpath != null) {
75-
URL xPathUrl = getURL(xpath);
78+
URL xPathUrl = getURL(xpath.source());
7679
if (xPathUrl != null) {
7780
return getFilePath(xPathUrl, logIOException);
7881
}
@@ -83,6 +86,23 @@ public String getImagePath(int zoom) {
8386

8487
}
8588

89+
/**
90+
* Represents an element, such as InputStream, Path or URL, at a specific zoom
91+
* level.
92+
*
93+
* @param <T> type of the element to be presented, e.g., {@link InputStream}
94+
*/
95+
record SourceAtZoom<T>(T source, int zoom) {
96+
public SourceAtZoom {
97+
if (source == null) {
98+
SWT.error(SWT.ERROR_NULL_ARGUMENT);
99+
}
100+
if (zoom <= 0) {
101+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
102+
}
103+
}
104+
}
105+
86106
private static class URLImageDataProvider implements ImageDataProvider {
87107

88108
private final String url;
@@ -128,7 +148,9 @@ public boolean equals(Object o) {
128148
@Deprecated
129149
@Override
130150
public ImageData getImageData() {
131-
return getImageData(getURL(url));
151+
// TODO What to do with this? targetZoom and fileZoom is unknown.
152+
// the first can be extracted from the url but the latter?
153+
return getImageData(getURL(url), 100, 100);
132154
}
133155

134156
@Override
@@ -140,31 +162,34 @@ private static ImageData getImageData(String url, int zoom) {
140162
URL tempURL = getURL(url);
141163
if (tempURL != null) {
142164
if (zoom == 100) {
143-
return getImageData(tempURL);
165+
return getImageData(tempURL, 100, zoom);
144166
}
145-
URL xUrl = getxURL(tempURL, zoom);
167+
SourceAtZoom<URL> xUrl = getxURL(tempURL, zoom);
146168
if (xUrl != null) {
147-
ImageData xdata = getImageData(xUrl);
169+
ImageData xdata = getImageData(xUrl.source(), xUrl.zoom(), zoom);
148170
if (xdata != null) {
149171
return xdata;
150172
}
151173
}
152-
String xpath = FileImageDescriptor.getxPath(url, zoom);
174+
SourceAtZoom<String> xpath = FileImageDescriptor.getxPath(url, zoom);
153175
if (xpath != null) {
154-
URL xPathUrl = getURL(xpath);
176+
URL xPathUrl = getURL(xpath.source());
155177
if (xPathUrl != null) {
156-
return getImageData(xPathUrl);
178+
return getImageData(xPathUrl, xpath.zoom(), zoom);
157179
}
158180
}
159181
}
160182
return null;
161183
}
162184

163-
private static ImageData getImageData(URL url) {
185+
@SuppressWarnings("restriction")
186+
private static ImageData getImageData(URL url, int fileZoom, int targetZoom) {
164187
ImageData result = null;
165188
try (InputStream in = getStream(url)) {
166189
if (in != null) {
167-
result = new ImageData(in);
190+
result = NativeImageLoader
191+
.load(new ElementAtZoom<>(in, fileZoom), new ImageLoader(), targetZoom).get(0)
192+
.element();
168193
}
169194
} catch (SWTException e) {
170195
if (e.code != SWT.ERROR_INVALID_IMAGE) {
@@ -227,7 +252,7 @@ public String toString() {
227252
return "URLImageDescriptor(" + url + ")"; //$NON-NLS-1$ //$NON-NLS-2$
228253
}
229254

230-
private static URL getxURL(URL url, int zoom) {
255+
private static SourceAtZoom<URL> getxURL(URL url, int zoom) {
231256
String path = url.getPath();
232257
int dot = path.lastIndexOf('.');
233258
if (dot != -1 && (zoom == 150 || zoom == 200)) {
@@ -242,7 +267,10 @@ private static URL getxURL(URL url, int zoom) {
242267
if (url.getQuery() != null) {
243268
file += '?' + url.getQuery();
244269
}
245-
return new URL(url.getProtocol(), url.getHost(), url.getPort(), file);
270+
if (x == "@1.5x") { //$NON-NLS-1$
271+
return new SourceAtZoom<>(new URL(url.getProtocol(), url.getHost(), url.getPort(), file), 150);
272+
}
273+
return new SourceAtZoom<>(new URL(url.getProtocol(), url.getHost(), url.getPort(), file), 200);
246274
} catch (MalformedURLException e) {
247275
Policy.getLog().log(new Status(IStatus.ERROR, Policy.JFACE, e.getLocalizedMessage(), e));
248276
}

0 commit comments

Comments
 (0)