#!/usr/bin/perl # Compares GD::SVG output in SVG to that generated by GD in PNG use strict; my ($image_class,$poly_class,$font_class,$image_type); sub BEGIN { chomp (my $package = shift); $package or die "\nUsage: generate_test_image.pl IMAGE_CLASS \t- where IMAGE_CLASS is one of GD or GD::SVG \t- GD generate png output; GD::SVG generates SVG.\n"; if ($package eq 'GD::SVG') { $image_type = 'svg'; } else { $image_type = 'png'; } eval "use $package"; $image_class = $package . '::Image'; $poly_class = $package . '::Polygon'; $font_class = $package . '::Font'; } my $yoffset; my $image = $image_class->new('800','1000'); # Allocate some colors my $white = $image->colorAllocate(255,255,255); my $red = $image->colorAllocate(255,0,0); my $black = $image->colorAllocate(0,0,0); my $blue = $image->colorAllocate(0,0,255); my $gray = $image->colorAllocate(127,127,127); my $aqua = $image->colorAllocate(127,255,212); my $yellow = $image->colorAllocate(255,255,0); my $orange = $image->colorAllocate(255,165,0); my $green = $image->colorAllocate(0,255,0); # Setting pixels my @colors = ($black,$red,$blue,$green,$yellow,$gray,$aqua,$orange); # Make the background transparent (and white) #$image->transparent($white); my $string = 'GD vs GD::SVG'; $image->string(gdGiantFont,800/2-((gdGiantFont->width * length $string) / 2),1,$string,$black); $image->string(gdMediumBoldFont,10,15,'Setting pixels...',$black); my $color_index = 0; for (my $x=250;$x<=750;$x+=10) { my $color = $colors[$color_index]; $image->setPixel($x,25,$color); $color_index++; $color_index = 0 if ($color_index >= @colors); } # Drawing lines $image->string(gdMediumBoldFont,10,35,'Drawing lines...',$black); $image->setThickness(0.5); $image->line(250,35,750,35,$aqua); $image->line(250,40,750,40,$yellow); $image->line(250,45,750,45,$red); $image->setThickness(1); $image->line(250,50,750,50,$black); $image->line(250,55,750,55,$red); $image->line(250,65,750,65,$green); $image->setThickness(2); $image->line(250,60,750,60,$blue); $image->line(250,65,750,65,$green); $image->line(250,70,750,70,$yellow); $image->setThickness(4); $image->line(250,75,750,75,$gray); $image->line(250,80,750,80,$aqua); $image->line(250,85,750,85,$orange); $image->setThickness(1); # Styled lines $image->setStyle($black,$red,$red,$red,$red,$red,$red,$black,$black,$black,$black,$green); $image->line(250,90,750,90,gdStyled); # Brushed lines... my $brush = $image_class->new(3,3); $brush->colorAllocate(255,255,255); my $mystery_color = $brush->colorAllocate(100,100,100); $brush->setThickness(3); $brush->line(0,0,0,3,$mystery_color); $image->setBrush($brush); $image->line(250,96,750,96,gdBrushed); # Rectangles $yoffset = 100; $yoffset += 15; $image->string(gdMediumBoldFont,10,$yoffset,'Rectangles...',$black); $image->rectangle(250,$yoffset,750,$yoffset+20,$black); # Filled rectangles $yoffset += 40; $image->string(gdMediumBoldFont,10,$yoffset,'Filled rectangles...',$black); $image->filledRectangle(250,$yoffset,750,$yoffset+20,$red); # Filled rectangles with borders $yoffset += 40; $image->string(gdMediumBoldFont,10,$yoffset,'Filled rectangles (bordered)...',$black); $image->filledRectangle(250,$yoffset,750,$yoffset+20,$aqua); $image->rectangle(250,$yoffset,750,$yoffset+20,$black); # Generic distribution of features my @xs = (qw/250 350 450 550 650/); # Polygons $yoffset += 40; my @star = ([40,0],[50,30], [80,40],[50,50], [40,80],[30,50], [0,40],[30,30],[40,0]); $image->string(gdMediumBoldFont,10,$yoffset,'Polygons...',$black); $color_index = 0; foreach my $startx (@xs) { my $polygon = $poly_class->new(); my $color = $colors[$color_index]; foreach (@star) { my ($x,$y) = @$_; $polygon->addPt($startx + $x,$yoffset + $y); } $image->polygon($polygon,$color); $color_index++; } # Filled polygons $yoffset = 320; # This is the same as above, but using the offset() # method of the polygon object Kind of a kludgy example (we have to # start the iterative loop 100 pixels left of where we really want to # start in order to demonstarte the offset method. $image->string(gdMediumBoldFont,10,$yoffset,'Filled polygons...',$black); $color_index = 0; for (my $x=150;$x<=550;$x+=100) { my $polygon = $poly_class->new(); my $color = $colors[$color_index]; foreach (@star) { my ($starx,$stary) = @$_; $polygon->addPt($starx + $x,$stary + $yoffset); } $polygon->offset(100,0); $image->filledPolygon($polygon,$color); $color_index++; } # Filled bordered polygons $yoffset += 100; $image->string(gdMediumBoldFont,10,$yoffset,'Filled polygons (bordered and boxed)...',$black); $color_index = 0; foreach my $startx (@xs) { my $polygon = $poly_class->new(); my $color = $colors[$color_index]; foreach (@star) { my ($x,$y) = @$_; $polygon->addPt($startx + $x,$yoffset + $y); } my ($left,$top,$right,$bottom) = $polygon->bounds(); $image->rectangle($left,$top,$right,$bottom,$black); $image->filledPolygon($polygon,$color); $image->polygon($polygon,$black); $color_index++; } # Ellipses $yoffset += 100; my @ellipses = qw/290 390 490 590 690/; $image->string(gdMediumBoldFont,10,$yoffset,'Ellipses...',$black); $color_index = 0; foreach my $x (@ellipses) { my $color = $colors[$color_index]; $image->ellipse($x,$yoffset,80,25,$color); $color_index++; } # Filled ellipses $yoffset += 30; $image->string(gdMediumBoldFont,10,$yoffset,'Filled ellipses...',$black); $color_index = 0; foreach my $x (@ellipses) { my $color = $colors[$color_index]; $image->filledEllipse($x,$yoffset,80,25,$color); $color_index++; } $yoffset += 30; $image->string(gdMediumBoldFont,10,$yoffset,'Filled ellipses (bordered, increasing thickness)...',$black); $color_index = 0; foreach my $x (@ellipses) { $image->setThickness($color_index+1); my $color = $colors[$color_index]; $image->filledEllipse($x,$yoffset,80,25,$color); $image->ellipse($x,$yoffset,80,25,$black); $color_index++; } $image->setThickness(1); # Arcs (closed) $yoffset += 30; $image->string(gdMediumBoldFont,10,$yoffset,'Arcs (closed)...',$black); $color_index = 0; foreach my $x (@ellipses) { my $color = $colors[$color_index]; $image->arc($x,$yoffset,80,25,0,360,$color); # Somewhat stupidly, these can also be created as $image->filledArc($x,$yoffset,80,25,0,360,$color,gdNoFill); $color_index++; } # Arcs on a circle (open) $yoffset += 30; $image->string(gdMediumBoldFont,10,$yoffset,'Arcs on a circle (open)...',$black); $color_index = 0; foreach my $x (@ellipses) { my $color = $colors[$color_index]; #$image->arc($x,$yoffset,25,80,0,270,$color); $image->arc($x,$yoffset,25,25,0,90,$color); # arcs on a circle... $color_index++; } # Arcs on an ellipse (open) $yoffset += 30; $image->string(gdMediumBoldFont,10,$yoffset,'Arcs on an ellipse (open)...',$black); $color_index = 0; foreach my $x (@ellipses) { my $color = $colors[$color_index]; $image->arc($x,$yoffset,25,80,0,270,$color); $color_index++; } # filledArcs (closed) $yoffset += 60; $image->string(gdMediumBoldFont,10,$yoffset,'Filled arcs (closed)...',$black); $color_index = 0; foreach my $x (@ellipses) { my $color = $colors[$color_index]; $image->filledArc($x,$yoffset,80,25,0,360,$color); $color_index++; } # filledArcs (open) $yoffset += 30; $image->string(gdMediumBoldFont,10,$yoffset,'Filled arcs (open)...',$black); $color_index = 0; foreach my $x (@ellipses) { my $color = $colors[$color_index]; $image->filledArc($x,$yoffset,80,25,40,120,$color); $color_index++; } # filledArcs (special styles) $yoffset += 30; $image->string(gdMediumBoldFont,10,$yoffset,'Filled arcs (special styles)...',$black); $color_index = 0; $image->filledArc(290,$yoffset,80,25,60,160,$colors[$color_index++],gdEdged|gdNoFill); $image->string(gdTinyFont,250,$yoffset+20,'gdEdged|gdNoFill',$black); $image->filledArc(390,$yoffset,80,25,60,160,$colors[$color_index++],gdArc); $image->string(gdTinyFont,350,$yoffset+20,'gdArc',$black); $image->filledArc(490,$yoffset,80,25,60,160,$colors[$color_index++],gdChord); $image->string(gdTinyFont,450,$yoffset+20,'gdChord',$black); $image->filledArc(590,$yoffset,80,25,60,160,$colors[$color_index++],gdChord|gdNoFill); $image->string(gdTinyFont,550,$yoffset+20,'gdChord|gdNoFill',$black); $image->filledArc(690,$yoffset,80,25,60,160,$colors[$color_index++],gdArc); $image->filledArc(690,$yoffset,80,25,60,160,$colors[0],gdEdged|gdNoFill); $image->string(gdTinyFont,630,$yoffset+20,'gdArc, then gdEdged|gdNoFill',$black); # Fonts... $yoffset += 40; $image->string(gdMediumBoldFont,10,$yoffset,'Fonts',$black); # Print examples of the oo-method calls $image->string(gdTinyFont,250,$yoffset,'gdTinyFont',$black); $image->string($font_class->Tiny,400,$yoffset,"$font_class->Tiny",$black); $image->string(gdSmallFont,250,$yoffset+20,'gdSmallFont',$black); $image->string($font_class->Small,400,$yoffset+20,"$font_class->Small",$black); $image->string(gdMediumBoldFont,250,$yoffset+40,'gdMediumBoldFont',$black); $image->string($font_class->MediumBold,400,$yoffset+40,"$font_class->MediumBold",$black); $image->string(gdLargeFont,250,$yoffset+60,'gdLargeFont',$black); $image->string($font_class->Large,400,$yoffset+60,"$font_class->Large",$black); $image->string(gdGiantFont,250,$yoffset+80,'gdGiantFont',$black); $image->string($font_class->Giant,400,$yoffset+80,"$font_class->Giant",$black); # stringUp is broken with SVG 2.32? $image->stringUp(gdGiantFont,370,$yoffset+100,'gdGiantFont',$black); $image->stringUp($font_class->Giant,550,$yoffset+100,"$font_class->Giant",$black); # Fetch all elements of the source image if ($image_type eq 'GD::SVG') { # Fetch all elements of the source image my @elements = $image->{img}->getElements; foreach (@elements) { my $att = $_->getAttributes(); # Points|rectangles, circles, lines my $x = $att->{x} || $att->{cx} || $att->{x1}; my $y = $att->{'y'} || $att->{cy} || $att->{y1}; # Get the first point for polygons unless ($x && $y) { my $points = $att->{points}; my @points = split(/\s/,$att->{points}); if ($points) { ($x,$y) = split(',',$points[0]); print STDERR "$x $y\n"; } } # Paths unless ($x && $y) { my @d = split(/\s/,$att->{d}); if (@d) { ($x,$y) = split(',',$d[0]); $x =~ s/^M//; # Remove the style directive } print STDERR "$x $y\n"; } } } print $image->$image_type();