Changeset 3880 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2011-02-10T00:05:18+01:00 (14 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
r3879 r3880 14 14 import java.awt.TexturePaint; 15 15 import java.awt.font.FontRenderContext; 16 import java.awt.font.GlyphVector; 16 17 import java.awt.font.LineMetrics; 18 import java.awt.geom.AffineTransform; 17 19 import java.awt.geom.GeneralPath; 18 20 import java.awt.geom.Rectangle2D; … … 37 39 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.HorizontalTextAlignment; 38 40 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.Symbol; 39 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle. TextElement;41 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.NodeTextElement; 40 42 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.VerticalTextAlignment; 43 import org.openstreetmap.josm.gui.mappaint.TextElement; 41 44 import org.openstreetmap.josm.tools.ImageProvider; 42 45 import org.openstreetmap.josm.tools.LanguageInfo; 43 import org.openstreetmap.josm.tools.Utils;44 46 45 47 public class MapPainter { … … 106 108 } 107 109 108 public void drawWay(Way way, Color color, BasicStroke line, BasicStroke dashes, Color dashedColor, boolean showDirection,110 public void drawWay(Way way, Color color, BasicStroke line, BasicStroke dashes, Color dashedColor, TextElement text, boolean showDirection, 109 111 boolean reversedDirection, boolean showHeadArrowOnly) { 110 112 … … 163 165 } 164 166 displaySegments(path, arrows, color, line, dashes, dashedColor); 167 drawTextOnPath(way, text); 165 168 } 166 169 … … 193 196 } 194 197 195 public void drawNodeIcon(Node n, ImageIcon icon, float iconAlpha, boolean selected, boolean member, TextElement text) { 198 private void drawTextOnPath(Way way, TextElement text) { 199 if (text == null) 200 return; 201 String name = getAreaName(way); 202 if (name == null || name.equals("")) 203 return; 204 205 Polygon poly = new Polygon(); 206 Point lastPoint = null; 207 Iterator<Node> it = way.getNodes().iterator(); 208 double pathLength = 0; 209 int dx, dy; 210 while (it.hasNext()) { 211 Node n = it.next(); 212 Point p = nc.getPoint(n); 213 poly.addPoint(p.x, p.y); 214 215 if(lastPoint != null) { 216 dx = p.x - lastPoint.x; 217 dy = p.y - lastPoint.y; 218 pathLength += Math.sqrt(dx*dx + dy*dy); 219 } 220 lastPoint = p; 221 } 222 223 FontMetrics fontMetrics = g.getFontMetrics(text.font); // if slow, use cache 224 Rectangle2D rec = fontMetrics.getStringBounds(name, g); // if slow, approximate by strlen()*maxcharbounds(font) 225 226 if (rec.getWidth() > pathLength) 227 return; 228 229 double t1 = (pathLength/2 - rec.getWidth()/2) / pathLength; 230 double t2 = (pathLength/2 + rec.getWidth()/2) / pathLength; 231 232 double[] p1 = pointAt(t1, poly, pathLength); 233 double[] p2 = pointAt(t2, poly, pathLength); 234 235 double angleOffset; 236 double offsetSign; 237 double tStart; 238 239 if (p1[0] < p2[0] && 240 p1[2] < Math.PI/2 && 241 p1[2] > -Math.PI/2) { 242 angleOffset = 0; 243 offsetSign = 1; 244 tStart = t1; 245 } else { 246 angleOffset = Math.PI; 247 offsetSign = -1; 248 tStart = t2; 249 } 250 251 FontRenderContext frc = g.getFontRenderContext(); 252 GlyphVector gv = text.font.createGlyphVector(frc, name); 253 254 for (int i=0; i<gv.getNumGlyphs(); ++i) { 255 Rectangle2D rect = gv.getGlyphLogicalBounds(i).getBounds2D(); 256 double t = tStart + offsetSign * (rect.getX() + rect.getWidth()/2) / pathLength; 257 double[] p = pointAt(t, poly, pathLength); 258 AffineTransform trfm = AffineTransform.getTranslateInstance(p[0] - rect.getX(), p[1]); 259 trfm.rotate(p[2]+angleOffset); 260 double off = -rect.getY() - rect.getHeight()/2 + text.yOffset; 261 trfm.translate(-rect.getWidth()/2, off); 262 gv.setGlyphTransform(i, trfm); 263 } 264 g.setColor(text.color); 265 g.drawGlyphVector(gv, 0, 0); 266 267 } 268 269 private double[] pointAt(double t, Polygon poly, double pathLength) { 270 double totalLen = t * pathLength; 271 double curLen = 0; 272 int dx, dy; 273 double segLen; 274 275 // Yes, it is ineffecient to iterate from the beginning for each glyph. 276 // Can be optimized if it turns out to be slow. 277 for (int i = 1; i < poly.npoints; ++i) { 278 dx = poly.xpoints[i] - poly.xpoints[i-1]; 279 dy = poly.ypoints[i] - poly.ypoints[i-1]; 280 segLen = Math.sqrt(dx*dx + dy*dy); 281 if (totalLen > curLen + segLen) { 282 curLen += segLen; 283 continue; 284 } 285 return new double[] {poly.xpoints[i-1]+(totalLen - curLen)/segLen*dx, 286 poly.ypoints[i-1]+(totalLen - curLen)/segLen*dy, 287 Math.atan2(dy, dx)}; 288 } 289 return null; 290 } 291 292 public void drawNodeIcon(Node n, ImageIcon icon, float iconAlpha, boolean selected, boolean member, NodeTextElement text) { 196 293 Point p = nc.getPoint(n); 197 294 if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return; … … 211 308 } 212 309 213 public void drawNodeSymbol(Node n, Symbol s, Color fillColor, Color strokeColor, TextElement text) {310 public void drawNodeSymbol(Node n, Symbol s, Color fillColor, Color strokeColor, NodeTextElement text) { 214 311 Point p = nc.getPoint(n); 215 312 if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return; … … 253 350 * @param color The color of the node. 254 351 */ 255 public void drawNode(Node n, Color color, int size, boolean fill, TextElement text) {352 public void drawNode(Node n, Color color, int size, boolean fill, NodeTextElement text) { 256 353 if (size > 1) { 257 354 Point p = nc.getPoint(n); … … 274 371 } 275 372 276 private void drawNodeText(Node n, TextElement text, Point p, int w_half, int h_half) {373 private void drawNodeText(Node n, NodeTextElement text, Point p, int w_half, int h_half) { 277 374 if (!isShowNames() || text == null) 278 375 return; … … 345 442 } 346 443 347 public void drawArea(Way w, Color color, BufferedImage fillImage, float fillImageAlpha, String name) {444 public void drawArea(Way w, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 348 445 Polygon polygon = getPolygon(w); 349 drawArea( polygon, color, fillImage, fillImageAlpha, name);350 } 351 352 protected void drawArea( Polygon polygon, Color color, BufferedImage fillImage, float fillImageAlpha, String name) {446 drawArea(w, polygon, color, fillImage, fillImageAlpha, text); 447 } 448 449 protected void drawArea(OsmPrimitive osm, Polygon polygon, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 353 450 354 451 if (fillImage == null) { … … 366 463 } 367 464 368 if (name != null) { 465 if (text != null && isShowNames()) { 466 String name = text.textKey == null ? getAreaName(osm) : osm.get(text.textKey); 467 if (name == null) 468 return; 469 369 470 Rectangle pb = polygon.getBounds(); 370 471 FontMetrics fontMetrics = g.getFontMetrics(orderFont); // if slow, use cache … … 403 504 } 404 505 405 public void drawArea(Relation r, Color color, BufferedImage fillImage, float fillImageAlpha, String name) {506 public void drawArea(Relation r, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 406 507 Multipolygon multipolygon = new Multipolygon(nc); 407 508 multipolygon.load(r); … … 412 513 continue; 413 514 } 414 drawArea( p, color, fillImage, fillImageAlpha, getAreaName(r));515 drawArea(r, p, color, fillImage, fillImageAlpha, text); 415 516 } 416 517 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java
r3879 r3880 26 26 public BufferedImage fillImage; 27 27 public float fillImageAlpha; 28 public TextElement text; 28 29 29 protected AreaElemStyle(Cascade c, Color color, BufferedImage fillImage, float fillImageAlpha ) {30 protected AreaElemStyle(Cascade c, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 30 31 super(c); 31 32 CheckParameterUtil.ensureParameterNotNull(color); … … 33 34 this.fillImage = fillImage; 34 35 this.fillImageAlpha = fillImageAlpha; 36 this.text = text; 35 37 } 36 38 … … 73 75 } 74 76 } 77 78 TextElement text = null; 79 String textPos = c.get("text-position", null, String.class); 80 if (textPos == null || Utils.equal(textPos, "center")) { 81 text = TextElement.create(c); 82 } 75 83 76 84 if (color != null) 77 return new AreaElemStyle(c, color, fillImage, fillImageAlpha );85 return new AreaElemStyle(c, color, fillImage, fillImageAlpha, text); 78 86 else 79 87 return null; … … 90 98 } 91 99 } 92 painter.drawArea((Way) osm, myColor, fillImage, fillImageAlpha, 93 painter.isShowNames() ? painter.getAreaName(osm) : null); 100 painter.drawArea((Way) osm, myColor, fillImage, fillImageAlpha, text); 94 101 } else if (osm instanceof Relation) 95 102 { … … 100 107 } 101 108 } 102 painter.drawArea((Relation) osm, myColor, fillImage, fillImageAlpha, 103 painter.getAreaName(osm)); 109 painter.drawArea((Relation) osm, myColor, fillImage, fillImageAlpha, text); 104 110 } 105 111 } … … 119 125 if (fillImageAlpha != other.fillImageAlpha) 120 126 return false; 127 if (!Utils.equal(text, other.text)) 128 return false; 121 129 return true; 122 130 } … … 128 136 hash = 61 * hash + (fillImage != null ? fillImage.hashCode() : 0); 129 137 hash = 61 * hash + Float.floatToIntBits(fillImageAlpha); 138 hash = 61 * hash + (text != null ? text.hashCode() : 0); 130 139 return hash; 131 140 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java
r3865 r3880 2 2 package org.openstreetmap.josm.gui.mappaint; 3 3 4 import static org.openstreetmap.josm.tools.Utils.equal; 5 6 import java.awt.Font; 7 8 import org.openstreetmap.josm.Main; 4 9 import org.openstreetmap.josm.data.osm.OsmPrimitive; 5 10 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 6 11 import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter; 12 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction.RelativeFloat; 7 13 8 14 abstract public class ElemStyle { … … 26 32 27 33 public abstract void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected, boolean member); 34 35 protected static Float getWidth(Cascade c, String key, Float relativeTo) { 36 Float width = c.get(key, null, Float.class, true); 37 if (width != null) { 38 if (width == -1f) 39 return (float) MapPaintSettings.INSTANCE.getDefaultSegmentWidth(); 40 if (width > 0) 41 return width; 42 } else { 43 String width_key = c.get(key, null, String.class, true); 44 if (equal(width_key, "thinnest")) 45 return 0f; 46 else if (relativeTo != null) { 47 RelativeFloat width_rel = c.get(key, null, RelativeFloat.class, true); 48 if (width_rel != null) 49 return relativeTo + width_rel.val; 50 } 51 } 52 return null; 53 } 54 55 protected static Font getFont(Cascade c) { 56 String name = c.get("font-family", Main.pref.get("mappaint.font", "Helvetica"), String.class); 57 float size = c.get("font-size", (float) Main.pref.getInteger("mappaint.fontsize", 8), Float.class); 58 int weight = Font.PLAIN; 59 String weightStr = c.get("font-wheight", null, String.class); 60 if (equal(weightStr, "bold")) { 61 weight = Font.BOLD; 62 } 63 int style = Font.PLAIN; 64 String styleStr = c.get("font-style", null, String.class); 65 if (equal(styleStr, "italic")) { 66 style = Font.ITALIC; 67 } 68 return new Font(name, weight | style, Math.round(size)); 69 } 28 70 29 71 @Override -
trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java
r3871 r3880 14 14 import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter; 15 15 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors; 16 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction.RelativeFloat;17 16 import org.openstreetmap.josm.tools.Utils; 18 17 … … 32 31 public Color color; 33 32 public Color dashesBackground; 33 public TextElement text; 34 34 public float realWidth; // the real width of this line in meter 35 35 36 36 private BasicStroke dashesLine; 37 37 38 protected LineElemStyle(Cascade c, BasicStroke line, Color color, BasicStroke dashesLine, Color dashesBackground, float realWidth) {38 protected LineElemStyle(Cascade c, BasicStroke line, Color color, BasicStroke dashesLine, Color dashesBackground, TextElement text, float realWidth) { 39 39 super(c); 40 40 this.line = line; … … 42 42 this.dashesLine = dashesLine; 43 43 this.dashesBackground = dashesBackground; 44 this.text = text; 44 45 this.realWidth = realWidth; 45 46 } 46 47 47 48 public static LineElemStyle createLine(Environment env) { 48 return createImpl(env, "");49 return createImpl(env, false); 49 50 } 50 51 51 52 public static LineElemStyle createCasing(Environment env) { 52 LineElemStyle casing = createImpl(env, "casing-");53 LineElemStyle casing = createImpl(env, true); 53 54 if (casing != null) { 54 55 casing.object_z_index = -1; … … 57 58 } 58 59 59 private static LineElemStyle createImpl(Environment env, String prefix) {60 private static LineElemStyle createImpl(Environment env, boolean casing) { 60 61 Cascade c = env.getCascade(); 61 Float width = c.get(prefix + "width", null, Float.class, true); 62 if (width != null) { 63 if (width == -1f) { 64 width = (float) MapPaintSettings.INSTANCE.getDefaultSegmentWidth(); 65 } 66 if (width <= 0) 67 return null; 62 Cascade c_def = env.mc.getCascade("default"); 63 64 String prefix = casing ? "casing-" : ""; 65 66 Float width; 67 if (casing) { 68 Float widthOnDefault = getWidth(c_def, "width", null); 69 Float widthLine = getWidth(c, "width", widthOnDefault); 70 width = getWidth(c, "casing-width", widthLine); 68 71 } else { 69 String width_key = c.get(prefix + "width", null, String.class, true); 70 if (equal(width_key, "thinnest")) { 71 width = 0f; 72 } else if (! equal(env.layer, "default")) { 73 RelativeFloat width_rel = c.get(prefix + "width", null, RelativeFloat.class, true); 74 if (width_rel != null) { 75 width = env.mc.getCascade("default").get("width", 0f, Float.class) + width_rel.val; 76 } else 77 return null; 78 } else 79 return null; 80 } 72 Float widthOnDefault = getWidth(c_def, "width", null); 73 width = getWidth(c, "width", widthOnDefault); 74 } 75 76 if (width == null) 77 return null; 81 78 82 79 float realWidth = c.get(prefix + "real-width", 0f, Float.class); … … 178 175 } 179 176 180 return new LineElemStyle(c, line, color, dashesLine, dashesBackground, realWidth); 177 TextElement text = null; 178 if (!casing) { 179 String textPos = c.get("text-position", null, String.class); 180 if (textPos == null || equal(textPos, "line")) { 181 text = TextElement.create(c); 182 } 183 } 184 185 return new LineElemStyle(c, line, color, dashesLine, dashesBackground, text, realWidth); 181 186 } 182 187 … … 222 227 } 223 228 224 painter.drawWay(w, markColor != null ? markColor : color, myLine, myDashLine, myDashedColor, showDirection,229 painter.drawWay(w, markColor != null ? markColor : color, myLine, myDashLine, myDashedColor, text, showDirection, 225 230 selected ? false : reversedDirection, showOnlyHeadArrowOnly); 226 231 … … 249 254 equal(dashesLine, other.dashesLine) && 250 255 equal(dashesBackground, other.dashesBackground) && 256 equal(text, other.text) && 251 257 realWidth == other.realWidth; 252 258 } … … 259 265 hash = 29 * hash + (dashesLine != null ? dashesLine.hashCode() : 0); 260 266 hash = 29 * hash + (dashesBackground != null ? dashesBackground.hashCode() : 0); 267 hash = 29 * hash + (text != null ? text.hashCode() : 0); 261 268 hash = 29 * hash + Float.floatToIntBits(realWidth); 262 269 return hash; -
trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java
r3879 r3880 18 18 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 19 19 import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter; 20 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;21 20 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference; 22 21 import org.openstreetmap.josm.tools.CheckParameterUtil; … … 31 30 public int iconAlpha; 32 31 public Symbol symbol; 33 public TextElement text;32 public NodeTextElement text; 34 33 35 34 private ImageIcon disabledIcon; … … 89 88 } 90 89 91 public static class TextElement { 92 public String textKey; 90 public static class NodeTextElement extends TextElement { 93 91 public HorizontalTextAlignment hAlign; 94 92 public VerticalTextAlignment vAlign; 95 public Font font; 96 public int xOffset; 97 public int yOffset; 98 public Color color; 99 100 public TextElement(String textKey, HorizontalTextAlignment hAlign, VerticalTextAlignment vAlign, Font font, int xOffset, int yOffset, Color color) { 93 94 public NodeTextElement(String textKey, HorizontalTextAlignment hAlign, VerticalTextAlignment vAlign, Font font, int xOffset, int yOffset, Color color) { 95 super(textKey, font, xOffset, yOffset, color); 101 96 CheckParameterUtil.ensureParameterNotNull(hAlign); 102 97 CheckParameterUtil.ensureParameterNotNull(vAlign); 103 CheckParameterUtil.ensureParameterNotNull(font);104 CheckParameterUtil.ensureParameterNotNull(color);105 this.textKey = textKey;106 98 this.hAlign = hAlign; 107 99 this.vAlign = vAlign; 108 this.font = font;109 this.xOffset = xOffset;110 this.yOffset = yOffset;111 this.color = color;112 100 } 113 101 114 102 @Override 115 103 public boolean equals(Object obj) { 104 if (!super.equals(obj)) 105 return false; 116 106 if (obj == null || getClass() != obj.getClass()) 117 107 return false; 118 final TextElement other = (TextElement) obj; 119 return equal(textKey, other.textKey) && 120 hAlign == other.hAlign && 121 vAlign == other.vAlign && 122 equal(font, other.font) && 123 xOffset == other.xOffset && 124 yOffset == other.yOffset && 125 equal(color, other.color); 108 final NodeTextElement other = (NodeTextElement) obj; 109 return hAlign == other.hAlign && 110 vAlign == other.vAlign; 126 111 } 127 112 128 113 @Override 129 114 public int hashCode() { 130 int hash = 3; 131 hash = 79 * hash + (textKey != null ? textKey.hashCode() : 0); 132 hash = 79 * hash + hAlign.hashCode(); 133 hash = 79 * hash + vAlign.hashCode(); 134 hash = 79 * hash + font.hashCode(); 135 hash = 79 * hash + xOffset; 136 hash = 79 * hash + yOffset; 137 hash = 79 * hash + color.hashCode(); 115 int hash = super.hashCode(); 116 hash = 97 * hash + hAlign.hashCode(); 117 hash = 97 * hash + vAlign.hashCode(); 138 118 return hash; 139 119 } 120 140 121 } 141 122 … … 147 128 } 148 129 149 protected NodeElemStyle(Cascade c, ImageIcon icon, int iconAlpha, Symbol symbol, TextElement text) {130 protected NodeElemStyle(Cascade c, ImageIcon icon, int iconAlpha, Symbol symbol, NodeTextElement text) { 150 131 super(c); 151 132 this.icon = icon; … … 179 160 return null; 180 161 181 TextElement text = null; 182 String textStr = c.get("text", null, String.class); 183 if (textStr != null) { 184 String textKey = null; 185 if (!"auto".equalsIgnoreCase(textStr)) { 186 textKey = textStr; 187 } 162 NodeTextElement text = null; 163 TextElement te = TextElement.create(c); 164 if (te != null) { 188 165 HorizontalTextAlignment hAlign = HorizontalTextAlignment.RIGHT; 189 166 String hAlignStr = c.get("text-anchor-horizontal", null, String.class); … … 208 185 vAlign = VerticalTextAlignment.BELOW; 209 186 } 210 String name = c.get("font-family", Main.pref.get("mappaint.font", "Helvetica"), String.class); 211 float size = c.get("font-size", (float) Main.pref.getInteger("mappaint.fontsize", 8), Float.class); 212 int weight = Font.PLAIN; 213 String weightStr = c.get("font-wheight", null, String.class); 214 if (equal(weightStr, "bold")) { 215 weight = Font.BOLD; 216 } 217 int style = Font.PLAIN; 218 String styleStr = c.get("font-style", null, String.class); 219 if (equal(styleStr, "italic")) { 220 style = Font.ITALIC; 221 } 222 Font font = new Font(name, weight | style, Math.round(size)); 223 int xOffset = c.get("text-offset-x", 0f, Float.class).intValue(); 224 int yOffset = c.get("text-offset-y", 0f, Float.class).intValue(); 225 Color color = c.get("text-color", PaintColors.TEXT.get(), Color.class); 226 text = new TextElement(textKey, hAlign, vAlign, font, xOffset, yOffset, color); 187 text = new NodeTextElement(te.textKey, hAlign, vAlign, te.font, te.xOffset, te.yOffset, te.color); 227 188 } 228 189 -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java
r3867 r3880 191 191 } 192 192 193 @SuppressWarnings("unchecked") 193 194 public boolean equal(Object a, Object b) { 194 195 // make sure the casts are done in a meaningful way, so -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r3860 r3880 49 49 return true; 50 50 if (base.equals("area")) { 51 if (osm instanceof Way && ((Way)osm).isClosed())51 if (osm instanceof Way) 52 52 return true; 53 53 if (osm instanceof Relation && ((Relation) osm).isMultipolygon()) -
trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java
r3865 r3880 350 350 if (p.area != null) { 351 351 def.putOrClear("fill-color", p.area.color); 352 def.putOrClear("text-position", "center"); 353 def.putOrClear("text", "auto"); 352 354 def.remove("fill-image"); 353 355 }
Note:
See TracChangeset
for help on using the changeset viewer.