diff options
Diffstat (limited to 'src/Tk/Zinc/SVGExtension.pm')
-rw-r--r-- | src/Tk/Zinc/SVGExtension.pm | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/Tk/Zinc/SVGExtension.pm b/src/Tk/Zinc/SVGExtension.pm new file mode 100644 index 0000000..fc1e17c --- /dev/null +++ b/src/Tk/Zinc/SVGExtension.pm @@ -0,0 +1,140 @@ +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 <mertz@cena.fr> +# +# $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; |