1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.svg.edit.client.utils;
19
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import com.google.gwt.canvas.client.Canvas;
24 import com.google.gwt.canvas.dom.client.Context2d;
25 import com.google.gwt.dom.client.ImageElement;
26 import com.google.gwt.resources.client.ImageResource;
27 import com.google.gwt.user.client.ui.AbstractImagePrototype;
28
29
30
31
32
33
34
35
36 public class DecoratedImageCache {
37
38
39
40 public enum HAlign {
41 LEFT,
42 CENTER,
43 RIGHT
44 };
45
46
47
48 public enum VAlign {
49 TOP,
50 CENTER,
51 BOTTOM
52 };
53
54
55
56 protected class StoreKey {
57 private HAlign halign;
58 private VAlign valign;
59 private ImageResource decoration;
60 public StoreKey(ImageResource decoration, HAlign halign, VAlign valign) {
61 this.decoration = decoration;
62 this.halign = halign;
63 this.valign = valign;
64 }
65 @Override
66 public String toString() {
67 StringBuilder builder = new StringBuilder();
68 builder.append("{");
69 if (decoration != null) {
70 builder.append(decoration.getName());
71 } else {
72 builder.append(decoration);
73 }
74 builder.append("; ");
75 builder.append(halign);
76 builder.append("; ");
77 builder.append(valign);
78 builder.append("}");
79 return builder.toString();
80 }
81 @Override
82 public boolean equals(Object o) {
83 if (o instanceof StoreKey) {
84 StoreKey storeKey = (StoreKey)o;
85 return halign == storeKey.halign
86 && valign == storeKey.valign
87 && decoration == storeKey.decoration;
88 }
89 return false;
90 }
91 @Override
92 public int hashCode() {
93 return halign.hashCode() + 13 * valign.hashCode() + 37 * (decoration == null ? 0 : decoration.hashCode());
94 }
95 }
96
97
98
99
100 protected Canvas canvas;
101
102
103
104 protected Context2d ctx;
105
106
107
108 protected Map<ImageResource, SimpleImage> resourceToImage;
109
110
111
112 protected Map<ImageResource,Map<StoreKey, AbstractImagePrototype>> imageToDecorations;
113
114
115
116
117
118 public DecoratedImageCache(Map<ImageResource, SimpleImage> resourceToImage) {
119 this.resourceToImage = resourceToImage;
120 imageToDecorations = new HashMap<ImageResource, Map<StoreKey, AbstractImagePrototype>>();
121 canvas = Canvas.createIfSupported();
122 ctx = canvas.getContext2d();
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public AbstractImagePrototype getImageWithDecoration(ImageResource base, ImageResource decoration, HAlign halign, VAlign valign) {
139 Map<StoreKey, AbstractImagePrototype> decorationToImage = imageToDecorations.get(base);
140 if (decorationToImage == null) {
141 decorationToImage = new HashMap<StoreKey, AbstractImagePrototype>();
142 imageToDecorations.put(base, decorationToImage);
143 }
144 StoreKey key = new StoreKey(decoration, halign, valign);
145 AbstractImagePrototype image = decorationToImage.get(key);
146 if (image == null) {
147 if (decoration != null) {
148 SimpleImage baseImg = resourceToImage.get(base);
149 if (baseImg == null) {
150 throw new IllegalArgumentException();
151 }
152 SimpleImage decorationImg = resourceToImage.get(decoration);
153 if (decorationImg == null) {
154 throw new IllegalArgumentException();
155 }
156 image = decorate(baseImg, decorationImg, halign, valign);
157 } else {
158 image = AbstractImagePrototype.create(base);
159 }
160 decorationToImage.put(key, image);
161 }
162 return image;
163 }
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 public AbstractImagePrototype decorate(SimpleImage base, SimpleImage decoration, HAlign halign, VAlign valign) {
179 ctx.clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
180 int baseWidth = base.getWidth();
181 int baseHeight = base.getHeight();
182 int decWidth = decoration.getWidth();
183 int decHeight = decoration.getHeight();
184 canvas.setCoordinateSpaceWidth(baseWidth);
185 canvas.setCoordinateSpaceHeight(baseHeight);
186 int x = 0;
187 switch(halign) {
188 case LEFT:
189 break;
190 case CENTER:
191 x = (baseWidth - decWidth) / 2;
192 break;
193 case RIGHT:
194 x = baseWidth - decWidth;
195 break;
196 }
197 int y = 0;
198 switch(valign) {
199 case TOP:
200 break;
201 case CENTER:
202 y = (baseHeight - decHeight) / 2;
203 break;
204 case BOTTOM:
205 y = baseHeight - decHeight;
206 break;
207 }
208 ctx.drawImage(base.getElement().<ImageElement>cast(), 0, 0);
209 ctx.drawImage(decoration.getElement().<ImageElement>cast(), x, y);
210 return new SimpleImagePrototype(canvas.toDataUrl(), baseWidth, baseHeight);
211 }
212 }