source: josm/trunk/src/com/kitfox/svg/xml/XMLParseUtil.java@ 14331

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

see #14319, see #16838 - fix regressions introduced in svgSalamander 1.1.2

see https://github.com/blackears/svgSalamander/issues/29

  • Property svn:eol-style set to native
File size: 9.4 KB
Line 
1/*
2 * SVG Salamander
3 * Copyright (c) 2004, Mark McKay
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
9 *
10 * - Redistributions of source code must retain the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
32 * projects can be found at http://www.kitfox.com
33 *
34 * Created on February 18, 2004, 1:49 PM
35 */
36
37package com.kitfox.svg.xml;
38
39import java.awt.Toolkit;
40import java.util.HashMap;
41import java.util.Iterator;
42import java.util.LinkedList;
43import java.util.logging.Level;
44import java.util.logging.Logger;
45import java.util.regex.Matcher;
46import java.util.regex.Pattern;
47
48import com.kitfox.svg.SVGConst;
49
50/**
51 * @author Mark McKay
52 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
53 */
54public class XMLParseUtil
55{
56 static final Matcher fpMatch = Pattern.compile("([-+]?((\\d*\\.\\d+)|(\\d+))([eE][+-]?\\d+)?)(\\%|in|cm|mm|pt|pc|px|em|ex)?").matcher("");
57 static final Matcher intMatch = Pattern.compile("[-+]?\\d+").matcher("");
58 static final Matcher quoteMatch = Pattern.compile("^'|'$").matcher("");
59
60 /** Creates a new instance of XMLParseUtil */
61 private XMLParseUtil()
62 {
63 }
64
65 public static String[] parseStringList(String list)
66 {
67 final Matcher matchWs = Pattern.compile("[^\\s]+").matcher("");
68 matchWs.reset(list);
69
70 LinkedList<String> matchList = new LinkedList<>();
71 while (matchWs.find())
72 {
73 matchList.add(matchWs.group());
74 }
75
76 String[] retArr = new String[matchList.size()];
77 return matchList.toArray(retArr);
78 }
79
80 public static double parseDouble(String val)
81 {
82 return findDouble(val);
83 }
84
85 /**
86 * Searches the given string for the first floating point number it contains,
87 * parses and returns it.
88 */
89 public synchronized static double findDouble(String val)
90 {
91 if (val == null) return 0;
92
93 fpMatch.reset(val);
94 try
95 {
96 if (!fpMatch.find()) return 0;
97 }
98 catch (StringIndexOutOfBoundsException e)
99 {
100 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
101 "XMLParseUtil: regex parse problem: '" + val + "'", e);
102 }
103
104 val = fpMatch.group(1);
105 //System.err.println("Parsing " + val);
106
107 double retVal = 0;
108 try
109 {
110 retVal = Double.parseDouble(val);
111
112 float pixPerInch;
113 try {
114 pixPerInch = Toolkit.getDefaultToolkit().getScreenResolution();
115 }
116 catch (NoClassDefFoundError err)
117 {
118 //Default value for headless X servers
119 pixPerInch = 72;
120 }
121 final float inchesPerCm = .3936f;
122 final String units = fpMatch.group(6);
123
124 if ("%".equals(units)) retVal /= 100;
125 else if ("in".equals(units))
126 {
127 retVal *= pixPerInch;
128 }
129 else if ("cm".equals(units))
130 {
131 retVal *= inchesPerCm * pixPerInch;
132 }
133 else if ("mm".equals(units))
134 {
135 retVal *= inchesPerCm * pixPerInch * .1f;
136 }
137 else if ("pt".equals(units))
138 {
139 retVal *= (1f / 72f) * pixPerInch;
140 }
141 else if ("pc".equals(units))
142 {
143 retVal *= (1f / 6f) * pixPerInch;
144 }
145 }
146 catch (Exception e)
147 {}
148 return retVal;
149 }
150
151 /**
152 * Scans an input string for double values. For each value found, places
153 * in a list. This method regards any characters not part of a floating
154 * point value to be seperators. Thus this will parse whitespace seperated,
155 * comma seperated, and many other separation schemes correctly.
156 */
157 public synchronized static double[] parseDoubleList(String list)
158 {
159 if (list == null) return null;
160
161 fpMatch.reset(list);
162
163 LinkedList<Double> doubList = new LinkedList<>();
164 while (fpMatch.find())
165 {
166 String val = fpMatch.group(1);
167 doubList.add(Double.valueOf(val));
168 }
169
170 double[] retArr = new double[doubList.size()];
171 Iterator<Double> it = doubList.iterator();
172 int idx = 0;
173 while (it.hasNext())
174 {
175 retArr[idx++] = it.next().doubleValue();
176 }
177
178 return retArr;
179 }
180
181 /**
182 * Searches the given string for the first floating point number it contains,
183 * parses and returns it.
184 */
185 public synchronized static float findFloat(String val)
186 {
187 if (val == null) return 0f;
188
189 fpMatch.reset(val);
190 if (!fpMatch.find()) return 0f;
191
192 val = fpMatch.group(1);
193 //System.err.println("Parsing " + val);
194
195 float retVal = 0f;
196 try
197 {
198 retVal = Float.parseFloat(val);
199 String units = fpMatch.group(6);
200 if ("%".equals(units)) retVal /= 100;
201 }
202 catch (Exception e)
203 {}
204 return retVal;
205 }
206
207 public synchronized static float[] parseFloatList(String list)
208 {
209 if (list == null) return null;
210
211 fpMatch.reset(list);
212
213 LinkedList<Float> floatList = new LinkedList<>();
214 while (fpMatch.find())
215 {
216 String val = fpMatch.group(1);
217 floatList.add(Float.valueOf(val));
218 }
219
220 float[] retArr = new float[floatList.size()];
221 Iterator<Float> it = floatList.iterator();
222 int idx = 0;
223 while (it.hasNext())
224 {
225 retArr[idx++] = it.next().floatValue();
226 }
227
228 return retArr;
229 }
230
231 /**
232 * Searches the given string for the first integer point number it contains,
233 * parses and returns it.
234 */
235 public static int findInt(String val)
236 {
237 if (val == null) return 0;
238
239 intMatch.reset(val);
240 if (!intMatch.find()) return 0;
241
242 val = intMatch.group();
243
244 int retVal = 0;
245 try
246 { retVal = Integer.parseInt(val); }
247 catch (Exception e)
248 {}
249 return retVal;
250 }
251
252 public static int[] parseIntList(String list)
253 {
254 if (list == null) return null;
255
256 intMatch.reset(list);
257
258 LinkedList<Integer> intList = new LinkedList<>();
259 while (intMatch.find())
260 {
261 String val = intMatch.group();
262 intList.add(Integer.valueOf(val));
263 }
264
265 int[] retArr = new int[intList.size()];
266 Iterator<Integer> it = intList.iterator();
267 int idx = 0;
268 while (it.hasNext())
269 {
270 retArr[idx++] = it.next().intValue();
271 }
272
273 return retArr;
274 }
275
276 /**
277 * The input string represents a ratio. Can either be specified as a
278 * double number on the range of [0.0 1.0] or as a percentage [0% 100%]
279 */
280 public static double parseRatio(String val)
281 {
282 if (val == null || val.equals("")) return 0.0;
283
284 if (val.charAt(val.length() - 1) == '%')
285 {
286 parseDouble(val.substring(0, val.length() - 1));
287 }
288 return parseDouble(val);
289 }
290
291 public static NumberWithUnits parseNumberWithUnits(String val)
292 {
293 if (val == null) return null;
294
295 return new NumberWithUnits(val);
296 }
297
298 /**
299 * Takes a CSS style string and returns a hash of them.
300 * @param styleString - A CSS formatted string of styles. Eg,
301 * "font-size:12;fill:#d32c27;fill-rule:evenodd;stroke-width:1pt;"
302 * @param map - A map to which these styles will be added
303 */
304 public static HashMap<String, StyleAttribute> parseStyle(String styleString, HashMap<String, StyleAttribute> map) {
305 final Pattern patSemi = Pattern.compile(";");
306
307 String[] styles = patSemi.split(styleString);
308
309 for (int i = 0; i < styles.length; i++)
310 {
311 if (styles[i].length() == 0)
312 {
313 continue;
314 }
315
316 int colon = styles[i].indexOf(':');
317 if (colon == -1)
318 {
319 continue;
320 }
321
322 String key = styles[i].substring(0, colon).trim();
323 String value = quoteMatch.reset(styles[i].substring(colon + 1).trim()).replaceAll("");
324
325 map.put(key, new StyleAttribute(key, value));
326 }
327
328 return map;
329 }
330}
Note: See TracBrowser for help on using the repository browser.