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

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

see #14319 - update to latest version of svgSalamander (2017-01-07, patched)

  • Property svn:eol-style set to native
File size: 9.3 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
59 /** Creates a new instance of XMLParseUtil */
60 private XMLParseUtil()
61 {
62 }
63
64 public static String[] parseStringList(String list)
65 {
66 final Matcher matchWs = Pattern.compile("[^\\s]+").matcher("");
67 matchWs.reset(list);
68
69 LinkedList<String> matchList = new LinkedList<>();
70 while (matchWs.find())
71 {
72 matchList.add(matchWs.group());
73 }
74
75 String[] retArr = new String[matchList.size()];
76 return matchList.toArray(retArr);
77 }
78
79 public static double parseDouble(String val)
80 {
81 return findDouble(val);
82 }
83
84 /**
85 * Searches the given string for the first floating point number it contains,
86 * parses and returns it.
87 */
88 public synchronized static double findDouble(String val)
89 {
90 if (val == null) return 0;
91
92 fpMatch.reset(val);
93 try
94 {
95 if (!fpMatch.find()) return 0;
96 }
97 catch (StringIndexOutOfBoundsException e)
98 {
99 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
100 "XMLParseUtil: regex parse problem: '" + val + "'", e);
101 }
102
103 val = fpMatch.group(1);
104 //System.err.println("Parsing " + val);
105
106 double retVal = 0;
107 try
108 {
109 retVal = Double.parseDouble(val);
110
111 float pixPerInch;
112 try {
113 pixPerInch = Toolkit.getDefaultToolkit().getScreenResolution();
114 }
115 catch (NoClassDefFoundError err)
116 {
117 //Default value for headless X servers
118 pixPerInch = 72;
119 }
120 final float inchesPerCm = .3936f;
121 final String units = fpMatch.group(6);
122
123 if ("%".equals(units)) retVal /= 100;
124 else if ("in".equals(units))
125 {
126 retVal *= pixPerInch;
127 }
128 else if ("cm".equals(units))
129 {
130 retVal *= inchesPerCm * pixPerInch;
131 }
132 else if ("mm".equals(units))
133 {
134 retVal *= inchesPerCm * pixPerInch * .1f;
135 }
136 else if ("pt".equals(units))
137 {
138 retVal *= (1f / 72f) * pixPerInch;
139 }
140 else if ("pc".equals(units))
141 {
142 retVal *= (1f / 6f) * pixPerInch;
143 }
144 }
145 catch (Exception e)
146 {}
147 return retVal;
148 }
149
150 /**
151 * Scans an input string for double values. For each value found, places
152 * in a list. This method regards any characters not part of a floating
153 * point value to be seperators. Thus this will parse whitespace seperated,
154 * comma seperated, and many other separation schemes correctly.
155 */
156 public synchronized static double[] parseDoubleList(String list)
157 {
158 if (list == null) return null;
159
160 fpMatch.reset(list);
161
162 LinkedList<Double> doubList = new LinkedList<>();
163 while (fpMatch.find())
164 {
165 String val = fpMatch.group(1);
166 doubList.add(Double.valueOf(val));
167 }
168
169 double[] retArr = new double[doubList.size()];
170 Iterator<Double> it = doubList.iterator();
171 int idx = 0;
172 while (it.hasNext())
173 {
174 retArr[idx++] = it.next().doubleValue();
175 }
176
177 return retArr;
178 }
179
180 /**
181 * Searches the given string for the first floating point number it contains,
182 * parses and returns it.
183 */
184 public synchronized static float findFloat(String val)
185 {
186 if (val == null) return 0f;
187
188 fpMatch.reset(val);
189 if (!fpMatch.find()) return 0f;
190
191 val = fpMatch.group(1);
192 //System.err.println("Parsing " + val);
193
194 float retVal = 0f;
195 try
196 {
197 retVal = Float.parseFloat(val);
198 String units = fpMatch.group(6);
199 if ("%".equals(units)) retVal /= 100;
200 }
201 catch (Exception e)
202 {}
203 return retVal;
204 }
205
206 public synchronized static float[] parseFloatList(String list)
207 {
208 if (list == null) return null;
209
210 fpMatch.reset(list);
211
212 LinkedList<Float> floatList = new LinkedList<>();
213 while (fpMatch.find())
214 {
215 String val = fpMatch.group(1);
216 floatList.add(Float.valueOf(val));
217 }
218
219 float[] retArr = new float[floatList.size()];
220 Iterator<Float> it = floatList.iterator();
221 int idx = 0;
222 while (it.hasNext())
223 {
224 retArr[idx++] = it.next().floatValue();
225 }
226
227 return retArr;
228 }
229
230 /**
231 * Searches the given string for the first integer point number it contains,
232 * parses and returns it.
233 */
234 public static int findInt(String val)
235 {
236 if (val == null) return 0;
237
238 intMatch.reset(val);
239 if (!intMatch.find()) return 0;
240
241 val = intMatch.group();
242
243 int retVal = 0;
244 try
245 { retVal = Integer.parseInt(val); }
246 catch (Exception e)
247 {}
248 return retVal;
249 }
250
251 public static int[] parseIntList(String list)
252 {
253 if (list == null) return null;
254
255 intMatch.reset(list);
256
257 LinkedList<Integer> intList = new LinkedList<>();
258 while (intMatch.find())
259 {
260 String val = intMatch.group();
261 intList.add(Integer.valueOf(val));
262 }
263
264 int[] retArr = new int[intList.size()];
265 Iterator<Integer> it = intList.iterator();
266 int idx = 0;
267 while (it.hasNext())
268 {
269 retArr[idx++] = it.next().intValue();
270 }
271
272 return retArr;
273 }
274
275 /**
276 * The input string represents a ratio. Can either be specified as a
277 * double number on the range of [0.0 1.0] or as a percentage [0% 100%]
278 */
279 public static double parseRatio(String val)
280 {
281 if (val == null || val.equals("")) return 0.0;
282
283 if (val.charAt(val.length() - 1) == '%')
284 {
285 parseDouble(val.substring(0, val.length() - 1));
286 }
287 return parseDouble(val);
288 }
289
290 public static NumberWithUnits parseNumberWithUnits(String val)
291 {
292 if (val == null) return null;
293
294 return new NumberWithUnits(val);
295 }
296
297 /**
298 * Takes a CSS style string and returns a hash of them.
299 * @param styleString - A CSS formatted string of styles. Eg,
300 * "font-size:12;fill:#d32c27;fill-rule:evenodd;stroke-width:1pt;"
301 * @param map - A map to which these styles will be added
302 */
303 public static HashMap<String, StyleAttribute> parseStyle(String styleString, HashMap<String, StyleAttribute> map) {
304 final Pattern patSemi = Pattern.compile(";");
305
306 String[] styles = patSemi.split(styleString);
307
308 for (int i = 0; i < styles.length; i++)
309 {
310 if (styles[i].length() == 0)
311 {
312 continue;
313 }
314
315 int colon = styles[i].indexOf(':');
316 if (colon == -1)
317 {
318 continue;
319 }
320
321 String key = styles[i].substring(0, colon).trim();
322 String value = styles[i].substring(colon + 1).trim();
323
324 map.put(key, new StyleAttribute(key, value));
325 }
326
327 return map;
328 }
329}
Note: See TracBrowser for help on using the repository browser.