aboutsummaryrefslogtreecommitdiff
path: root/src/Tk/Zinc/SVGExtension.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/Tk/Zinc/SVGExtension.pm')
-rw-r--r--src/Tk/Zinc/SVGExtension.pm140
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;