source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/MapImage.java@ 8958

Last change on this file since 8958 was 8958, checked in by Don-vip, 8 years ago

update javadoc + checkstyle fix + update presets links

  • Property svn:eol-style set to native
File size: 7.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import java.awt.Graphics;
5import java.awt.Image;
6import java.awt.Rectangle;
7import java.awt.image.BufferedImage;
8import java.util.Objects;
9
10import javax.swing.ImageIcon;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.BoxProvider;
14import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.BoxProviderResult;
15import org.openstreetmap.josm.gui.util.GuiHelper;
16import org.openstreetmap.josm.tools.ImageProvider;
17import org.openstreetmap.josm.tools.ImageProvider.ImageCallback;
18import org.openstreetmap.josm.tools.Utils;
19
20/**
21 * An image that will be displayed on the map.
22 */
23public class MapImage {
24
25 private static final int MAX_SIZE = 48;
26
27 /**
28 * ImageIcon can change while the image is loading.
29 */
30 private BufferedImage img;
31
32 public int alpha = 255;
33 public String name;
34 public StyleSource source;
35 public boolean autoRescale;
36 public int width = -1;
37 public int height = -1;
38 public int offsetX;
39 public int offsetY;
40
41 private boolean temporary;
42 private BufferedImage disabledImgCache;
43
44 public MapImage(String name, StyleSource source) {
45 this(name, source, true);
46 }
47
48 public MapImage(String name, StyleSource source, boolean autoRescale) {
49 this.name = name;
50 this.source = source;
51 this.autoRescale = autoRescale;
52 }
53
54 /**
55 * Get the image associated with this MapImage object.
56 *
57 * @param disabled {@code} true to request disabled version, {@code false} for the standard version
58 * @return the image
59 */
60 public BufferedImage getImage(boolean disabled) {
61 if (disabled) {
62 return getDisabled();
63 } else {
64 return getImage();
65 }
66 }
67
68 private BufferedImage getDisabled() {
69 if (disabledImgCache != null)
70 return disabledImgCache;
71 if (img == null)
72 getImage(); // fix #7498 ?
73 Image disImg = GuiHelper.getDisabledImage(img);
74 if (disImg instanceof BufferedImage) {
75 disabledImgCache = (BufferedImage) disImg;
76 } else {
77 disabledImgCache = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
78 Graphics g = disabledImgCache.getGraphics();
79 g.drawImage(disImg, 0, 0, null);
80 g.dispose();
81 }
82 return disabledImgCache;
83 }
84
85 private BufferedImage getImage() {
86 if (img != null)
87 return img;
88 temporary = false;
89 new ImageProvider(name)
90 .setDirs(MapPaintStyles.getIconSourceDirs(source))
91 .setId("mappaint."+source.getPrefName())
92 .setArchive(source.zipIcons)
93 .setInArchiveDir(source.getZipEntryDirName())
94 .setWidth(width)
95 .setHeight(height)
96 .setOptional(true)
97 .getInBackground(new ImageCallback() {
98 @Override
99 public void finished(ImageIcon result) {
100 synchronized (MapImage.this) {
101 if (result == null) {
102 ImageIcon noIcon = MapPaintStyles.getNoIcon_Icon(source);
103 img = noIcon == null ? null : (BufferedImage) noIcon.getImage();
104 } else {
105 img = (BufferedImage) rescale(result.getImage());
106 }
107 if (temporary) {
108 disabledImgCache = null;
109 Main.map.mapView.preferenceChanged(null); // otherwise repaint is ignored, because layer hasn't changed
110 Main.map.mapView.repaint();
111 }
112 temporary = false;
113 }
114 }
115 }
116 );
117 synchronized (this) {
118 if (img == null) {
119 img = (BufferedImage) ImageProvider.get("clock").getImage();
120 temporary = true;
121 }
122 }
123 return img;
124 }
125
126 public int getWidth() {
127 return getImage().getWidth(null);
128 }
129
130 public int getHeight() {
131 return getImage().getHeight(null);
132 }
133
134 public float getAlphaFloat() {
135 return Utils.color_int2float(alpha);
136 }
137
138 /**
139 * Determines if image is not completely loaded and {@code getImage()} returns a temporary image.
140 * @return {@code true} if image is not completely loaded and getImage() returns a temporary image
141 */
142 public boolean isTemporary() {
143 return temporary;
144 }
145
146 protected class MapImageBoxProvider implements BoxProvider {
147 @Override
148 public BoxProviderResult get() {
149 return new BoxProviderResult(box(), temporary);
150 }
151
152 private Rectangle box() {
153 int w = getWidth(), h = getHeight();
154 if (mustRescale(getImage())) {
155 w = 16;
156 h = 16;
157 }
158 return new Rectangle(-w/2, -h/2, w, h);
159 }
160
161 private MapImage getParent() {
162 return MapImage.this;
163 }
164
165 @Override
166 public int hashCode() {
167 return MapImage.this.hashCode();
168 }
169
170 @Override
171 public boolean equals(Object obj) {
172 if (!(obj instanceof BoxProvider))
173 return false;
174 if (obj instanceof MapImageBoxProvider) {
175 MapImageBoxProvider other = (MapImageBoxProvider) obj;
176 return MapImage.this.equals(other.getParent());
177 } else if (temporary) {
178 return false;
179 } else {
180 final BoxProvider other = (BoxProvider) obj;
181 BoxProviderResult resultOther = other.get();
182 if (resultOther.isTemporary()) return false;
183 return box().equals(resultOther.getBox());
184 }
185 }
186 }
187
188 public BoxProvider getBoxProvider() {
189 return new MapImageBoxProvider();
190 }
191
192 /**
193 * Rescale excessively large images.
194 * @param image the unscaled image
195 * @return The scaled down version to 16x16 pixels if the image height and width exceeds 48 pixels and no size has been explicitely specified
196 */
197 private Image rescale(Image image) {
198 if (image == null) return null;
199 // Scale down large (.svg) images to 16x16 pixels if no size is explicitely specified
200 if (mustRescale(image)) {
201 return ImageProvider.createBoundedImage(image, 16);
202 } else {
203 return image;
204 }
205 }
206
207 private boolean mustRescale(Image image) {
208 return autoRescale && width == -1 && image.getWidth(null) > MAX_SIZE
209 && height == -1 && image.getHeight(null) > MAX_SIZE;
210 }
211
212 @Override
213 public boolean equals(Object obj) {
214 if (obj == null || getClass() != obj.getClass())
215 return false;
216 final MapImage other = (MapImage) obj;
217 // img changes when image is fully loaded and can't be used for equality check.
218 return alpha == other.alpha &&
219 Objects.equals(name, other.name) &&
220 Objects.equals(source, other.source) &&
221 autoRescale == other.autoRescale &&
222 width == other.width &&
223 height == other.height;
224 }
225
226 @Override
227 public int hashCode() {
228 int hash = 7;
229 hash = 67 * hash + alpha;
230 hash = 67 * hash + name.hashCode();
231 hash = 67 * hash + source.hashCode();
232 hash = 67 * hash + (autoRescale ? 1 : 0);
233 hash = 67 * hash + width;
234 hash = 67 * hash + height;
235 return hash;
236 }
237
238 @Override
239 public String toString() {
240 return name;
241 }
242}
Note: See TracBrowser for help on using the repository browser.