// The 'clipPath' element or any of its children can specify
// property 'clip-path'.
//
Area clipPath = new Area();
GVTBuilder builder = ctx.getGVTBuilder();
GVTFactory gvtFactory = ctx.getGVTFactory();
// parse the transform attribute
AffineTransform Tx =
SVGUtilities.convertAffineTransform(clipElement,
ATTR_TRANSFORM,
ctx.getParserFactory());
// parse the clipPathUnits attribute
Viewport oldViewport = ctx.getCurrentViewport();
String units = clipElement.getAttributeNS(null, ATTR_CLIP_PATH_UNITS);
if (units.length() == 0) {
units = VALUE_USER_SPACE_ON_USE;
}
int unitsType;
try {
unitsType = SVGUtilities.parseCoordinateSystem(units);
} catch (IllegalArgumentException ex) {
throw new IllegalAttributeValueException(
Messages.formatMessage("clipPath.units.invalid",
new Object[] {units,
ATTR_CLIP_PATH_UNITS}));
}
if (unitsType == SVGUtilities.OBJECT_BOUNDING_BOX) {
// units are resolved using objectBoundingBox
ctx.setCurrentViewport(new ObjectBoundingBoxViewport());
}
// compute an additional transform related the clipPathUnits
Tx = SVGUtilities.convertAffineTransform(Tx, gn, unitsType);
// build the clipPath according to the clipPath's children
boolean hasChildren = false;
for(Node node=clipElement.getFirstChild();
node != null;
node = node.getNextSibling()){
// check if the node is a valid Element
if (node.getNodeType() != node.ELEMENT_NODE) {
continue;
}
Element child = (Element)node;
GraphicsNode clipNode = builder.build(ctx, child) ;
// check if a GVT node has been created
if (clipNode == null) {
throw new IllegalAttributeValueException(
Messages.formatMessage("clipPath.subelement.illegal",
new Object[] {node.getLocalName()}));
}
hasChildren = true;
// compute the outline of the current Element
CSSStyleDeclaration c =
ctx.getViewCSS().getComputedStyle(child, null);
CSSPrimitiveValue v = (CSSPrimitiveValue)c.getPropertyCSSValue
(CSS_CLIP_RULE_PROPERTY);
int wr = (CSSUtilities.rule(v) == CSSUtilities.RULE_NONZERO)
? GeneralPath.WIND_NON_ZERO
: GeneralPath.WIND_EVEN_ODD;
GeneralPath path = new GeneralPath(clipNode.getOutline());
path.setWindingRule(wr);
Shape outline = Tx.createTransformedShape(path);
// apply the clip-path of the current Element
ShapeNode outlineNode = gvtFactory.createShapeNode();
outlineNode.setShape(outline);
Clip clip = CSSUtilities.convertClipPath(child,
outlineNode,
ctx);
if (clip != null) {
Area area = new Area(outline);
area.subtract(new Area(clip.getClipPath()));
outline = area;
}
clipPath.add(new Area(outline));
}
// restore the viewport
ctx.setCurrentViewport(oldViewport);
if (!hasChildren) {
return null; // no clipPath defined
}
// apply the clip-path of this clipPath Element (already in user space)
ShapeNode clipPathNode = gvtFactory.createShapeNode();
clipPathNode.setShape(clipPath);
Clip clipElementClipPath =
CSSUtilities.convertClipPath(clipElement, clipPathNode, ctx);
if (clipElementClipPath != null) {
clipPath.subtract(new Area(clipElementClipPath.getClipPath()));