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

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

fix #9286 - fix rendering of names for rescaled SVG icons

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