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

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

sonar - squid:S00100 - Method names should comply with a naming convention

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