1 package org
.argeo
.cms
.swt
.osgi
;
3 import java
.io
.ByteArrayInputStream
;
4 import java
.io
.ByteArrayOutputStream
;
5 import java
.io
.IOException
;
6 import java
.io
.InputStream
;
7 import java
.lang
.System
.Logger
;
8 import java
.lang
.System
.Logger
.Level
;
9 import java
.util
.Collections
;
10 import java
.util
.HashMap
;
13 import org
.apache
.batik
.transcoder
.TranscoderException
;
14 import org
.apache
.batik
.transcoder
.TranscoderInput
;
15 import org
.apache
.batik
.transcoder
.TranscoderOutput
;
16 import org
.apache
.batik
.transcoder
.image
.ImageTranscoder
;
17 import org
.apache
.batik
.transcoder
.image
.PNGTranscoder
;
18 import org
.eclipse
.swt
.graphics
.Image
;
19 import org
.eclipse
.swt
.graphics
.ImageData
;
20 import org
.eclipse
.swt
.widgets
.Display
;
21 import org
.osgi
.framework
.BundleContext
;
23 /** Theme which can dynamically create icons from SVG data. */
24 public class BundleSvgTheme
extends BundleCmsSwtTheme
{
25 private final static Logger logger
= System
.getLogger(BundleSvgTheme
.class.getName());
27 private Map
<String
, Map
<Integer
, Image
>> imageCache
= Collections
.synchronizedMap(new HashMap
<>());
29 private Map
<Integer
, ImageTranscoder
> transcoders
= Collections
.synchronizedMap(new HashMap
<>());
32 public Image
getIcon(String name
, Integer preferredSize
) {
33 String path
= "icons/types/svg/" + name
+ ".svg";
34 return createImageFromSvg(path
, preferredSize
);
37 protected Image
createImageFromSvg(String path
, Integer preferredSize
) {
39 if (imageCache
.containsKey(path
)) {
40 image
= imageCache
.get(path
).get(preferredSize
);
44 ImageData imageData
= loadFromSvg(path
, preferredSize
);
45 image
= new Image(Display
.getDefault(), imageData
);
46 if (!imageCache
.containsKey(path
))
47 imageCache
.put(path
, Collections
.synchronizedMap(new HashMap
<>()));
48 imageCache
.get(path
).put(preferredSize
, image
);
52 protected ImageData
loadFromSvg(String path
, int size
) {
53 ImageTranscoder transcoder
= null;
55 transcoder
= transcoders
.get(size
);
56 if (transcoder
== null) {
57 transcoder
= new PNGTranscoder();
58 transcoder
.addTranscodingHint(PNGTranscoder
.KEY_WIDTH
, (float) size
);
59 transcoder
.addTranscodingHint(PNGTranscoder
.KEY_HEIGHT
, (float) size
);
60 transcoders
.put(size
, transcoder
);
64 try (InputStream in
= getResourceAsStream(path
); ByteArrayOutputStream out
= new ByteArrayOutputStream();) {
66 throw new IllegalArgumentException(path
+ " not found");
67 TranscoderInput input
= new TranscoderInput(in
);
68 TranscoderOutput output
= new TranscoderOutput(out
);
69 transcoder
.transcode(input
, output
);
70 try (InputStream imageIn
= new ByteArrayInputStream(out
.toByteArray())) {
71 imageData
= new ImageData(imageIn
);
73 logger
.log(Level
.DEBUG
, () -> "Generated " + size
+ "x" + size
+ " PNG icon from " + path
);
74 } catch (IOException
| TranscoderException e
) {
75 throw new RuntimeException("Cannot transcode SVG " + path
, e
);
82 public void init(BundleContext bundleContext
, Map
<String
, String
> properties
) {
83 super.init(bundleContext
, properties
);
86 // paths: for (String p : getImagesPaths()) {
87 // if (!p.endsWith(".svg"))
89 // createImageFromSvg(p, getDefaultIconSize());
94 public void destroy(BundleContext bundleContext
, Map
<String
, String
> properties
) {
95 Display display
= Display
.getDefault();
97 for (String path
: imageCache
.keySet()) {
98 for (Image image
: imageCache
.get(path
).values()) {
99 display
.syncExec(() -> image
.dispose());
102 super.destroy(bundleContext
, properties
);