Ticket #12957: patch-mappaint-code-cleanup.patch
| File patch-mappaint-code-cleanup.patch, 26.9 KB (added by , 10 years ago) |
|---|
-
src/org/openstreetmap/josm/gui/MapView.java
diff --git a/src/org/openstreetmap/josm/gui/MapView.java b/src/org/openstreetmap/josm/gui/MapView.java index 5f4df08..d4d5e9c 100644
a b LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener { 1182 1182 } 1183 1183 }; 1184 1184 1185 /** 1186 * Destroy this map view panel. Should be called once when it is not needed any more. 1187 */ 1185 1188 public void destroy() { 1186 1189 layerManager.removeLayerChangeListener(this); 1187 1190 layerManager.removeActiveLayerChangeListener(this); … … LayerManager.LayerChangeListener, MainLayerManager.ActiveLayerChangeListener { 1195 1198 synchronized (temporaryLayers) { 1196 1199 temporaryLayers.clear(); 1197 1200 } 1201 nonChangedLayersBuffer = null; 1198 1202 } 1199 1203 1200 1204 /** -
src/org/openstreetmap/josm/gui/mappaint/styleelement/BoxTextElement.java
diff --git a/src/org/openstreetmap/josm/gui/mappaint/styleelement/BoxTextElement.java b/src/org/openstreetmap/josm/gui/mappaint/styleelement/BoxTextElement.java index 02843eb..971fe66 100644
a b import org.openstreetmap.josm.tools.CheckParameterUtil; 21 21 */ 22 22 public class BoxTextElement extends StyleElement { 23 23 24 /** 25 * MapCSS text-anchor-horizontal 26 */ 24 27 public enum HorizontalTextAlignment { LEFT, CENTER, RIGHT } 25 28 29 /** 30 * MapCSS text-anchor-vertical 31 */ 26 32 public enum VerticalTextAlignment { ABOVE, TOP, CENTER, BOTTOM, BELOW } 27 33 34 /** 35 * Something that provides us with a {@link BoxProviderResult} 36 */ 28 37 public interface BoxProvider { 38 /** 39 * Compute and get the {@link BoxProviderResult}. The temporary flag is set if the result of the computation may change in the future. 40 * @return The result of the computation. 41 */ 29 42 BoxProviderResult get(); 30 43 } 31 44 45 /** 46 * A box rectangle with a flag if it is temporary. 47 */ 32 48 public static class BoxProviderResult { 33 49 private final Rectangle box; 34 50 private final boolean temporary; … … public class BoxTextElement extends StyleElement { 55 71 } 56 72 } 57 73 74 /** 75 * A {@link BoxProvider} that always returns the same non-temporary rectangle 76 */ 58 77 public static class SimpleBoxProvider implements BoxProvider { 59 78 private final Rectangle box; 60 79 … … public class BoxTextElement extends StyleElement { 85 104 } 86 105 } 87 106 107 /** 108 * A rectangle with size 0x0 109 */ 88 110 public static final Rectangle ZERO_BOX = new Rectangle(0, 0, 0, 0); 89 111 112 /** 113 * The default style a simple node should use for it's text 114 */ 115 public static final BoxTextElement SIMPLE_NODE_TEXT_ELEMSTYLE; 116 static { 117 MultiCascade mc = new MultiCascade(); 118 Cascade c = mc.getOrCreateCascade("default"); 119 c.put(TEXT, Keyword.AUTO); 120 Node n = new Node(); 121 n.put("name", "dummy"); 122 SIMPLE_NODE_TEXT_ELEMSTYLE = create(new Environment(n, mc, "default", null), NodeElement.SIMPLE_NODE_ELEMSTYLE.getBoxProvider()); 123 if (SIMPLE_NODE_TEXT_ELEMSTYLE == null) throw new AssertionError(); 124 } 125 126 /** 127 * Caches the default text color from the preferences. 128 * 129 * FIXME: the cache isn't updated if the user changes the preference during a JOSM 130 * session. There should be preference listener updating this cache. 131 */ 132 private static volatile Color defaultTextColorCache; 133 134 /** 135 * The text this element should display. 136 */ 90 137 public TextLabel text; 91 138 // Either boxProvider or box is not null. If boxProvider is different from 92 139 // null, this means, that the box can still change in future, otherwise 93 140 // it is fixed. 94 141 protected BoxProvider boxProvider; 95 142 protected Rectangle box; 143 /** 144 * The {@link HorizontalTextAlignment} for this text. 145 */ 96 146 public HorizontalTextAlignment hAlign; 147 /** 148 * The {@link VerticalTextAlignment} for this text. 149 */ 97 150 public VerticalTextAlignment vAlign; 98 151 152 /** 153 * Create a new {@link BoxTextElement} 154 * @param c The current cascade 155 * @param text The text to display 156 * @param boxProvider The box provider to use 157 * @param box The initial box to use. 158 * @param hAlign The {@link HorizontalTextAlignment} 159 * @param vAlign The {@link VerticalTextAlignment} 160 */ 99 161 public BoxTextElement(Cascade c, TextLabel text, BoxProvider boxProvider, Rectangle box, 100 162 HorizontalTextAlignment hAlign, VerticalTextAlignment vAlign) { 101 163 super(c, 5f); … … public class BoxTextElement extends StyleElement { 109 171 this.vAlign = vAlign; 110 172 } 111 173 174 /** 175 * Create a new {@link BoxTextElement} with a dynamic box 176 * @param env The MapCSS environment 177 * @param boxProvider The box provider that computes the box. 178 * @return A new {@link BoxTextElement} or <code>null</code> if the creation failed. 179 */ 112 180 public static BoxTextElement create(Environment env, BoxProvider boxProvider) { 113 181 return create(env, boxProvider, null); 114 182 } 115 183 184 /** 185 * Create a new {@link BoxTextElement} with a fixed box 186 * @param env The MapCSS environment 187 * @param box The box 188 * @return A new {@link BoxTextElement} or <code>null</code> if the creation failed. 189 */ 116 190 public static BoxTextElement create(Environment env, Rectangle box) { 117 191 return create(env, null, box); 118 192 } 119 193 194 /** 195 * Create a new {@link BoxTextElement} with a boxprovider and a box. 196 * @param env The MapCSS environment 197 * @param boxProvider The box provider. 198 * @param box The box. Only considered if boxProvider is null. 199 * @return A new {@link BoxTextElement} or <code>null</code> if the creation failed. 200 */ 120 201 public static BoxTextElement create(Environment env, BoxProvider boxProvider, Rectangle box) { 121 202 initDefaultParameters(); 122 203 123 TextLabel text = TextLabel.create(env, DEFAULT_TEXT_COLOR, false);204 TextLabel text = TextLabel.create(env, defaultTextColorCache, false); 124 205 if (text == null) return null; 125 206 // Skip any primitives that don't have text to draw. (Styles are recreated for any tag change.) 126 207 // The concrete text to render is not cached in this object, but computed for each … … public class BoxTextElement extends StyleElement { 163 244 return new BoxTextElement(c, text, boxProvider, box, hAlign, vAlign); 164 245 } 165 246 247 /** 248 * Get the box in which the content should be drawn. 249 * @return The box. 250 */ 166 251 public Rectangle getBox() { 167 252 if (boxProvider != null) { 168 253 BoxProviderResult result = boxProvider.get(); … … public class BoxTextElement extends StyleElement { 175 260 return box; 176 261 } 177 262 178 public static final BoxTextElement SIMPLE_NODE_TEXT_ELEMSTYLE;179 static {180 MultiCascade mc = new MultiCascade();181 Cascade c = mc.getOrCreateCascade("default");182 c.put(TEXT, Keyword.AUTO);183 Node n = new Node();184 n.put("name", "dummy");185 SIMPLE_NODE_TEXT_ELEMSTYLE = create(new Environment(n, mc, "default", null), NodeElement.SIMPLE_NODE_ELEMSTYLE.getBoxProvider());186 if (SIMPLE_NODE_TEXT_ELEMSTYLE == null) throw new AssertionError();187 }188 189 /*190 * Caches the default text color from the preferences.191 *192 * FIXME: the cache isn't updated if the user changes the preference during a JOSM193 * session. There should be preference listener updating this cache.194 */195 private static volatile Color DEFAULT_TEXT_COLOR;196 263 197 264 private static void initDefaultParameters() { 198 if ( DEFAULT_TEXT_COLOR!= null) return;199 DEFAULT_TEXT_COLOR= PaintColors.TEXT.get();265 if (defaultTextColorCache != null) return; 266 defaultTextColorCache = PaintColors.TEXT.get(); 200 267 } 201 268 202 269 @Override -
src/org/openstreetmap/josm/gui/mappaint/styleelement/LineElement.java
diff --git a/src/org/openstreetmap/josm/gui/mappaint/styleelement/LineElement.java b/src/org/openstreetmap/josm/gui/mappaint/styleelement/LineElement.java index 350ae7f..c50b971 100644
a b import org.openstreetmap.josm.gui.mappaint.MultiCascade; 20 20 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction.RelativeFloat; 21 21 import org.openstreetmap.josm.tools.Utils; 22 22 23 /** 24 * This is the style definition for a simple line. 25 */ 23 26 public class LineElement extends StyleElement { 24 25 public static LineElement createSimpleLineStyle(Color color, boolean isAreaEdge) { 26 MultiCascade mc = new MultiCascade(); 27 Cascade c = mc.getOrCreateCascade("default"); 28 c.put(WIDTH, Keyword.DEFAULT); 29 c.put(COLOR, color != null ? color : PaintColors.UNTAGGED.get()); 30 c.put(OPACITY, 1f); 31 if (isAreaEdge) { 32 c.put(Z_INDEX, -3f); 33 } 34 Way w = new Way(); 35 return createLine(new Environment(w, mc, "default", null)); 36 } 37 27 /** 28 * The default style for any untagged way. 29 */ 38 30 public static final LineElement UNTAGGED_WAY = createSimpleLineStyle(null, false); 39 31 40 32 private BasicStroke line; … … public class LineElement extends StyleElement { 72 64 this.realWidth = realWidth; 73 65 this.wayDirectionArrows = wayDirectionArrows; 74 66 } 67 @Override 68 public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, StyledMapRenderer painter, 69 boolean selected, boolean outermember, boolean member) { 70 Way w = (Way) primitive; 71 /* show direction arrows, if draw.segment.relevant_directions_only is not set, 72 the way is tagged with a direction key 73 (even if the tag is negated as in oneway=false) or the way is selected */ 74 boolean showOrientation; 75 if (defaultSelectedHandling) { 76 showOrientation = !isModifier && (selected || paintSettings.isShowDirectionArrow()) && !paintSettings.isUseRealWidth(); 77 } else { 78 showOrientation = wayDirectionArrows; 79 } 80 boolean showOneway = !isModifier && !selected && 81 !paintSettings.isUseRealWidth() && 82 paintSettings.isShowOnewayArrow() && w.hasDirectionKeys(); 83 boolean onewayReversed = w.reversedDirection(); 84 /* head only takes over control if the option is true, 85 the direction should be shown at all and not only because it's selected */ 86 boolean showOnlyHeadArrowOnly = showOrientation && !selected && paintSettings.isShowHeadArrowOnly(); 87 Node lastN; 88 89 Color myDashedColor = dashesBackground; 90 BasicStroke myLine = line, myDashLine = dashesLine; 91 if (realWidth > 0 && paintSettings.isUseRealWidth() && !showOrientation) { 92 float myWidth = (int) (100 / (float) (painter.getCircum() / realWidth)); 93 if (myWidth < line.getLineWidth()) { 94 myWidth = line.getLineWidth(); 95 } 96 myLine = new BasicStroke(myWidth, line.getEndCap(), line.getLineJoin(), 97 line.getMiterLimit(), line.getDashArray(), line.getDashPhase()); 98 if (dashesLine != null) { 99 myDashLine = new BasicStroke(myWidth, dashesLine.getEndCap(), dashesLine.getLineJoin(), 100 dashesLine.getMiterLimit(), dashesLine.getDashArray(), dashesLine.getDashPhase()); 101 } 102 } 103 104 Color myColor = color; 105 if (defaultSelectedHandling && selected) { 106 myColor = paintSettings.getSelectedColor(color.getAlpha()); 107 } else if (member || outermember) { 108 myColor = paintSettings.getRelationSelectedColor(color.getAlpha()); 109 } else if (w.isDisabled()) { 110 myColor = paintSettings.getInactiveColor(); 111 myDashedColor = paintSettings.getInactiveColor(); 112 } 113 114 painter.drawWay(w, myColor, myLine, myDashLine, myDashedColor, offset, showOrientation, 115 showOnlyHeadArrowOnly, showOneway, onewayReversed); 116 117 if (paintSettings.isShowOrderNumber() && !painter.isInactiveMode()) { 118 int orderNumber = 0; 119 lastN = null; 120 for (Node n : w.getNodes()) { 121 if (lastN != null) { 122 orderNumber++; 123 painter.drawOrderNumber(lastN, n, orderNumber, myColor); 124 } 125 lastN = n; 126 } 127 } 128 } 129 130 @Override 131 public boolean isProperLineStyle() { 132 return !isModifier; 133 } 134 135 public String linejoinToString(int linejoin) { 136 switch (linejoin) { 137 case BasicStroke.JOIN_BEVEL: return "bevel"; 138 case BasicStroke.JOIN_ROUND: return "round"; 139 case BasicStroke.JOIN_MITER: return "miter"; 140 default: return null; 141 } 142 } 143 144 public String linecapToString(int linecap) { 145 switch (linecap) { 146 case BasicStroke.CAP_BUTT: return "none"; 147 case BasicStroke.CAP_ROUND: return "round"; 148 case BasicStroke.CAP_SQUARE: return "square"; 149 default: return null; 150 } 151 } 152 153 @Override 154 public boolean equals(Object obj) { 155 if (obj == null || getClass() != obj.getClass()) 156 return false; 157 if (!super.equals(obj)) 158 return false; 159 final LineElement other = (LineElement) obj; 160 return Objects.equals(line, other.line) && 161 Objects.equals(color, other.color) && 162 Objects.equals(dashesLine, other.dashesLine) && 163 Objects.equals(dashesBackground, other.dashesBackground) && 164 offset == other.offset && 165 realWidth == other.realWidth && 166 wayDirectionArrows == other.wayDirectionArrows; 167 } 168 169 @Override 170 public int hashCode() { 171 return Objects.hash(super.hashCode(), line, color, dashesBackground, offset, realWidth, wayDirectionArrows, dashesLine); 172 } 173 174 @Override 175 public String toString() { 176 return "LineElemStyle{" + super.toString() + "width=" + line.getLineWidth() + 177 " realWidth=" + realWidth + " color=" + Utils.toString(color) + 178 " dashed=" + Arrays.toString(line.getDashArray()) + 179 (line.getDashPhase() == 0 ? "" : " dashesOffses=" + line.getDashPhase()) + 180 " dashedColor=" + Utils.toString(dashesBackground) + 181 " linejoin=" + linejoinToString(line.getLineJoin()) + 182 " linecap=" + linecapToString(line.getEndCap()) + 183 (offset == 0 ? "" : " offset=" + offset) + 184 '}'; 185 } 186 187 /** 188 * Creates a simple line with default widt. 189 * @param color The color to use 190 * @param isAreaEdge If this is an edge for an area. Edges are drawn at lower Z-Index. 191 * @return The line style. 192 */ 193 public static LineElement createSimpleLineStyle(Color color, boolean isAreaEdge) { 194 MultiCascade mc = new MultiCascade(); 195 Cascade c = mc.getOrCreateCascade("default"); 196 c.put(WIDTH, Keyword.DEFAULT); 197 c.put(COLOR, color != null ? color : PaintColors.UNTAGGED.get()); 198 c.put(OPACITY, 1f); 199 if (isAreaEdge) { 200 c.put(Z_INDEX, -3f); 201 } 202 Way w = new Way(); 203 return createLine(new Environment(w, mc, "default", null)); 204 } 75 205 76 206 public static LineElement createLine(Environment env) { 77 207 return createImpl(env, LineType.NORMAL); … … public class LineElement extends StyleElement { 104 234 private static LineElement createImpl(Environment env, LineType type) { 105 235 Cascade c = env.mc.getCascade(env.layer); 106 236 Cascade cDef = env.mc.getCascade("default"); 107 Float width; 108 switch (type) { 109 case NORMAL: 110 width = getWidth(c, WIDTH, getWidth(cDef, WIDTH, null)); 111 break; 112 case CASING: 113 Float casingWidth = c.get(type.prefix + WIDTH, null, Float.class, true); 114 if (casingWidth == null) { 115 RelativeFloat relCasingWidth = c.get(type.prefix + WIDTH, null, RelativeFloat.class, true); 116 if (relCasingWidth != null) { 117 casingWidth = relCasingWidth.val / 2; 118 } 119 } 120 if (casingWidth == null) 121 return null; 122 width = getWidth(c, WIDTH, getWidth(cDef, WIDTH, null)); 123 if (width == null) { 124 width = 0f; 125 } 126 width += 2 * casingWidth; 127 break; 128 case LEFT_CASING: 129 case RIGHT_CASING: 130 width = getWidth(c, type.prefix + WIDTH, null); 131 break; 132 default: 133 throw new AssertionError(); 134 } 237 Float width = computeWidth(type, c, cDef); 135 238 if (width == null) 136 239 return null; 137 240 138 float realWidth = c.get(type.prefix + REAL_WIDTH, 0f, Float.class); 139 if (realWidth > 0 && MapPaintSettings.INSTANCE.isUseRealWidth()) { 241 float realWidth = computeRealWidth(env, type, c); 140 242 141 /* if we have a "width" tag, try use it */ 142 String widthTag = env.osm.get("width"); 143 if (widthTag == null) { 144 widthTag = env.osm.get("est_width"); 145 } 146 if (widthTag != null) { 147 try { 148 realWidth = Float.parseFloat(widthTag); 149 } catch (NumberFormatException nfe) { 150 Main.warn(nfe); 151 } 152 } 153 } 154 155 Float offset = c.get(OFFSET, 0f, Float.class); 156 switch (type) { 157 case NORMAL: 158 break; 159 case CASING: 160 offset += c.get(type.prefix + OFFSET, 0f, Float.class); 161 break; 162 case LEFT_CASING: 163 case RIGHT_CASING: 164 Float baseWidthOnDefault = getWidth(cDef, WIDTH, null); 165 Float baseWidth = getWidth(c, WIDTH, baseWidthOnDefault); 166 if (baseWidth == null || baseWidth < 2f) { 167 baseWidth = 2f; 168 } 169 float casingOffset = c.get(type.prefix + OFFSET, 0f, Float.class); 170 casingOffset += baseWidth / 2 + width / 2; 171 /* flip sign for the right-casing-offset */ 172 if (type == LineType.RIGHT_CASING) { 173 casingOffset *= -1f; 174 } 175 offset += casingOffset; 176 break; 177 } 243 Float offset = computeOffset(type, c, cDef, width); 178 244 179 245 int alpha = 255; 180 246 Color color = c.get(type.prefix + COLOR, null, Color.class); … … public class LineElement extends StyleElement { 272 338 offset, realWidth, wayDirectionArrows); 273 339 } 274 340 275 @Override 276 public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, StyledMapRenderer painter, 277 boolean selected, boolean outermember, boolean member) { 278 Way w = (Way) primitive; 279 /* show direction arrows, if draw.segment.relevant_directions_only is not set, 280 the way is tagged with a direction key 281 (even if the tag is negated as in oneway=false) or the way is selected */ 282 boolean showOrientation; 283 if (defaultSelectedHandling) { 284 showOrientation = !isModifier && (selected || paintSettings.isShowDirectionArrow()) && !paintSettings.isUseRealWidth(); 285 } else { 286 showOrientation = wayDirectionArrows; 287 } 288 boolean showOneway = !isModifier && !selected && 289 !paintSettings.isUseRealWidth() && 290 paintSettings.isShowOnewayArrow() && w.hasDirectionKeys(); 291 boolean onewayReversed = w.reversedDirection(); 292 /* head only takes over control if the option is true, 293 the direction should be shown at all and not only because it's selected */ 294 boolean showOnlyHeadArrowOnly = showOrientation && !selected && paintSettings.isShowHeadArrowOnly(); 295 Node lastN; 296 297 Color myDashedColor = dashesBackground; 298 BasicStroke myLine = line, myDashLine = dashesLine; 299 if (realWidth > 0 && paintSettings.isUseRealWidth() && !showOrientation) { 300 float myWidth = (int) (100 / (float) (painter.getCircum() / realWidth)); 301 if (myWidth < line.getLineWidth()) { 302 myWidth = line.getLineWidth(); 303 } 304 myLine = new BasicStroke(myWidth, line.getEndCap(), line.getLineJoin(), 305 line.getMiterLimit(), line.getDashArray(), line.getDashPhase()); 306 if (dashesLine != null) { 307 myDashLine = new BasicStroke(myWidth, dashesLine.getEndCap(), dashesLine.getLineJoin(), 308 dashesLine.getMiterLimit(), dashesLine.getDashArray(), dashesLine.getDashPhase()); 309 } 310 } 311 312 Color myColor = color; 313 if (defaultSelectedHandling && selected) { 314 myColor = paintSettings.getSelectedColor(color.getAlpha()); 315 } else if (member || outermember) { 316 myColor = paintSettings.getRelationSelectedColor(color.getAlpha()); 317 } else if (w.isDisabled()) { 318 myColor = paintSettings.getInactiveColor(); 319 myDashedColor = paintSettings.getInactiveColor(); 341 private static Float computeWidth(LineType type, Cascade c, Cascade cDef) { 342 Float width; 343 switch (type) { 344 case NORMAL: 345 width = getWidth(c, WIDTH, getWidth(cDef, WIDTH, null)); 346 break; 347 case CASING: 348 Float casingWidth = c.get(type.prefix + WIDTH, null, Float.class, true); 349 if (casingWidth == null) { 350 RelativeFloat relCasingWidth = c.get(type.prefix + WIDTH, null, RelativeFloat.class, true); 351 if (relCasingWidth != null) { 352 casingWidth = relCasingWidth.val / 2; 353 } 354 } 355 if (casingWidth == null) 356 return null; 357 width = getWidth(c, WIDTH, getWidth(cDef, WIDTH, null)); 358 if (width == null) { 359 width = 0f; 360 } 361 width += 2 * casingWidth; 362 break; 363 case LEFT_CASING: 364 case RIGHT_CASING: 365 width = getWidth(c, type.prefix + WIDTH, null); 366 break; 367 default: 368 throw new AssertionError(); 320 369 } 370 return width; 371 } 321 372 322 painter.drawWay(w, myColor, myLine, myDashLine, myDashedColor, offset, showOrientation, 323 showOnlyHeadArrowOnly, showOneway, onewayReversed); 373 private static float computeRealWidth(Environment env, LineType type, Cascade c) { 374 float realWidth = c.get(type.prefix + REAL_WIDTH, 0f, Float.class); 375 if (realWidth > 0 && MapPaintSettings.INSTANCE.isUseRealWidth()) { 324 376 325 if (paintSettings.isShowOrderNumber() && !painter.isInactiveMode()) { 326 int orderNumber = 0; 327 lastN = null; 328 for (Node n : w.getNodes()) { 329 if (lastN != null) { 330 orderNumber++; 331 painter.drawOrderNumber(lastN, n, orderNumber, myColor); 377 /* if we have a "width" tag, try use it */ 378 String widthTag = env.osm.get("width"); 379 if (widthTag == null) { 380 widthTag = env.osm.get("est_width"); 381 } 382 if (widthTag != null) { 383 try { 384 realWidth = Float.parseFloat(widthTag); 385 } catch (NumberFormatException nfe) { 386 Main.warn(nfe); 332 387 } 333 lastN = n;334 388 } 335 389 } 390 return realWidth; 336 391 } 337 392 338 @Override 339 public boolean isProperLineStyle() { 340 return !isModifier; 341 } 342 343 @Override 344 public boolean equals(Object obj) { 345 if (obj == null || getClass() != obj.getClass()) 346 return false; 347 if (!super.equals(obj)) 348 return false; 349 final LineElement other = (LineElement) obj; 350 return Objects.equals(line, other.line) && 351 Objects.equals(color, other.color) && 352 Objects.equals(dashesLine, other.dashesLine) && 353 Objects.equals(dashesBackground, other.dashesBackground) && 354 offset == other.offset && 355 realWidth == other.realWidth && 356 wayDirectionArrows == other.wayDirectionArrows; 357 } 358 359 @Override 360 public int hashCode() { 361 return Objects.hash(super.hashCode(), line, color, dashesBackground, offset, realWidth, wayDirectionArrows, dashesLine); 362 } 363 364 @Override 365 public String toString() { 366 return "LineElemStyle{" + super.toString() + "width=" + line.getLineWidth() + 367 " realWidth=" + realWidth + " color=" + Utils.toString(color) + 368 " dashed=" + Arrays.toString(line.getDashArray()) + 369 (line.getDashPhase() == 0 ? "" : " dashesOffses=" + line.getDashPhase()) + 370 " dashedColor=" + Utils.toString(dashesBackground) + 371 " linejoin=" + linejoinToString(line.getLineJoin()) + 372 " linecap=" + linecapToString(line.getEndCap()) + 373 (offset == 0 ? "" : " offset=" + offset) + 374 '}'; 375 } 376 377 public String linejoinToString(int linejoin) { 378 switch (linejoin) { 379 case BasicStroke.JOIN_BEVEL: return "bevel"; 380 case BasicStroke.JOIN_ROUND: return "round"; 381 case BasicStroke.JOIN_MITER: return "miter"; 382 default: return null; 393 private static Float computeOffset(LineType type, Cascade c, Cascade cDef, Float width) { 394 Float offset = c.get(OFFSET, 0f, Float.class); 395 switch (type) { 396 case NORMAL: 397 break; 398 case CASING: 399 offset += c.get(type.prefix + OFFSET, 0f, Float.class); 400 break; 401 case LEFT_CASING: 402 case RIGHT_CASING: 403 Float baseWidthOnDefault = getWidth(cDef, WIDTH, null); 404 Float baseWidth = getWidth(c, WIDTH, baseWidthOnDefault); 405 if (baseWidth == null || baseWidth < 2f) { 406 baseWidth = 2f; 407 } 408 float casingOffset = c.get(type.prefix + OFFSET, 0f, Float.class); 409 casingOffset += baseWidth / 2 + width / 2; 410 /* flip sign for the right-casing-offset */ 411 if (type == LineType.RIGHT_CASING) { 412 casingOffset *= -1f; 413 } 414 offset += casingOffset; 415 break; 383 416 } 417 return offset; 384 418 } 385 419 386 public String linecapToString(int linecap) {387 switch (linecap) {388 case BasicStroke.CAP_BUTT: return "none";389 case BasicStroke.CAP_ROUND: return "round";390 case BasicStroke.CAP_SQUARE: return "square";391 default: return null;392 }393 }394 420 }
