Ignore:
Timestamp:
2016-06-14T19:40:45+02:00 (8 years ago)
Author:
Don-vip
Message:

fix #12957 - BoxTextElement and LineElement: More documentation and reorder methods (patch by michael2402) - gsoc-core

Location:
trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/BoxTextElement.java

    r10217 r10374  
    2222public class BoxTextElement extends StyleElement {
    2323
     24    /**
     25     * MapCSS text-anchor-horizontal
     26     */
    2427    public enum HorizontalTextAlignment { LEFT, CENTER, RIGHT }
    2528
     29    /**
     30     * MapCSS text-anchor-vertical
     31     */
    2632    public enum VerticalTextAlignment { ABOVE, TOP, CENTER, BOTTOM, BELOW }
    2733
     34    /**
     35     * Something that provides us with a {@link BoxProviderResult}
     36     */
    2837    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         */
    2942        BoxProviderResult get();
    3043    }
    3144
     45    /**
     46     * A box rectangle with a flag if it is temporary.
     47     */
    3248    public static class BoxProviderResult {
    3349        private final Rectangle box;
     
    5672    }
    5773
     74    /**
     75     * A {@link BoxProvider} that always returns the same non-temporary rectangle
     76     */
    5877    public static class SimpleBoxProvider implements BoxProvider {
    5978        private final Rectangle box;
     
    86105    }
    87106
     107    /**
     108     * A rectangle with size 0x0
     109     */
    88110    public static final Rectangle ZERO_BOX = new Rectangle(0, 0, 0, 0);
    89111
     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     */
    90137    public TextLabel text;
    91138    // Either boxProvider or box is not null. If boxProvider is different from
     
    94141    protected BoxProvider boxProvider;
    95142    protected Rectangle box;
     143    /**
     144     * The {@link HorizontalTextAlignment} for this text.
     145     */
    96146    public HorizontalTextAlignment hAlign;
     147    /**
     148     * The {@link VerticalTextAlignment} for this text.
     149     */
    97150    public VerticalTextAlignment vAlign;
    98151
     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     */
    99161    public BoxTextElement(Cascade c, TextLabel text, BoxProvider boxProvider, Rectangle box,
    100162            HorizontalTextAlignment hAlign, VerticalTextAlignment vAlign) {
     
    110172    }
    111173
     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     */
    112180    public static BoxTextElement create(Environment env, BoxProvider boxProvider) {
    113181        return create(env, boxProvider, null);
    114182    }
    115183
     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     */
    116190    public static BoxTextElement create(Environment env, Rectangle box) {
    117191        return create(env, null, box);
    118192    }
    119193
     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     */
    120201    public static BoxTextElement create(Environment env, BoxProvider boxProvider, Rectangle box) {
    121202        initDefaultParameters();
    122203
    123         TextLabel text = TextLabel.create(env, DEFAULT_TEXT_COLOR, false);
     204        TextLabel text = TextLabel.create(env, defaultTextColorCache, false);
    124205        if (text == null) return null;
    125206        // Skip any primitives that don't have text to draw. (Styles are recreated for any tag change.)
     
    164245    }
    165246
     247    /**
     248     * Get the box in which the content should be drawn.
     249     * @return The box.
     250     */
    166251    public Rectangle getBox() {
    167252        if (boxProvider != null) {
     
    176261    }
    177262
    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 JOSM
    193      * session. There should be preference listener updating this cache.
    194      */
    195     private static volatile Color DEFAULT_TEXT_COLOR;
    196263
    197264    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();
    200267    }
    201268
  • trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LineElement.java

    r10001 r10374  
    2121import org.openstreetmap.josm.tools.Utils;
    2222
     23/**
     24 * This is the style definition for a simple line.
     25 */
    2326public 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     */
    3830    public static final LineElement UNTAGGED_WAY = createSimpleLineStyle(null, false);
    3931
     
    7264        this.realWidth = realWidth;
    7365        this.wayDirectionArrows = wayDirectionArrows;
    74     }
    75 
    76     public static LineElement createLine(Environment env) {
    77         return createImpl(env, LineType.NORMAL);
    78     }
    79 
    80     public static LineElement createLeftCasing(Environment env) {
    81         LineElement leftCasing = createImpl(env, LineType.LEFT_CASING);
    82         if (leftCasing != null) {
    83             leftCasing.isModifier = true;
    84         }
    85         return leftCasing;
    86     }
    87 
    88     public static LineElement createRightCasing(Environment env) {
    89         LineElement rightCasing = createImpl(env, LineType.RIGHT_CASING);
    90         if (rightCasing != null) {
    91             rightCasing.isModifier = true;
    92         }
    93         return rightCasing;
    94     }
    95 
    96     public static LineElement createCasing(Environment env) {
    97         LineElement casing = createImpl(env, LineType.CASING);
    98         if (casing != null) {
    99             casing.isModifier = true;
    100         }
    101         return casing;
    102     }
    103 
    104     private static LineElement createImpl(Environment env, LineType type) {
    105         Cascade c = env.mc.getCascade(env.layer);
    106         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         }
    135         if (width == null)
    136             return null;
    137 
    138         float realWidth = c.get(type.prefix + REAL_WIDTH, 0f, Float.class);
    139         if (realWidth > 0 && MapPaintSettings.INSTANCE.isUseRealWidth()) {
    140 
    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         }
    178 
    179         int alpha = 255;
    180         Color color = c.get(type.prefix + COLOR, null, Color.class);
    181         if (color != null) {
    182             alpha = color.getAlpha();
    183         }
    184         if (type == LineType.NORMAL && color == null) {
    185             color = c.get(FILL_COLOR, null, Color.class);
    186         }
    187         if (color == null) {
    188             color = PaintColors.UNTAGGED.get();
    189         }
    190 
    191         Integer pAlpha = Utils.color_float2int(c.get(type.prefix + OPACITY, null, Float.class));
    192         if (pAlpha != null) {
    193             alpha = pAlpha;
    194         }
    195         color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
    196 
    197         float[] dashes = c.get(type.prefix + DASHES, null, float[].class, true);
    198         if (dashes != null) {
    199             boolean hasPositive = false;
    200             for (float f : dashes) {
    201                 if (f > 0) {
    202                     hasPositive = true;
    203                 }
    204                 if (f < 0) {
    205                     dashes = null;
    206                     break;
    207                 }
    208             }
    209             if (!hasPositive || (dashes != null && dashes.length == 0)) {
    210                 dashes = null;
    211             }
    212         }
    213         float dashesOffset = c.get(type.prefix + DASHES_OFFSET, 0f, Float.class);
    214         Color dashesBackground = c.get(type.prefix + DASHES_BACKGROUND_COLOR, null, Color.class);
    215         if (dashesBackground != null) {
    216             pAlpha = Utils.color_float2int(c.get(type.prefix + DASHES_BACKGROUND_OPACITY, null, Float.class));
    217             if (pAlpha != null) {
    218                 alpha = pAlpha;
    219             }
    220             dashesBackground = new Color(dashesBackground.getRed(), dashesBackground.getGreen(),
    221                     dashesBackground.getBlue(), alpha);
    222         }
    223 
    224         Integer cap = null;
    225         Keyword capKW = c.get(type.prefix + LINECAP, null, Keyword.class);
    226         if (capKW != null) {
    227             if ("none".equals(capKW.val)) {
    228                 cap = BasicStroke.CAP_BUTT;
    229             } else if ("round".equals(capKW.val)) {
    230                 cap = BasicStroke.CAP_ROUND;
    231             } else if ("square".equals(capKW.val)) {
    232                 cap = BasicStroke.CAP_SQUARE;
    233             }
    234         }
    235         if (cap == null) {
    236             cap = dashes != null ? BasicStroke.CAP_BUTT : BasicStroke.CAP_ROUND;
    237         }
    238 
    239         Integer join = null;
    240         Keyword joinKW = c.get(type.prefix + LINEJOIN, null, Keyword.class);
    241         if (joinKW != null) {
    242             if ("round".equals(joinKW.val)) {
    243                 join = BasicStroke.JOIN_ROUND;
    244             } else if ("miter".equals(joinKW.val)) {
    245                 join = BasicStroke.JOIN_MITER;
    246             } else if ("bevel".equals(joinKW.val)) {
    247                 join = BasicStroke.JOIN_BEVEL;
    248             }
    249         }
    250         if (join == null) {
    251             join = BasicStroke.JOIN_ROUND;
    252         }
    253 
    254         float miterlimit = c.get(type.prefix + MITERLIMIT, 10f, Float.class);
    255         if (miterlimit < 1f) {
    256             miterlimit = 10f;
    257         }
    258 
    259         BasicStroke line = new BasicStroke(width, cap, join, miterlimit, dashes, dashesOffset);
    260         BasicStroke dashesLine = null;
    261 
    262         if (dashes != null && dashesBackground != null) {
    263             float[] dashes2 = new float[dashes.length];
    264             System.arraycopy(dashes, 0, dashes2, 1, dashes.length - 1);
    265             dashes2[0] = dashes[dashes.length-1];
    266             dashesLine = new BasicStroke(width, cap, join, miterlimit, dashes2, dashes2[0] + dashesOffset);
    267         }
    268 
    269         boolean wayDirectionArrows = c.get(type.prefix + WAY_DIRECTION_ARROWS, env.osm.isSelected(), Boolean.class);
    270 
    271         return new LineElement(c, type.defaultMajorZIndex, line, color, dashesLine, dashesBackground,
    272                 offset, realWidth, wayDirectionArrows);
    27366    }
    27467
     
    339132    public boolean isProperLineStyle() {
    340133        return !isModifier;
     134    }
     135
     136    public String linejoinToString(int linejoin) {
     137        switch (linejoin) {
     138            case BasicStroke.JOIN_BEVEL: return "bevel";
     139            case BasicStroke.JOIN_ROUND: return "round";
     140            case BasicStroke.JOIN_MITER: return "miter";
     141            default: return null;
     142        }
     143    }
     144
     145    public String linecapToString(int linecap) {
     146        switch (linecap) {
     147            case BasicStroke.CAP_BUTT: return "none";
     148            case BasicStroke.CAP_ROUND: return "round";
     149            case BasicStroke.CAP_SQUARE: return "square";
     150            default: return null;
     151        }
    341152    }
    342153
     
    375186    }
    376187
    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;
    383         }
    384     }
    385 
    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         }
     188    /**
     189     * Creates a simple line with default widt.
     190     * @param color The color to use
     191     * @param isAreaEdge If this is an edge for an area. Edges are drawn at lower Z-Index.
     192     * @return The line style.
     193     */
     194    public static LineElement createSimpleLineStyle(Color color, boolean isAreaEdge) {
     195        MultiCascade mc = new MultiCascade();
     196        Cascade c = mc.getOrCreateCascade("default");
     197        c.put(WIDTH, Keyword.DEFAULT);
     198        c.put(COLOR, color != null ? color : PaintColors.UNTAGGED.get());
     199        c.put(OPACITY, 1f);
     200        if (isAreaEdge) {
     201            c.put(Z_INDEX, -3f);
     202        }
     203        Way w = new Way();
     204        return createLine(new Environment(w, mc, "default", null));
     205    }
     206
     207    public static LineElement createLine(Environment env) {
     208        return createImpl(env, LineType.NORMAL);
     209    }
     210
     211    public static LineElement createLeftCasing(Environment env) {
     212        LineElement leftCasing = createImpl(env, LineType.LEFT_CASING);
     213        if (leftCasing != null) {
     214            leftCasing.isModifier = true;
     215        }
     216        return leftCasing;
     217    }
     218
     219    public static LineElement createRightCasing(Environment env) {
     220        LineElement rightCasing = createImpl(env, LineType.RIGHT_CASING);
     221        if (rightCasing != null) {
     222            rightCasing.isModifier = true;
     223        }
     224        return rightCasing;
     225    }
     226
     227    public static LineElement createCasing(Environment env) {
     228        LineElement casing = createImpl(env, LineType.CASING);
     229        if (casing != null) {
     230            casing.isModifier = true;
     231        }
     232        return casing;
     233    }
     234
     235    private static LineElement createImpl(Environment env, LineType type) {
     236        Cascade c = env.mc.getCascade(env.layer);
     237        Cascade cDef = env.mc.getCascade("default");
     238        Float width = computeWidth(type, c, cDef);
     239        if (width == null)
     240            return null;
     241
     242        float realWidth = computeRealWidth(env, type, c);
     243
     244        Float offset = computeOffset(type, c, cDef, width);
     245
     246        int alpha = 255;
     247        Color color = c.get(type.prefix + COLOR, null, Color.class);
     248        if (color != null) {
     249            alpha = color.getAlpha();
     250        }
     251        if (type == LineType.NORMAL && color == null) {
     252            color = c.get(FILL_COLOR, null, Color.class);
     253        }
     254        if (color == null) {
     255            color = PaintColors.UNTAGGED.get();
     256        }
     257
     258        Integer pAlpha = Utils.color_float2int(c.get(type.prefix + OPACITY, null, Float.class));
     259        if (pAlpha != null) {
     260            alpha = pAlpha;
     261        }
     262        color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
     263
     264        float[] dashes = c.get(type.prefix + DASHES, null, float[].class, true);
     265        if (dashes != null) {
     266            boolean hasPositive = false;
     267            for (float f : dashes) {
     268                if (f > 0) {
     269                    hasPositive = true;
     270                }
     271                if (f < 0) {
     272                    dashes = null;
     273                    break;
     274                }
     275            }
     276            if (!hasPositive || (dashes != null && dashes.length == 0)) {
     277                dashes = null;
     278            }
     279        }
     280        float dashesOffset = c.get(type.prefix + DASHES_OFFSET, 0f, Float.class);
     281        Color dashesBackground = c.get(type.prefix + DASHES_BACKGROUND_COLOR, null, Color.class);
     282        if (dashesBackground != null) {
     283            pAlpha = Utils.color_float2int(c.get(type.prefix + DASHES_BACKGROUND_OPACITY, null, Float.class));
     284            if (pAlpha != null) {
     285                alpha = pAlpha;
     286            }
     287            dashesBackground = new Color(dashesBackground.getRed(), dashesBackground.getGreen(),
     288                    dashesBackground.getBlue(), alpha);
     289        }
     290
     291        Integer cap = null;
     292        Keyword capKW = c.get(type.prefix + LINECAP, null, Keyword.class);
     293        if (capKW != null) {
     294            if ("none".equals(capKW.val)) {
     295                cap = BasicStroke.CAP_BUTT;
     296            } else if ("round".equals(capKW.val)) {
     297                cap = BasicStroke.CAP_ROUND;
     298            } else if ("square".equals(capKW.val)) {
     299                cap = BasicStroke.CAP_SQUARE;
     300            }
     301        }
     302        if (cap == null) {
     303            cap = dashes != null ? BasicStroke.CAP_BUTT : BasicStroke.CAP_ROUND;
     304        }
     305
     306        Integer join = null;
     307        Keyword joinKW = c.get(type.prefix + LINEJOIN, null, Keyword.class);
     308        if (joinKW != null) {
     309            if ("round".equals(joinKW.val)) {
     310                join = BasicStroke.JOIN_ROUND;
     311            } else if ("miter".equals(joinKW.val)) {
     312                join = BasicStroke.JOIN_MITER;
     313            } else if ("bevel".equals(joinKW.val)) {
     314                join = BasicStroke.JOIN_BEVEL;
     315            }
     316        }
     317        if (join == null) {
     318            join = BasicStroke.JOIN_ROUND;
     319        }
     320
     321        float miterlimit = c.get(type.prefix + MITERLIMIT, 10f, Float.class);
     322        if (miterlimit < 1f) {
     323            miterlimit = 10f;
     324        }
     325
     326        BasicStroke line = new BasicStroke(width, cap, join, miterlimit, dashes, dashesOffset);
     327        BasicStroke dashesLine = null;
     328
     329        if (dashes != null && dashesBackground != null) {
     330            float[] dashes2 = new float[dashes.length];
     331            System.arraycopy(dashes, 0, dashes2, 1, dashes.length - 1);
     332            dashes2[0] = dashes[dashes.length-1];
     333            dashesLine = new BasicStroke(width, cap, join, miterlimit, dashes2, dashes2[0] + dashesOffset);
     334        }
     335
     336        boolean wayDirectionArrows = c.get(type.prefix + WAY_DIRECTION_ARROWS, env.osm.isSelected(), Boolean.class);
     337
     338        return new LineElement(c, type.defaultMajorZIndex, line, color, dashesLine, dashesBackground,
     339                offset, realWidth, wayDirectionArrows);
     340    }
     341
     342    private static Float computeWidth(LineType type, Cascade c, Cascade cDef) {
     343        Float width;
     344        switch (type) {
     345            case NORMAL:
     346                width = getWidth(c, WIDTH, getWidth(cDef, WIDTH, null));
     347                break;
     348            case CASING:
     349                Float casingWidth = c.get(type.prefix + WIDTH, null, Float.class, true);
     350                if (casingWidth == null) {
     351                    RelativeFloat relCasingWidth = c.get(type.prefix + WIDTH, null, RelativeFloat.class, true);
     352                    if (relCasingWidth != null) {
     353                        casingWidth = relCasingWidth.val / 2;
     354                    }
     355                }
     356                if (casingWidth == null)
     357                    return null;
     358                width = getWidth(c, WIDTH, getWidth(cDef, WIDTH, null));
     359                if (width == null) {
     360                    width = 0f;
     361                }
     362                width += 2 * casingWidth;
     363                break;
     364            case LEFT_CASING:
     365            case RIGHT_CASING:
     366                width = getWidth(c, type.prefix + WIDTH, null);
     367                break;
     368            default:
     369                throw new AssertionError();
     370        }
     371        return width;
     372    }
     373
     374    private static float computeRealWidth(Environment env, LineType type, Cascade c) {
     375        float realWidth = c.get(type.prefix + REAL_WIDTH, 0f, Float.class);
     376        if (realWidth > 0 && MapPaintSettings.INSTANCE.isUseRealWidth()) {
     377
     378            /* if we have a "width" tag, try use it */
     379            String widthTag = env.osm.get("width");
     380            if (widthTag == null) {
     381                widthTag = env.osm.get("est_width");
     382            }
     383            if (widthTag != null) {
     384                try {
     385                    realWidth = Float.parseFloat(widthTag);
     386                } catch (NumberFormatException nfe) {
     387                    Main.warn(nfe);
     388                }
     389            }
     390        }
     391        return realWidth;
     392    }
     393
     394    private static Float computeOffset(LineType type, Cascade c, Cascade cDef, Float width) {
     395        Float offset = c.get(OFFSET, 0f, Float.class);
     396        switch (type) {
     397            case NORMAL:
     398                break;
     399            case CASING:
     400                offset += c.get(type.prefix + OFFSET, 0f, Float.class);
     401                break;
     402            case LEFT_CASING:
     403            case RIGHT_CASING:
     404                Float baseWidthOnDefault = getWidth(cDef, WIDTH, null);
     405                Float baseWidth = getWidth(c, WIDTH, baseWidthOnDefault);
     406                if (baseWidth == null || baseWidth < 2f) {
     407                    baseWidth = 2f;
     408                }
     409                float casingOffset = c.get(type.prefix + OFFSET, 0f, Float.class);
     410                casingOffset += baseWidth / 2 + width / 2;
     411                /* flip sign for the right-casing-offset */
     412                if (type == LineType.RIGHT_CASING) {
     413                    casingOffset *= -1f;
     414                }
     415                offset += casingOffset;
     416                break;
     417        }
     418        return offset;
    393419    }
    394420}
Note: See TracChangeset for help on using the changeset viewer.