// geometry.ysl2 // // 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()"; // Debug data emit "debug:geometry" { | ID, x, y, w, h foreach "$geometry" | «@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 param "a0"; param "a1"; param "b0"; param "b1"; const "d0", "$a0 >= $b0"; const "d1", "$a1 >= $b1"; choose { when "not($d0) and $d1" // b contained in a // a0<b0 b1<a1 // a +--------+ // b +--+ result "3"; when "$d0 and not($d1)" // a contained in b // b0<a0 a1<b1 // a +--+ // b +--------+ result "2"; when "$d0 and $d1 and $a0 < $b1" // a and b are overlapped // b0<a0<b1<a1 // a +-----+ // b +-----+ result "1"; when "not($d0) and not($d1) and $b0 < $a1" // a and b are overlapped // a0<b0<a1<b1 // a +-----+ // b +-----+ result "1"; // since orientation doesn't matter, // rated same as previous symetrical overlapping otherwise result "0"; /* no intersection*/ } } // Rates intersection A and B areas described with x,y,w and h // attributes passed as $a and $b parameters. // // returns : // 0 - no intersection // .-----. // .-----. | b| // | | | | // | | '-----' // |a | // '-----' // // 1 - overlapping // .-----. // .---|--. b| // | | | | // | '-----' // |a | // '------' // // 2 - overlapping // .-----. // | a | // .---|-----|---. // | '-----' | // | b | // '-------------' // // 3 - overlapping // .-----. // | b | // .---|-----|---. // | '-----' | // | a | // '-------------' // // 4 - a contained in b // .-------------. // | .-----. | // | | a | | // |b '-----' | // '-------------' // // 6 - overlapping // .----. // | b| // .---|----|---. // |a | | | // '---|----|---' // '----' // // 9 - b contained in a // .-------------. // | .-----. | // | | b | | // |a '-----' | // '-------------' // def "func:intersect" { param "a"; param "b"; const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)"; choose{ 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"; } otherwise result "0"; } } // 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" { param "elt"; const "groups", "/svg:svg | //svg:g"; 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 ))]"""; }