View Javadoc

1   package org.vectomatic.dom.svg.impl;
2   
3   import java.util.ArrayList;
4   import java.util.HashMap;
5   import java.util.List;
6   import java.util.Map;
7   
8   import org.vectomatic.dom.svg.OMCSSPrimitiveValue;
9   import org.vectomatic.dom.svg.OMCSSValue;
10  import org.vectomatic.dom.svg.OMCSSValueList;
11  import org.vectomatic.dom.svg.utils.SVGConstants;
12  
13  import com.google.gwt.core.client.JavaScriptException;
14  import com.google.gwt.regexp.shared.MatchResult;
15  import com.google.gwt.regexp.shared.RegExp;
16  
17  /**
18   * Class to parse SVG dash arrays. Do not call this class directly,
19   * it will be removed when browser provide good native support for it.
20   * Following is the BNF grammar of the expression supported.
21   * <pre>
22   * dasharray ::= (length | percentage) (comma-wsp dasharray)?
23   * length ::= number (~"em" | ~"ex" | ~"px" | ~"in" | ~"cm" | ~"mm" | ~"pt" | ~"pc")?
24   * length ::= number ("em" | "ex" | "px" | "in" | "cm" | "mm" | "pt" | "pc" | "%")?
25   * number ::= integer | [+-]? [0-9]* "." [0-9]+
26   * </pre>
27   * @author laaglu
28   */
29  public class DashArrayParser {
30  	private static final String WS = "\\s*";
31  	private static final String COMMA = WS + "," + WS;
32  	private static final RegExp LENGTH = RegExp.compile("^[+-]?((?:0|[1-9][0-9]*)(?:\\.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc|%)?$", "i");
33  	public static final DashArrayParser INSTANCE = new DashArrayParser();
34  	private Map<String, Short> unitToPrimitiveType;
35  
36  	private DashArrayParser() {
37  		unitToPrimitiveType = new HashMap<String, Short>();
38  		unitToPrimitiveType.put("em", OMCSSPrimitiveValue.CSS_EMS);
39  		unitToPrimitiveType.put("ex", OMCSSPrimitiveValue.CSS_EXS);
40  		unitToPrimitiveType.put("px", OMCSSPrimitiveValue.CSS_PX);
41  		unitToPrimitiveType.put("in", OMCSSPrimitiveValue.CSS_IN);
42  		unitToPrimitiveType.put("cm", OMCSSPrimitiveValue.CSS_CM);
43  		unitToPrimitiveType.put("mm", OMCSSPrimitiveValue.CSS_MM);
44  		unitToPrimitiveType.put("pt", OMCSSPrimitiveValue.CSS_PT);
45  		unitToPrimitiveType.put("pc", OMCSSPrimitiveValue.CSS_PC);
46  		unitToPrimitiveType.put("%", OMCSSPrimitiveValue.CSS_PERCENTAGE);
47  	}
48  	
49  	public OMCSSValue parse(String cssText) {
50  		OMCSSValue[] values = null;
51  		if (SVGConstants.CSS_NONE_VALUE.equals(cssText) || cssText == null || cssText.length() == 0) {
52  			return new OMCSSPrimitiveValue(cssText, OMCSSPrimitiveValue.CSS_IDENT);
53  		} else if (SVGConstants.CSS_INHERIT_VALUE.equals(cssText)) {
54  			return new OMCSSPrimitiveValue(cssText, OMCSSPrimitiveValue.CSS_IDENT);
55  		}
56  		
57  		List<OMCSSPrimitiveValue> lengths = new ArrayList<OMCSSPrimitiveValue>();
58  		String[] lengthArray = cssText.split(COMMA);
59  		for (int i = 0; i < lengthArray.length; i++) {
60  			if (lengthArray[i].length() > 0) {
61  				LENGTH.setLastIndex(0);
62  				String length = lengthArray[i].trim();
63  				MatchResult result = LENGTH.exec(length);
64  				if (result != null && result.getGroupCount() == 3) {
65  					short primitiveType = OMCSSPrimitiveValue.CSS_NUMBER;
66  					String unit = result.getGroup(2);
67  					if (unit != null) {
68  						primitiveType = unitToPrimitiveType.get(unit.toLowerCase());
69  					}
70  					float value = Float.parseFloat(result.getGroup(1));
71  					lengths.add(new OMCSSPrimitiveValue(value, primitiveType));
72  				} else {
73  					throw new JavaScriptException("Invalid length spec: " + length);
74  				}
75  			}
76  		}
77  		values = lengths.toArray(new OMCSSValue[lengths.size()]);
78  		return new OMCSSValueList(values, cssText);
79  	}
80  }