// Geometry (bounding box intersection) definitions
// This retrieves geometry obtained through "inkscape -S"
// already parsed by python and presented as a list of
// <bbox x="0" y="0" w="42" h="42">
const "geometry", "ns:GetSVGGeometry()";
| «@Id» «@x» «@y» «@w» «@h»
// Rates 1D intersection of 2 segments A and B
// described respectively with a0,a1 and b0,b1
def "func:intersect_1d" {
// it is assumed that a1 > a0 and b1 > b0
const "d0", "$a0 >= $b0";
const "d1", "$a1 >= $b1";
when "$d0 and $d1 and $a0 < $b1"
// a and b are overlapped
when "not($d0) and not($d1) and $b0 < $a1"
// a and b are overlapped
// since orientation doesn't matter,
// rated same as previous symetrical overlapping
result "0"; /* no intersection*/
// Rates intersection A and B areas described with x,y,w and h
// attributes passed as $a and $b parameters.
const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)";
when "$x_intersect != 0"{
const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)";
result "$x_intersect * $y_intersect";
const "groups", "/svg:svg | //svg:g";
// return overlapping geometry for a given element
// all intersercting element are returned
// except groups, that must be contained to be counted in
def "func:overlapping_geometry" {
const "g", "$geometry[@Id = $elt/@id]";
const "candidates", "$geometry[@Id != $elt/@id]";
result """$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or
(not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]""";