:- lib(xpath).
:- lib(pack_errors). % type/3
/** svg_tag_coords( +Svg, +Tag, -Coords ).
svg_tag_coords( +Svg, +Tag, +AsPos, -Coords ).
Find the locations (X-Y, Coords) of all tags of type Tag in an Svg file.
Predicate simply looks for x=, y= into Atts of matching tags.
AsPos is a boolean (false when missing) that when set translates each X and Y to it positive value.
==
?- svg_tag_coords( pack('svg/examples/rea_smp-e10_fclr.svg'), text, Coords ), maplist( writeln, Coords ), fail.
197- -302.3
197- -230.3
446- -374.3
...
344- -14.3
197- -86.3
false.
?- svg_tag_coords( pack('svg/examples/rea_smp-e10_fclr.svg'), text, true, Coords ), maplist( writeln, Coords ), fail.
197-706.3
197-634.3
446-778.3
...
344-418.3
197-490.3
false.
?- svg_size( pack('svg/examples/rea_smp-e10_fclr.svg'), W, H ).
W = 497,
H = 404.
==
@author nicos angelopoulos
@version 0.1 2018/2/21
*/
svg_tag_coords( SvgIn, Tag, Coords ) :-
svg_tag_coords( SvgIn, Tag, false, Coords ).
svg_tag_coords( SvgIn, Tag, AsPos, Coords ) :-
type( boolean, AsPos, [pack(svg),pred(svg_tag_coords(arg3)/4)] ),
svg( SvgIn, Svg ),
Svg = svg(SvgAtts,Dom),
svg_tag_coords_iff( AsPos, SvgAtts, W, H ),
findall( X-Y, (
xpath( Dom, //(Tag), element(Tag,Atts,_Elems) ),
memberchk( x=Xatm, Atts ),
memberchk( y=Yatm, Atts ),
atom_number( Xatm, Xnak ),
atom_number( Yatm, Ynak ),
svg_tag_coord_to_positive( AsPos, W, Xnak, X ),
svg_tag_coord_to_positive( AsPos, H, Ynak, Y )
),
Coords ).
svg_tag_coords_iff( true, Atts, W, H ) :-
memberchk( width=Wat, Atts ),
memberchk( height=Hat, Atts ),
maplist( svg_size_dim, [Wat,Hat], [W,H] ).
svg_tag_coords_iff( false, _Atts, t, t ).
svg_tag_coord_to_positive( true, Size, Val, Ret ) :-
( Val < 0 -> Ret is Size + Val; Ret is Val ). % fixme: + Val - 1 ???
svg_tag_coord_to_positive( false, _Size, Val, Val ).