package SVGExtension; # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU LGPL Libray General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, # or refer to http://www.gnu.org/copyleft/lgpl.html # ################################################################## # Zinc methods, usefull at display time of Zinc code generated for SVG file # # Copyright 2003 # Centre d'Études de la Navigation Aérienne # # Author: Christophe Mertz # # $Id: SVGExtension.pm,v 1.1.1.1 2006-10-20 13:34:25 merlin Exp $ ############################################################################# use strict; use Carp; use vars qw( $VERSION ); ($VERSION) = sprintf("%d.%02d", q$Revision: 1.1.1.1 $ =~ /(\d+)\.(\d+)/); # To implement SVG viewport. # This method must be called when dispalying zinc objects, because the bbox of # Zinc objects must be known. ## BUG: Zinc method bbox return an oversized bbox (Zinc 3.2.6h). ## So this method cannot currently be fully exact. sub Tk::Zinc::adaptViewport { my ($zinc, $name, $width,$height, $viewbox, $aspectRatio) = @_; my($x0,$y0,$x1,$y1)=$zinc->bbox($name); ($x0,$y0,$x1,$y1)=($x0+2,$y0+2,$x1-2,$y1-2); # 2 is a delta induced by zinc! my $dx=$x1-$x0; my $dy=$y1-$y0; # print "In adaptViewport: $name w=$width h=$height dx=$dx dy=$dy x0=$x0,y0=$y0,x1=$x1,y1=$y1\n"; if (!$aspectRatio) { ## simple scale should be enough! my ($scaleX,$scaleY) = ($width/$dx, $height/$dy); $zinc->scale($name, $scaleX,$scaleY); } else { my ($minx,$miny,$portWidth,$portHeight) = split /[\s,]+/ , $viewbox; my ($xalign,$yalign,$meet) = $aspectRatio =~ /x(.*)Y(.*)\s+(.*)/ ; print "In adaptViewport: $name viewbox=$viewbox xalign=$xalign yalign=$yalign meet=$meet\n"; if ($meet eq 'meet') { ## il faut réduire la taille my $scale = 1; my ($scaleX,$scaleY) = ($width/$dx, $height/$dy); if ($scaleX < $scaleY) { if ($scaleX < 1) { $scale = $scaleX; } } elsif ($scaleY < 1) { $scale = $scaleY; } print "In adaptViewport: meet scale=$scale\n"; $zinc->scale($name, $scale,$scale); my ($shiftX,$shiftY)=(0,0); if ($xalign eq 'Min') { } elsif ($xalign eq 'Max') { $shiftX = $width - $dx*$scale; } elsif ($xalign eq 'Mid') { $shiftX = ($width - $dx*$scale)/2; } else { print "ERROR bad aspectratio value (for X): $aspectRatio\n"; } if ($yalign eq 'Min') { } elsif ($yalign eq 'Max') { $shiftY = $height - $dy*$scale; } elsif ($yalign eq 'Mid') { $shiftY = ($height - $dy*$scale)/2; } else { print "ERROR: bad aspectratio value (for Y): $aspectRatio \n"; } $zinc->translate($name, $shiftX,$shiftY); } elsif ($meet eq 'slice') { ## il faut clipper my $scale = 1; if ($dx < $width) { $scale = $width/$dx; } if ($dy < $height) { my $scaleY = $height/$dy; if ($scaleY > $scale) {$scale=$scaleY}; } print "In adaptViewport: slice scale=$scale\n"; $zinc->scale($name, $scale,$scale); my ($shiftX,$shiftY)=(0,0); if ($xalign eq 'Min') { } elsif ($xalign eq 'Max') { $shiftX = $width - $dx*$scale; } elsif ($xalign eq 'Mid') { $shiftX = ($width - $dx*$scale)/2; } else { print "ERROR bad aspectratio value (for X): $aspectRatio\n"; } if ($yalign eq 'Min') { } elsif ($yalign eq 'Max') { $shiftY = $height - $dy*$scale; } elsif ($yalign eq 'Mid') { $shiftY = ($height - $dy*$scale)/2; } else { print "ERROR: bad aspectratio value (for Y): $aspectRatio \n"; } $zinc->translate($name, $shiftX,$shiftY); my $g=$zinc->group($name); my ($tag)= $zinc->gettags($name); # there should only be one! $zinc->add('group', $g, -tags => [ "sub$tag" ]); $zinc->chggroup($name, "sub$tag"); print "clipping with [0,0, $width,$height]\n"; $zinc->add('rectangle', "sub$tag", [0,0, $width+1,$height+1], -tags => ["clipper_sub$tag"]); $zinc->itemconfigure("sub$tag", -clip => "clipper_sub$tag"); } print "\n"; } } ################################################################### 1;