1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.data.preferences;
|
---|
3 |
|
---|
4 | import java.awt.BasicStroke;
|
---|
5 | import java.util.Collections;
|
---|
6 | import java.util.List;
|
---|
7 | import java.util.regex.Pattern;
|
---|
8 | import java.util.stream.Collectors;
|
---|
9 |
|
---|
10 | import org.openstreetmap.josm.Main;
|
---|
11 |
|
---|
12 | /**
|
---|
13 | * A property that stores a {@link BasicStroke}.
|
---|
14 | * @author Michael Zangl
|
---|
15 | * @since 10874
|
---|
16 | */
|
---|
17 | public class StrokeProperty extends AbstractToStringProperty<BasicStroke> {
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * Create a new stroke property from a string.
|
---|
21 | * @param key The key to use
|
---|
22 | * @param defaultValue The default stroke as string
|
---|
23 | */
|
---|
24 | public StrokeProperty(String key, String defaultValue) {
|
---|
25 | super(key, getFromString(defaultValue));
|
---|
26 | }
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * Create a new stroke property from a stroke object.
|
---|
30 | * @param key The key
|
---|
31 | * @param defaultStroke The default stroke.
|
---|
32 | */
|
---|
33 | public StrokeProperty(String key, BasicStroke defaultStroke) {
|
---|
34 | super(key, defaultStroke);
|
---|
35 | }
|
---|
36 |
|
---|
37 | @Override
|
---|
38 | protected BasicStroke fromString(String string) {
|
---|
39 | return getFromString(string);
|
---|
40 | }
|
---|
41 |
|
---|
42 | @Override
|
---|
43 | protected String toString(BasicStroke t) {
|
---|
44 | StringBuilder string = new StringBuilder();
|
---|
45 | string.append(t.getLineWidth());
|
---|
46 |
|
---|
47 | float[] dashes = t.getDashArray();
|
---|
48 | if (dashes != null) {
|
---|
49 | for (float d : dashes) {
|
---|
50 | string.append(' ').append(d);
|
---|
51 | }
|
---|
52 | }
|
---|
53 |
|
---|
54 | return string.toString();
|
---|
55 | }
|
---|
56 |
|
---|
57 | /**
|
---|
58 | * Return s new BasicStroke object with given thickness and style
|
---|
59 | * @param code = 3.5 -> thickness=3.5px; 3.5 10 5 -> thickness=3.5px, dashed: 10px filled + 5px empty
|
---|
60 | * @return stroke for drawing
|
---|
61 | */
|
---|
62 | public static BasicStroke getFromString(String code) {
|
---|
63 | Pattern floatPattern = Pattern.compile("(\\.\\d+|\\d+(\\.\\d+)?)");
|
---|
64 |
|
---|
65 | List<Double> captures = Pattern.compile("[^\\d.]+").splitAsStream(code)
|
---|
66 | .filter(s -> floatPattern.matcher(s).matches())
|
---|
67 | .map(Double::valueOf).collect(Collectors.toList());
|
---|
68 |
|
---|
69 | double w = 1;
|
---|
70 | List<Double> dashes = Collections.emptyList();
|
---|
71 | if (!captures.isEmpty()) {
|
---|
72 | w = captures.get(0);
|
---|
73 | dashes = captures.subList(1, captures.size());
|
---|
74 | }
|
---|
75 |
|
---|
76 | if (!dashes.isEmpty()) {
|
---|
77 | double sumAbs = dashes.stream().mapToDouble(Math::abs).sum();
|
---|
78 |
|
---|
79 | if (sumAbs < 1e-1) {
|
---|
80 | Main.error("Error in stroke dash format (all zeros): " + code);
|
---|
81 | dashes = Collections.emptyList();
|
---|
82 | }
|
---|
83 | }
|
---|
84 |
|
---|
85 | int cap;
|
---|
86 | int join;
|
---|
87 | if (w > 1) {
|
---|
88 | // thick stroke
|
---|
89 | cap = BasicStroke.CAP_ROUND;
|
---|
90 | join = BasicStroke.JOIN_ROUND;
|
---|
91 | } else {
|
---|
92 | // thin stroke
|
---|
93 | cap = BasicStroke.CAP_BUTT;
|
---|
94 | join = BasicStroke.JOIN_MITER;
|
---|
95 | }
|
---|
96 |
|
---|
97 | return new BasicStroke((float) w, cap, join, 10.0f, toDashArray(dashes), 0.0f);
|
---|
98 | }
|
---|
99 |
|
---|
100 | private static float[] toDashArray(List<Double> dashes) {
|
---|
101 | if (dashes.isEmpty()) {
|
---|
102 | return null;
|
---|
103 | } else {
|
---|
104 | float[] array = new float[dashes.size()];
|
---|
105 | for (int i = 0; i < array.length; i++) {
|
---|
106 | array[i] = (float) (double) dashes.get(i);
|
---|
107 | }
|
---|
108 | return array;
|
---|
109 | }
|
---|
110 | }
|
---|
111 | }
|
---|