SVG paint and stroke

The SVG standard provides a complete API to deal with various forms of paint (rgb colors, named colors, linear gradients, patterns, …) and this API integrates tightly with the CSS APIs to provide programmatic access to the various characteristics of the paint. The dash-array CSS property can also be introspected with the same CSS APIs.

In real web development however, things are not as easy as they should, because almost all browsers fail to implement correctly if at all at least some part of the specification. This is why I had not tried to incorporate this part of the specification in lib-gwt-svg so far.

If things were perfect, all one would have to write to access a color or the dash-array attribute would be:

<svg xmlns="http://www.w3.org/2000/svg">
<circle id="c1" style="fill:tomato;stroke:black;stroke-dasharray:2mm,1mm" cx="10" cy="10" r="5"/>
</svg>
var circle = document.getElementById('c1');
var paint = circle.style.getCSSPropertyValue('fill');
var green = paint.rgbColor.green;
var greenValue = green.getFloatValue(green.primitiveType);
var dash1 = circle.style.getCSSPropertyValue('dash-array').item(0);
var dash1Value = dash1.getFloatValue(dash1.primitiveType);

In the real world, the code above does not run well in most browsers:

Browser Result
Firefox 4+ getCSSPropertyValue works only for computedStyle, not style
Chrome 14+ Works correctly
Opera 10+ Not supported (exception thrown)
IE9+ Not tested

In version 0.5.3 of lib-gwt-svg, I have developed a few classes to emulate most of the behavior of SVGPaint and CSSValue and map it to GWT. The implementation is based on parsing the css text value of the css properties to create a small graph of objects representing the color. The shortcoming of this approach is that this graph is an emulation: changing it will not affect the original CSS property. With this restriction in mind, it is now possible however to write applications which manipulate SVG paint and dash arrays, in a portable way. If browser implementations make enough progress, I plan to switch to the native implementation.

Here is sample code which uses it:

OMSVGCircleElement circle = (OMSVGCircleElement)OMSVGParser.currentDocument().getElementById("c1");
OMSVGPaint paint = (OMSVGPaint)circle.getStyle().getSVGPropertyCSS(SVGConstants.CSS_FILL_PROPERTY);
OMRGBColor green = paint.getRgbColor().getGreen();
float greenValue = green.getFloatValue(green.getPrimitiveType());
OMCSSValueList dashArray = (OMCSSValueList)circle.getStyle().getSVGPropertyCSS(SVGConstants.CSS_STROKE_DASH_ARRAY_PROPERTY);
OMCSSPrimitiveValue dash1 = (OMCSSPrimitiveValue)dashArray.getItem(0);
float dash1Value = dash1.getFloatValue(dash1.getPrimitiveType());

To conclude this post, here is a pointer to the javadoc documentation of this API.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>