in batik-bridge/src/main/java/org/apache/batik/bridge/SVGSVGElementBridge.java [441:574]
public List getIntersectionList(SVGRect svgRect, Element end) {
List ret = new ArrayList();
Rectangle2D rect = new Rectangle2D.Float(svgRect.getX(),
svgRect.getY(),
svgRect.getWidth(),
svgRect.getHeight());
GraphicsNode svgGN = ctx.getGraphicsNode(e);
if (svgGN == null) return ret;
Rectangle2D svgBounds = svgGN.getSensitiveBounds();
if (svgBounds == null)
return ret;
// If the svg elem doesn't intersect none of the children
// will.
if (!rect.intersects(svgBounds))
return ret;
Element base = e;
AffineTransform ati = svgGN.getGlobalTransform();
try {
ati = ati.createInverse();
} catch (NoninvertibleTransformException e) {
}
Element curr;
Node next = base.getFirstChild();
while (next != null) {
if (next instanceof Element)
break;
next = next.getNextSibling();
}
if (next == null) return ret;
curr = (Element)next;
Set ancestors = null;
if (end != null) {
ancestors = getAncestors(end, base);
if (ancestors == null)
end = null;
}
while (curr != null) {
String nsURI = curr.getNamespaceURI();
String tag = curr.getLocalName();
boolean isGroup;
isGroup = SVG_NAMESPACE_URI.equals(nsURI)
&& (SVG_G_TAG.equals(tag)
|| SVG_SVG_TAG.equals(tag)
|| SVG_A_TAG.equals(tag));
GraphicsNode gn = ctx.getGraphicsNode(curr);
if (gn == null) {
// No graphics node but check if curr is an
// ancestor of end.
if ((ancestors != null) && (ancestors.contains(curr)))
break;
curr = getNext(curr, base, end);
continue;
}
AffineTransform at = gn.getGlobalTransform();
Rectangle2D gnBounds = gn.getSensitiveBounds();
at.preConcatenate(ati);
if (gnBounds != null)
gnBounds = at.createTransformedShape(gnBounds).getBounds2D();
if ((gnBounds == null) ||
(!rect.intersects(gnBounds))) {
// Graphics node does not intersect check if curr is
// an ancestor of end.
if ((ancestors != null) && (ancestors.contains(curr)))
break;
curr = getNext(curr, base, end);
continue;
}
// Check if it is an SVG 'g', or 'svg' element in
// which case don't add this node but do check it's
// children.
if (isGroup) {
// Check children.
next = curr.getFirstChild();
while (next != null) {
if (next instanceof Element)
break;
next = next.getNextSibling();
}
if (next != null) {
curr = (Element)next;
continue;
}
} else {
if (curr == end) break;
// Otherwise check this node for intersection more
// carefully and if it still intersects add it.
if (SVG_NAMESPACE_URI.equals(nsURI)
&& SVG_USE_TAG.equals(tag)) {
// FIXX: This really isn't right we need to
// Add the proxy children.
if (rect.contains(gnBounds))
ret.add(curr);
} if (gn instanceof ShapeNode) {
ShapeNode sn = (ShapeNode)gn;
Shape sensitive = sn.getSensitiveArea();
if (sensitive != null) {
sensitive = at.createTransformedShape(sensitive);
if (sensitive.intersects(rect))
ret.add(curr);
}
} else if (gn instanceof TextNode) {
SVGOMElement svgElem = (SVGOMElement)curr;
SVGTextElementBridge txtBridge;
txtBridge = (SVGTextElementBridge)svgElem.getSVGContext();
Set elems = txtBridge.getTextIntersectionSet(at, rect);
// filter elems based on who is before end as
// children of curr, if needed.
if ((ancestors != null) && ancestors.contains(curr))
filterChildren(curr, end, elems, ret);
else
ret.addAll(elems);
} else {
ret.add(curr);
}
}
curr = getNext(curr, base, end);
}
return ret;
}