.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "SVG 3pm" .TH SVG 3pm "2020-07-29" "perl v5.30.3" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" GD::SVG \- Seamlessly enable SVG output from scripts written using GD .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& # use GD; \& use GD::SVG; \& \& # my $img = GD::Image\->new(); \& my $img = GD::SVG::Image\->new(); \& \& # $img\->png(); \& $img\->svg(); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\s-1GD::SVG\s0 painlessly enables scripts that utilize \s-1GD\s0 to export scalable vector graphics (\s-1SVG\s0). It accomplishes this task by wrapping \s-1SVG\s0.pm with GD-styled method calls. To enable this functionality, one need only change the \*(L"use \s-1GD\*(R"\s0 call to \*(L"use \s-1GD::SVG\*(R"\s0 (and initial \*(L"new\*(R" method calls). .SH "EXPORTS" .IX Header "EXPORTS" \&\s-1GD::SVG\s0 exports the same methods as \s-1GD\s0 itself, overriding those methods. .SH "USAGE" .IX Header "USAGE" In order to generate \s-1SVG\s0 output from your script using \s-1GD::SVG,\s0 you will need to first .PP .Vb 2 \& # use GD; \& use GD::SVG; .Ve .PP After that, each call to the package classes that \s-1GD\s0 implements should be changed to \s-1GD::SVG.\s0 Thus: .PP .Vb 2 \& GD::Image becomes GD::SVG::Image \& GD::Font becomes GD::SVG::Font .Ve .SH "DYNAMICALLY SELECTING SVG OUTPUT" .IX Header "DYNAMICALLY SELECTING SVG OUTPUT" If you would like your script to be able to dynamically select either \&\s-1PNG\s0 or \s-1JPEG\s0 output (via \s-1GD\s0) or \s-1SVG\s0 output (via \s-1GD::SVG\s0), you should place your \*(L"use\*(R" statement within an eval. In the example below, each of the available classes is created at the top of the script for convenience, as well as the image output type. .PP .Vb 4 \& my $package = shift; \& eval "use $package"; \& my $image_pkg = $package . \*(Aq::Image\*(Aq; \& my $font_pkg = $package . \*(Aq::Font\*(Aq; \& \& # Creating new images thus becomes \& my $image = $image_pkg\->new($width,$height); \& \& # Establish the image output type \& my $image_type; \& if ($package = \*(AqGD::SVG\*(Aq) { \& $image_type = \*(Aqsvg\*(Aq; \& } else { \& $image_type = \*(Aqpng\*(Aq; \& } .Ve .PP Finally, you should change all GD::Image and GD::Font references to \&\f(CW$image_pkg\fR\-> and \f(CW$font_pkg\fR\->, respectively. .PP .Vb 2 \& GD::Image\->new() becomes $image_pkg\->new() \& GD::Font\->Large() becomes $font_pkg\->Large() .Ve .PP The GD::Polygon and GD::Polyline classes work with \s-1GD::SVG\s0 without modification. .PP If you make heavy use of \s-1GD\s0's exported methods, it may also be necessary to add () to the endo of method names to avoide bareword compilation errors. That's the price you pay for using exported functions! .SH "IMPORTANT NOTES" .IX Header "IMPORTANT NOTES" \&\s-1GD::SVG\s0 does not directly generate \s-1SVG,\s0 but instead relies upon \&\s-1SVG\s0.pm. It is not intended to supplant \s-1SVG\s0.pm. Furthermore, since \&\s-1GD::SVG\s0 is, in essence an \s-1API\s0 to an \s-1API,\s0 it may not be suitable for applications where speed is of the essence. In these cases, \s-1GD::SVG\s0 may provide a short-term solution while scripts are re-written to enable more direct output of \s-1SVG.\s0 .PP Many of the \s-1GD::SVG\s0 methods accept additional parameters (which are in turn reflected in the \s-1SVG\s0.pm \s-1API\s0) that are not supported in \s-1GD.\s0 Look through the remainder of this document for options on specific In addition, several functions have yet to be mapped to \s-1SVG\s0.pm calls. Please see the section below regarding regarding \s-1GD\s0 functions that are missing or altered in \s-1GD::SVG.\s0 .PP A similar module (\s-1SVG::GD\s0) implements a similar wrapper around \&\s-1GD.\s0 Please see the section at the bottom of this document that compares \s-1GD::SVG\s0 to \s-1SVG::GD.\s0 .SH "PREREQUISITES" .IX Header "PREREQUISITES" \&\s-1GD::SVG\s0 requires the Ronan Oger's \s-1SVG\s0.pm module, Lincoln Stein's \s-1GD\s0.pm module, libgd and its dependencies. .SH "GENERAL DIFFICULTIES IN TRANSLATING GD TO SVG" .IX Header "GENERAL DIFFICULTIES IN TRANSLATING GD TO SVG" These are the primary weaknesses of \s-1GD::SVG.\s0 .IP "\s-1SVG\s0 requires unique identifiers for each element" 4 .IX Item "SVG requires unique identifiers for each element" Each element in an \s-1SVG\s0 image requires a unique identifier. In general, \&\s-1GD::SVG\s0 handles this by automatically generating unique random numbers. In addition to the typical parameters for \s-1GD\s0 methods, \&\s-1GD::SVG\s0 methods allow a user to pass an optional id parameter for naming the object. .IP "Direct calls to the \s-1GD\s0 package will fail" 4 .IX Item "Direct calls to the GD package will fail" You must change direct calls to the classes that \s-1GD\s0 invokes: GD::Image\->\fBnew()\fR should be changed to GD::SVG::Image\->\fBnew()\fR .Sp See the documentation above for how to dynamically switch between packages. .IP "raster \fBfill()\fR and \fBfillToBorder()\fR not supported" 4 .IX Item "raster fill() and fillToBorder() not supported" As \s-1SVG\s0 documents are not inherently aware of their canvas, the flood fill methods are not currently supported. .IP "\fBgetPixel()\fR not supported." 4 .IX Item "getPixel() not supported." Although \fBsetPixel()\fR works as expected, its counterpart \fBgetPixel()\fR is not supported. I plan to support this method in a future release. .IP "No support for generation of images from filehandles or raw data" 4 .IX Item "No support for generation of images from filehandles or raw data" \&\s-1GD::SVG\s0 works only with scripts that generate images directly in the code using the \s-1GD\-\s0>new(height,width) approach. \fBnewFrom()\fR methods are not currently supported. .IP "Tiled fills are not supported" 4 .IX Item "Tiled fills are not supported" Any functions passed gdTiled objects will die. .IP "Styled and Brushed lines only partially implemented" 4 .IX Item "Styled and Brushed lines only partially implemented" Calls to the gdStyled and gdBrushed functions via a rather humorous kludge (and simplification). Depending on the complexity of the brush, they may behave from slightly differently to radically differently from their behavior under \s-1GD.\s0 You have been warned. See the documentation sections for the methods that set these options (\fBsetStyle()\fR, \fBsetBrush()\fR, and \fBsetTransparent()\fR). .PP See below for a full list of methods that have not yet been implemented. .SH "WHEN THINGS GO WRONG" .IX Header "WHEN THINGS GO WRONG" \&\s-1GD\s0 is a complicated module. Translating \s-1GD\s0 methods into those required to draw in \s-1SVG\s0 are not always direct. You may or may not get the output you expect. In general, some tweaking of image parameters (like text height and width) may be necessary. .PP If your script doesn't work as expected, first check the list of methods that \s-1GD::SVG\s0 provides. Due to differences in the nature of \&\s-1SVG\s0 images, not all \s-1GD\s0 methods have been implemented in \s-1GD::SVG.\s0 .PP If your image doesn't look as expected, try tweaking specific aspects of image generation. In particular, check for instances where you calculate dimensions of items on the fly like font\->height. In \s-1SVG,\s0 the values of fonts are defined explicitly. .SH "GD FUNCTIONS MISSING FROM GD::SVG" .IX Header "GD FUNCTIONS MISSING FROM GD::SVG" The following \s-1GD\s0 functions have not yet been incorporated into \&\s-1GD::SVG.\s0 If you attempt to use one of these functions (and you have enabled debug warnings via the \fBnew()\fR method), \s-1GD::SVG\s0 will print a warning to \s-1STDERR.\s0 .PP .Vb 10 \& Creating image objects: \& GD::Image\->newPalette([$width,$height]) \& GD::Image\->newTrueColor([$width,$height]) \& GD::Image\->newFromPng($file, [$truecolor]) \& GD::Image\->newFromPngData($data, [$truecolor]) \& GD::Image\->newFromJpeg($file, [$truecolor]) \& GD::Image\->newFromJpegData($data, [$truecolor]) \& GD::Image\->newFromXbm($file) \& GD::Image\->newFromWMP($file) \& GD::Image\->newFromGd($file) \& GD::Image\->newFromGdData($data) \& GD::Image\->newFromGd2($file) \& GD::Image\->newFromGd2Data($data) \& GD::Image\->newFromGd2Part($file,srcX,srcY,width,height) \& GD::Image\->newFromXpm($filename) \& \& Image methods: \& $gddata = $image\->gd \& $gd2data = $image\->gd2 \& $wbmpdata = $image\->wbmp([$foreground]) \& \& Color control methods: \& $image\->colorAllocateAlpha() \& $image\->colorClosest() \& $image\->colorClosestHWB() \& $image\->getPixel() \& $image\->transparent() \& \& Special Colors: \& $image\->setBrush() (semi\-supported, with kludge) \& $image\->setStyle() (semi\-supported, with kludge) \& gdTiled \& $image\->setAntialiased() \& gdAntiAliased() \& $image\->setAntiAliasedDontBlend() \& \& Drawing methods: \& $image\->dashedLine() \& $image\->fill() \& $image\->fillToBorder() \& \& Image copying methods \& None of the image copying methods are yet supported \& \& Image transformation methods \& None of the image transformation methods are yet supported \& \& Character and string drawing methods \& $image\->stringUp() \- incompletely supported \- broken \& $image\->charUp() \& $image\->stringFT() \& \& Alpha Channels \& $image\->alphaBlending() \& $image\->saveAlpha() \& \& Miscellaneous image methods \& $image\->isTrueColor() \& $image\->compare($image2) \& $image\->clip() \& $image\->boundsSafe() \& \& GD::Polyline \& Supported without modifications \& \& Font methods: \& $font\->nchars() \& $font\->offset() .Ve .SH "GROUPING FUNCTIONS GD::SVG" .IX Header "GROUPING FUNCTIONS GD::SVG" \&\s-1GD::SVG\s0 supports three additional methods that provides the ability to recursively group objects: .ie n .IP "$this\->startGroup([$id,\e%style]), $this\->\fBendGroup()\fR" 4 .el .IP "\f(CW$this\fR\->startGroup([$id,\e%style]), \f(CW$this\fR\->\fBendGroup()\fR" 4 .IX Item "$this->startGroup([$id,%style]), $this->endGroup()" These methods start and end a group in a procedural manner. Once a group is started, all further drawing will be appended to the group until \fBendGroup()\fR is invoked. You may optionally pass a string \s-1ID\s0 and an \s-1SVG\s0 styles hash to startGroup. .ie n .IP "$group = $this\->newGroup([$id,\e%style])" 4 .el .IP "\f(CW$group\fR = \f(CW$this\fR\->newGroup([$id,\e%style])" 4 .IX Item "$group = $this->newGroup([$id,%style])" This method returns a GD::Group object, which has all the behaviors of a \s-1GD::SVG\s0 object except that it draws within the current group. You can invoke this object's drawing methods to draw into a group. The group is closed once the object goes out of scope. While the object is open, invoking drawing methods on the parent \s-1GD::SVG\s0 object will also draw into the group until it goes out of scope. .Sp Here is an example of using grouping in the procedural way: .Sp .Vb 6 \& use GD::SVG; \& my $img = GD::SVG::Image\->new(500,500); \& my $white = $img\->colorAllocate(255,255,255); \& my $black = $img\->colorAllocate(0,0,0); \& my $blue = $img\->colorAllocate(0,0,255); \& my $red = $img\->colorAllocate(255,0,0); \& \& $img\->startGroup(\*(Aqcircle in square\*(Aq); \& $img\->rectangle(100,100,400,400,$blue); \& \& $img\->startGroup(\*(Aqcircle and boundary\*(Aq); \& $img\->filledEllipse(250,250,200,200,$red); \& $img\->ellipse(250,250,200,200,$black); \& \& $img\->endGroup; \& $img\->endGroup; \& \& print $img\->svg; .Ve .Sp Here is an example of using grouping with the GD::Group object: .Sp .Vb 1 \& ... \& \& my $g1 = $img\->newGroup(\*(Aqcircle in square\*(Aq); \& $g1\->rectangle(100,100,400,400,$blue); \& \& my $g2 = $g1\->startGroup(\*(Aqcircle and boundary\*(Aq); \& $g2\->filledEllipse(250,250,200,200,$red); \& $g2\->ellipse(250,250,200,200,$black); \& \& print $img\->svg; .Ve .Sp Finally, here is a fully worked example of using the GD::Simple module to make the syntax cleaner: .Sp .Vb 1 \& #!/usr/bin/perl \& \& use strict; \& use GD::Simple; \& \& GD::Simple\->class(\*(AqGD::SVG\*(Aq); \& \& my $img = GD::Simple\->new(500,500); \& $img\->bgcolor(\*(Aqwhite\*(Aq); \& $img\->fgcolor(\*(Aqblue\*(Aq); \& \& my $g1 = $img\->newGroup(\*(Aqcircle in square\*(Aq); \& $g1\->rectangle(100,100,400,400); \& $g1\->moveTo(250,250); \& \& my $g2 = $g1\->newGroup(\*(Aqcircle and boundary\*(Aq); \& $g2\->fgcolor(\*(Aqblack\*(Aq); \& $g2\->bgcolor(\*(Aqred\*(Aq); \& $g2\->ellipse(200,200); \& \& print $img\->svg; .Ve .SH "GD VERSUS GD::SVG METHODS" .IX Header "GD VERSUS GD::SVG METHODS" All \s-1GD::SVG\s0 methods mimic the naming and interface of \s-1GD\s0 methods. As such, maintenance of \s-1GD::SVG\s0 follows the development of both \s-1GD\s0 and \&\s-1SVG.\s0 Much of the original \s-1GD\s0 documentation is replicated here for ease of use. Subtle differences in the implementation of these methods between \s-1GD\s0 and \s-1GD::SVG\s0 are discussed below. In particular, the return value for some \s-1GD::SVG\s0 methods differs from its \s-1GD\s0 counterpart. .SH "OBJECT CONSTRUCTORS: CREATING IMAGES" .IX Header "OBJECT CONSTRUCTORS: CREATING IMAGES" \&\s-1GD::SVG\s0 currently only supports the creation of image objects via its new constructor. This is in contrast to \s-1GD\s0 proper which supports the creation of images from previous images, filehandles, filenames, and data. .ie n .IP "$image = GD::SVG::Image\->new($height,$width,$debug);" 4 .el .IP "\f(CW$image\fR = GD::SVG::Image\->new($height,$width,$debug);" 4 .IX Item "$image = GD::SVG::Image->new($height,$width,$debug);" Create a blank \s-1GD::SVG\s0 image object of the specified dimensions in pixels. In turn, this method will create a new \s-1SVG\s0 object and store it internally. You can turn on debugging with the \s-1GD::SVG\s0 specific \f(CW$debug\fR parameter. This should be boolean true and will cause non-implemented methods to print a warning on their status to \s-1STDERR.\s0 .SH "GD::SVG::Image METHODS" .IX Header "GD::SVG::Image METHODS" Once a GD::Image object is created, you can draw with it, copy it, and merge two images. When you are finished manipulating the object, you can convert it into a standard image file format to output or save to a file. .SS "Image Data Output Methods" .IX Subsection "Image Data Output Methods" \&\s-1GD::SVG\s0 implements a single output method, \fBsvg()\fR! .ie n .IP "$svg = $image\->\fBsvg()\fR;" 4 .el .IP "\f(CW$svg\fR = \f(CW$image\fR\->\fBsvg()\fR;" 4 .IX Item "$svg = $image->svg();" This returns the image in \s-1SVG\s0 format. You may then print it, pipe it to an image viewer, or write it to a file handle. For example, .Sp .Vb 5 \& $svg_data = $image\->svg(); \& open (DISPLAY,"| display \-") || die; \& binmode DISPLAY; \& print DISPLAY $svg_data; \& close DISPLAY; .Ve .Sp if you'd like to return an inline version of the image (instead of a full document version complete with the \s-1DTD\s0), pass the \fBsvg()\fR method the \&'inline' flag: .Sp .Vb 1 \& $svg_data = $image\->svg(\-inline=>\*(Aqtrue\*(Aq); .Ve .Sp Calling the other standard \s-1GD\s0 image output methods (eg jpeg,gd,gd2,png) on a GD::SVG::Image object will cause your script to exit with a warning. .SS "Color Control" .IX Subsection "Color Control" These methods allow you to control and manipulate the color table of a \&\s-1GD::SVG\s0 image. In contrast to \s-1GD\s0 which uses color indices, \s-1GD::SVG\s0 passes stringified \s-1RGB\s0 triplets as colors. \s-1GD::SVG,\s0 however, maintains an internal hash structure of colors and colored indices in order to map \s-1GD\s0 functions that manipulate the color table. This typically requires behind-the-scenes translation of these stringified \s-1RGB\s0 triplets into a color index. .ie n .IP "$stringified_color = $image\->colorAllocate(\s-1RED,GREEN,BLUE\s0)" 4 .el .IP "\f(CW$stringified_color\fR = \f(CW$image\fR\->colorAllocate(\s-1RED,GREEN,BLUE\s0)" 4 .IX Item "$stringified_color = $image->colorAllocate(RED,GREEN,BLUE)" Unlike \s-1GD,\s0 colors need not be allocated in advance in \s-1SVG.\s0 Unlike \s-1GD\s0 which returns a color index, colorAllocate returns a formatted string compatible with \s-1SVG.\s0 Simultaneously, it creates and stores internally a \s-1GD\s0 compatible color index for use with \s-1GD\s0's color manipulation methods. .Sp .Vb 1 \& returns: "rgb(RED,GREEN,BLUE)" .Ve .ie n .IP "$index = $image\->\fBcolorAllocateAlpha()\fR" 4 .el .IP "\f(CW$index\fR = \f(CW$image\fR\->\fBcolorAllocateAlpha()\fR" 4 .IX Item "$index = $image->colorAllocateAlpha()" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$image\->colorDeallocate($index)" 4 .el .IP "\f(CW$image\fR\->colorDeallocate($index)" 4 .IX Item "$image->colorDeallocate($index)" Provided with a color index, remove it from the color table. .ie n .IP "$index = $image\->colorClosest(red,green,blue)" 4 .el .IP "\f(CW$index\fR = \f(CW$image\fR\->colorClosest(red,green,blue)" 4 .IX Item "$index = $image->colorClosest(red,green,blue)" This returns the index of the color closest in the color table to the red green and blue components specified. This method is inherited directly from \s-1GD.\s0 .Sp .Vb 1 \& Example: $apricot = $myImage\->colorClosest(255,200,180); .Ve .Sp \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$index = $image\->colorClosestHWB(red,green,blue)" 4 .el .IP "\f(CW$index\fR = \f(CW$image\fR\->colorClosestHWB(red,green,blue)" 4 .IX Item "$index = $image->colorClosestHWB(red,green,blue)" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$index = $image\->colorExact(red,green,blue)" 4 .el .IP "\f(CW$index\fR = \f(CW$image\fR\->colorExact(red,green,blue)" 4 .IX Item "$index = $image->colorExact(red,green,blue)" Retrieve the color index of an rgb triplet (or \-1 if it has yet to be allocated). .Sp \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$index = $image\->colorResolve(red,green,blue)" 4 .el .IP "\f(CW$index\fR = \f(CW$image\fR\->colorResolve(red,green,blue)" 4 .IX Item "$index = $image->colorResolve(red,green,blue)" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$colors_total = $image\->\fBcolorsTotal()\fR" 4 .el .IP "\f(CW$colors_total\fR = \f(CW$image\fR\->\fBcolorsTotal()\fR" 4 .IX Item "$colors_total = $image->colorsTotal()" Retrieve the total number of colors indexed in the image. .ie n .IP "$index = $image\->getPixel(x,y)" 4 .el .IP "\f(CW$index\fR = \f(CW$image\fR\->getPixel(x,y)" 4 .IX Item "$index = $image->getPixel(x,y)" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "($red,$green,$blue) = $image\->rgb($index)" 4 .el .IP "($red,$green,$blue) = \f(CW$image\fR\->rgb($index)" 4 .IX Item "($red,$green,$blue) = $image->rgb($index)" Provided with a color index, return the \s-1RGB\s0 triplet. In \s-1GD::SVG,\s0 color indexes are replaced with actual \s-1RGB\s0 triplets in the form \&\*(L"rgb($r,$g,$b)\*(R". .ie n .IP "$image\->transparent($colorIndex);" 4 .el .IP "\f(CW$image\fR\->transparent($colorIndex);" 4 .IX Item "$image->transparent($colorIndex);" Control the transparency of individual colors. .Sp \&\s-1NOT IMPLEMENTED\s0 .SS "Special Colors" .IX Subsection "Special Colors" \&\s-1GD\s0 implements a number of special colors that can be used to achieve special effects. They are constants defined in the \s-1GD::\s0 namespace, but automatically exported into your namespace when the \s-1GD\s0 module is loaded. \s-1GD::SVG\s0 offers limited support for these methods. .ie n .IP "$image\->setBrush($brush) (\s-1KLUDGE ALERT\s0)" 4 .el .IP "\f(CW$image\fR\->setBrush($brush) (\s-1KLUDGE ALERT\s0)" 4 .IX Item "$image->setBrush($brush) (KLUDGE ALERT)" .PD 0 .IP "gdBrushed" 4 .IX Item "gdBrushed" .PD In \s-1GD,\s0 one can draw lines and shapes using a brush pattern. Brushes are just images that you can create and manipulate in the usual way. When you draw with them, their contents are used for the color and shape of the lines. .Sp To make a brushed line, you must create or load the brush first, then assign it to the image using \fBsetBrush()\fR. You can then draw in that with that brush using the gdBrushed special color. It's often useful to set the background of the brush to transparent so that the non-colored parts don't overwrite other parts of your image. .Sp .Vb 6 \& # Via GD, this is how one would set a Brush \& $diagonal_brush = new GD::Image(5,5); \& $white = $diagonal_brush\->colorAllocate(255,255,255); \& $black = $diagonal_brush\->colorAllocate(0,0,0); \& $diagonal_brush\->transparent($white); \& $diagonal_brush\->line(0,4,4,0,$black); # NE diagonal .Ve .Sp \&\s-1GD::SVG\s0 offers limited support for setBrush (and the corresponding gdBrushed methods) \- currently only in the shapes of squares. Internally, \s-1GD::SVG\s0 extracts the longest dimension of the image using the \fBgetBounds()\fR method. Next, it extracts the second color set, assuming that to be the foreground color. It then re-calls the original drawing method with these new values in place of the gdBrushed. See the private _distill_gdSpecial method for the internal details of this operation. .ie n .IP "$image\->setThickness($thickness)" 4 .el .IP "\f(CW$image\fR\->setThickness($thickness)" 4 .IX Item "$image->setThickness($thickness)" Lines drawn with \fBline()\fR, \fBrectangle()\fR, \fBarc()\fR, and so forth are 1 pixel thick by default. Call \fBsetThickness()\fR to change the line drawing width. .ie n .IP "$image\->setStyle(@colors)" 4 .el .IP "\f(CW$image\fR\->setStyle(@colors)" 4 .IX Item "$image->setStyle(@colors)" \&\fBsetStyle()\fR and \fBgdStyled()\fR are partially supported in \s-1GD::SVG. GD::SVG\s0 determines the alternating pattern of dashes, treating the first unique color encountered in the array as on, the second as off and so on. The first color in the array is then used to draw the actual line. .IP "gdTiled" 4 .IX Item "gdTiled" \&\s-1NOT IMPLEMENTED\s0 .IP "\fBgdStyled()\fR" 4 .IX Item "gdStyled()" The \s-1GD\s0 special color gdStyled is partially implemented in \&\s-1GD::SVG.\s0 Only the first color will be used to generate the dashed pattern specified in \fBsetStyle()\fR. See \fBsetStyle()\fR for additional information. .ie n .IP "$image\->setAntiAliased($color)" 4 .el .IP "\f(CW$image\fR\->setAntiAliased($color)" 4 .IX Item "$image->setAntiAliased($color)" \&\s-1NOT IMPLEMENTED\s0 .IP "gdAntiAliased" 4 .IX Item "gdAntiAliased" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$image\->setAntiAliasedDontBlend($color,[$flag])" 4 .el .IP "\f(CW$image\fR\->setAntiAliasedDontBlend($color,[$flag])" 4 .IX Item "$image->setAntiAliasedDontBlend($color,[$flag])" \&\s-1NOT IMPLEMENTED\s0 .SS "Drawing Commands" .IX Subsection "Drawing Commands" .ie n .IP "$image\->setPixel($x,$y,$color)" 4 .el .IP "\f(CW$image\fR\->setPixel($x,$y,$color)" 4 .IX Item "$image->setPixel($x,$y,$color)" Set the corresponding pixel to the given color. \s-1GD::SVG\s0 implements this by drawing a single dot in the specified color at that position. .ie n .IP "$image\->line(x1,y1,x2,y2,color);" 4 .el .IP "\f(CW$image\fR\->line(x1,y1,x2,y2,color);" 4 .IX Item "$image->line(x1,y1,x2,y2,color);" Draw a line between the two coordinate points with the specified color. Passing an optional id will set the id of that \s-1SVG\s0 element. \s-1GD::SVG\s0 also supports drawing with the special brushes \- gdStyled and gdBrushed \- although these special styles are difficult to replicate precisley in \s-1GD::SVG.\s0 .ie n .IP "$image\->dashedLine($x1,$y1,$x2,$y2,$color);" 4 .el .IP "\f(CW$image\fR\->dashedLine($x1,$y1,$x2,$y2,$color);" 4 .IX Item "$image->dashedLine($x1,$y1,$x2,$y2,$color);" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$image\->rectangle($x1,$y1,$x2,$y2,$color);" 4 .el .IP "\f(CW$image\fR\->rectangle($x1,$y1,$x2,$y2,$color);" 4 .IX Item "$image->rectangle($x1,$y1,$x2,$y2,$color);" This draws a rectangle with the specified color. (x1,y1) and (x2,y2) are the upper left and lower right corners respectively. You may also draw with the special colors gdBrushed and gdStyled. .ie n .IP "$image\->filledRectangle($x1,$y1,$x2,$y2,$color);" 4 .el .IP "\f(CW$image\fR\->filledRectangle($x1,$y1,$x2,$y2,$color);" 4 .IX Item "$image->filledRectangle($x1,$y1,$x2,$y2,$color);" filledRectangle is a \s-1GD\s0 specific method with no direct equivalent in \&\s-1SVG.\s0 \s-1GD::SVG\s0 translates this method into an \s-1SVG\s0 appropriate method by passing the filled color parameter as a named 'filled' parameter to \&\s-1SVG.\s0 Drawing with the special colors is also permitted. See the documentation for the \fBline()\fR method for additional details. .Sp .Vb 2 \& GD call: \& $img\->filledRectangle($x1,$y1,$x2,$y2,$color); \& \& SVG call: \& $img\->rectangle(x=> $x1,y=> $y1, \& width => $x2\-$x1, \& height => $y2\-$y1, \& fill => $color .Ve .ie n .IP "$image\->polygon($polygon,$color);" 4 .el .IP "\f(CW$image\fR\->polygon($polygon,$color);" 4 .IX Item "$image->polygon($polygon,$color);" This draws a polygon with the specified color. The polygon must be created first (see \*(L"Polygons\*(R" below). The polygon must have at least three vertices. If the last vertex doesn't close the polygon, the method will close it for you. Both real color indexes and the special colors gdBrushed, gdStyled and gdStyledBrushed can be specified. See the documentation for the \fBline()\fR method for additional details. .Sp .Vb 5 \& $poly = new GD::Polygon; \& $poly\->addPt(50,0); \& $poly\->addPt(99,99); \& $poly\->addPt(0,99); \& $image\->polygon($poly,$blue); .Ve .ie n .IP "$image\->filledPolygon($polygon,$color);" 4 .el .IP "\f(CW$image\fR\->filledPolygon($polygon,$color);" 4 .IX Item "$image->filledPolygon($polygon,$color);" This draws a polygon filled with the specified color. Drawing with the special colors is also permitted. See the documentation for the \&\fBline()\fR method for additional details. .Sp .Vb 5 \& # make a polygon \& $poly = new GD::Polygon; \& $poly\->addPt(50,0); \& $poly\->addPt(99,99); \& $poly\->addPt(0,99); \& \& # draw the polygon, filling it with a color \& $image\->filledPolygon($poly,$peachpuff); .Ve .ie n .IP "$image\->filledPolygon($polygon,$color);" 4 .el .IP "\f(CW$image\fR\->filledPolygon($polygon,$color);" 4 .IX Item "$image->filledPolygon($polygon,$color);" This draws a polygon filled with the specified color. Drawing with the special colors is also permitted. See the documentation for the \&\fBline()\fR method for additional details. .Sp .Vb 5 \& # make a polygon \& $poly = new GD::Polygon; \& $poly\->addPt(50,0); \& $poly\->addPt(99,99); \& $poly\->addPt(0,99); \& \& # draw the polygon, filling it with a color \& $image\->filledPolygon($poly,$peachpuff); .Ve .ie n .IP "$image\->polyline(polyline,color)" 4 .el .IP "\f(CW$image\fR\->polyline(polyline,color)" 4 .IX Item "$image->polyline(polyline,color)" .Vb 1 \& $image\->polyline($polyline,$black) .Ve .Sp This draws a polyline with the specified color. Both real color indexes and the special colors gdBrushed, gdStyled and gdStyledBrushed can be specified. .Sp Neither the \fBpolyline()\fR method or the \fBpolygon()\fR method are very picky: you can call either method with either a GD::Polygon or a GD::Polyline. The \fImethod\fR determines if the shape is \*(L"closed\*(R" or \&\*(L"open\*(R" as drawn, \fInot\fR the object type. .ie n .IP "$image\->polydraw(polything,color)" 4 .el .IP "\f(CW$image\fR\->polydraw(polything,color)" 4 .IX Item "$image->polydraw(polything,color)" .Vb 1 \& $image\->polydraw($poly,$black) .Ve .Sp This method draws the polything as expected (polygons are closed, polylines are open) by simply checking the object type and calling either \f(CW$image\fR\->\fBpolygon()\fR or \f(CW$image\fR\->\fBpolyline()\fR. .ie n .IP "$image\->ellipse($cx,$cy,$width,$height,$color)" 4 .el .IP "\f(CW$image\fR\->ellipse($cx,$cy,$width,$height,$color)" 4 .IX Item "$image->ellipse($cx,$cy,$width,$height,$color)" .PD 0 .ie n .IP "$image\->filledEllipse($cx,$cy,$width,$height,$color)" 4 .el .IP "\f(CW$image\fR\->filledEllipse($cx,$cy,$width,$height,$color)" 4 .IX Item "$image->filledEllipse($cx,$cy,$width,$height,$color)" .PD These \fBmethods()\fR draw ellipses. ($cx,$cy) is the center of the arc, and ($width,$height) specify the ellipse width and height, respectively. \&\fBfilledEllipse()\fR is like \fBellipse()\fR except that the former produces filled versions of the ellipse. Drawing with the special colors is also permitted. See the documentation for the \fBline()\fR method for additional details. .ie n .IP "$image\->arc($cy,$cy,$width,$height,$start,$end,$color);" 4 .el .IP "\f(CW$image\fR\->arc($cy,$cy,$width,$height,$start,$end,$color);" 4 .IX Item "$image->arc($cy,$cy,$width,$height,$start,$end,$color);" This draws arcs and ellipses. (cx,cy) are the center of the arc, and (width,height) specify the width and height, respectively. The portion of the ellipse covered by the arc are controlled by start and end, both of which are given in degrees from 0 to 360. Zero is at the top of the ellipse, and angles increase clockwise. To specify a complete ellipse, use 0 and 360 as the starting and ending angles. To draw a circle, use the same value for width and height. .Sp Internally, \fBarc()\fR calls the \fBellipse()\fR method of \s-1SVG\s0.pm. Drawing with the special colors is also permitted. See the documentation for the \&\fBline()\fR method for additional details. .Sp Currently, true arcs are \s-1NOT\s0 supported, only those where the start and end equal 0 and 360 respectively resulting in a closed arc. .ie n .IP "$image\->filledArc($cx,$cy,$width,$height,$start,$end,$color [,$arc_style])" 4 .el .IP "\f(CW$image\fR\->filledArc($cx,$cy,$width,$height,$start,$end,$color [,$arc_style])" 4 .IX Item "$image->filledArc($cx,$cy,$width,$height,$start,$end,$color [,$arc_style])" This method is like \fBarc()\fR except that it colors in the pie wedge with the selected color. \f(CW$arc_style\fR is optional. If present it is a bitwise \s-1OR\s0 of the following constants: .Sp gdArc connect start & end points of arc with a rounded edge gdChord connect start & end points of arc with a straight line gdPie synonym for gdChord gdNoFill outline the arc or chord gdEdged connect beginning and ending of the arc to the center .Sp gdArc and gdChord are mutally exclusive. gdChord just connects the starting and ending angles with a straight line, while gdArc pro\- duces a rounded edge. gdPie is a synonym for gdArc. gdNoFill indi\- cates that the arc or chord should be outlined, not filled. gdEdged, used together with gdNoFill, indicates that the beginning and ending angles should be connected to the center; this is a good way to outline (rather than fill) a \*(L"pie slice.\*(R" .Sp Using these special styles, you can easily draw bordered ellipses and circles. .Sp # Create the filled shape: \&\f(CW$image\fR\->filledArc($x,$y,$width,$height,0,360,$fill); # Now border it. \&\f(CW$image\fR\->filledArc($x,$y,$width,$height,0,360,$color,gdNoFill); .ie n .IP "$image\->\fBfill()\fR;" 4 .el .IP "\f(CW$image\fR\->\fBfill()\fR;" 4 .IX Item "$image->fill();" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$image\->\fBfillToBorder()\fR" 4 .el .IP "\f(CW$image\fR\->\fBfillToBorder()\fR" 4 .IX Item "$image->fillToBorder()" \&\s-1NOT IMPLEMENTED\s0 .SS "Image Copying Methods" .IX Subsection "Image Copying Methods" The basic \fBcopy()\fR command is implemented in \s-1GD::SVG.\s0 You can copy one \&\s-1GD::SVG\s0 into another \s-1GD::SVG,\s0 or copy a GD::Image or GD::Simple object into a \s-1GD::SVG,\s0 thereby embedding a pixmap image into the \s-1SVG\s0 image. .PP All other image copying methods are unsupported, and if your script calls one of the following methods, your script will die remorsefully with a warning. With sufficient demand, I might try to implement some of these methods. For now, I think that they are beyond the intent of \&\s-1GD::SVG.\s0 .PP .Vb 6 \& $image\->clone() \& $image\->copyMerge() \& $image\->copyMergeGray() \& $image\->copyResized() \& $image\->copyResampled() \& $image\->trueColorToPalette() .Ve .SS "Image Transfomation Commands" .IX Subsection "Image Transfomation Commands" None of the image transformation commands are implemented in \s-1GD::SVG.\s0 If your script calls one of the following methods, your script will die remorsefully with a warning. With sufficient demand, I might try to implement some of these methods. For now, I think that they are beyond the intent of \s-1GD::SVG.\s0 .PP .Vb 10 \& $image = $sourceImage\->copyRotate90() \& $image = $sourceImage\->copyRotate180() \& $image = $sourceImage\->copyRotate270() \& $image = $sourceImage\->copyFlipHorizontal() \& $image = $sourceImage\->copyFlipVertical() \& $image = $sourceImage\->copyTranspose() \& $image = $sourceImage\->copyReverseTranspose() \& $image\->rotate180() \& $image\->flipHorizontal() \& $image\->flipVertical() .Ve .SS "Character And String Drawing" .IX Subsection "Character And String Drawing" \&\s-1GD\s0 allows you to draw characters and strings, either in normal horizon\- tal orientation or rotated 90 degrees. In \s-1GD,\s0 these routines use a GD::Font object. Internally, \s-1GD::SVG\s0 mimics the behavior of \s-1GD\s0 with respect to fonts in a very similar manner, using instead a GD::SVG::Font object described in more detail below. .PP \&\s-1GD\s0's font handling abilities are not as flexible as \s-1SVG\s0 and it does not allow the dynamic creation of fonts, instead exporting five available fonts as global variables: gdGiantFont, gdLargeFont, gdMediumBoldFont, gdSmallFont and gdTinyFont. \s-1GD::SVG\s0 also exports these same global variables but establishes them in a different manner using constant variables to establish the font family, font height and width of these global fonts. These values were chosen to match as closely as possible \s-1GD\s0's output. If unsatisfactory, adjust the constants at the top of this file. In all subroutines below, \s-1GD::SVG\s0 passes a generic GD::SVG::Font object in place of the exported font variables. .ie n .IP "$image\->string($font,$x,$y,$string,$color)" 4 .el .IP "\f(CW$image\fR\->string($font,$x,$y,$string,$color)" 4 .IX Item "$image->string($font,$x,$y,$string,$color)" This method draws a string starting at position (x,y) in the speci\- fied font and color. Your choices of fonts are gdSmallFont, gdMediumBoldFont, gdTinyFont, gdLargeFont and gdGiantFont. .Sp .Vb 1 \& $myImage\->string(gdSmallFont,2,10,"Peachy Keen",$peach); .Ve .ie n .IP "$image\->stringUp($font,$x,$y,$string,$color)" 4 .el .IP "\f(CW$image\fR\->stringUp($font,$x,$y,$string,$color)" 4 .IX Item "$image->stringUp($font,$x,$y,$string,$color)" Same as the previous example, except that it draws the text rotated counter-clockwise 90 degrees. .ie n .IP "$image\->char($font,$x,$y,$char,$color)" 4 .el .IP "\f(CW$image\fR\->char($font,$x,$y,$char,$color)" 4 .IX Item "$image->char($font,$x,$y,$char,$color)" .PD 0 .ie n .IP "$image\->charUp($font,$x,$y,$char,$color)" 4 .el .IP "\f(CW$image\fR\->charUp($font,$x,$y,$char,$color)" 4 .IX Item "$image->charUp($font,$x,$y,$char,$color)" .PD These methods draw single characters at position (x,y) in the spec\- ified font and color. They're carry-overs from the C interface, where there is a distinction between characters and strings. Perl is insensible to such subtle distinctions. Neither is \s-1SVG,\s0 which simply calls the \fBstring()\fR method internally. .ie n .IP "@bounds = $image\->stringFT($fgcolor,$font\- name,$ptsize,$angle,$x,$y,$string)" 4 .el .IP "\f(CW@bounds\fR = \f(CW$image\fR\->stringFT($fgcolor,$font\- name,$ptsize,$angle,$x,$y,$string)" 4 .IX Item "@bounds = $image->stringFT($fgcolor,$font- name,$ptsize,$angle,$x,$y,$string)" .PD 0 .ie n .IP "@bounds = $image\->stringFT($fgcolor,$font\- name,$ptsize,$angle,$x,$y,$string,\e%options)" 4 .el .IP "\f(CW@bounds\fR = \f(CW$image\fR\->stringFT($fgcolor,$font\- name,$ptsize,$angle,$x,$y,$string,\e%options)" 4 .IX Item "@bounds = $image->stringFT($fgcolor,$font- name,$ptsize,$angle,$x,$y,$string,%options)" .PD In \s-1GD,\s0 these methods use TrueType to draw a scaled, antialiased strings using the TrueType font of your choice. \s-1GD::SVG\s0 can handle this directly generating by calling the \fBstring()\fR method internally. .Sp .Vb 1 \& The arguments are as follows: \& \& fgcolor Color index to draw the string in \& fontname An absolute path to the TrueType (.ttf) font file \& ptsize The desired point size (may be fractional) \& angle The rotation angle, in radians \& x,y X and Y coordinates to start drawing the string \& string The string itself .Ve .Sp \&\s-1GD::SVG\s0 attempts to extract the name of the font from the pathname supplied in the fontname argument. If it fails, Helvetica will be used instead. .Sp If successful, the method returns an eight-element list giving the boundaries of the rendered string: .Sp .Vb 4 \& @bounds[0,1] Lower left corner (x,y) \& @bounds[2,3] Lower right corner (x,y) \& @bounds[4,5] Upper right corner (x,y) \& @bounds[6,7] Upper left corner (x,y) .Ve .Sp This from the \s-1GD\s0 documentation (not yet implemented in \s-1GD::SVG\s0): .Sp An optional 8th argument allows you to pass a hashref of options to \&\fBstringFT()\fR. Two hashkeys are recognized: linespacing, if present, controls the spacing between lines of text. charmap, if present, sets the character map to use. .Sp The value of linespacing is supposed to be a multiple of the char\- acter height, so setting linespacing to 2.0 will result in double\- spaced lines of text. However the current version of libgd (2.0.12) does not do this. Instead the linespacing seems to be double what is provided in this argument. So use a spacing of 0.5 to get separation of exactly one line of text. In practice, a spacing of 0.6 seems to give nice results. Another thing to watch out for is that successive lines of text should be separated by the \*(L"\er\en\*(R" characters, not just \&\*(L"\en\*(R". .Sp The value of charmap is one of \*(L"Unicode\*(R", \*(L"Shift_JIS\*(R" and \*(L"Big5\*(R". The interaction between Perl, Unicode and libgd is not clear to me, and you should experiment a bit if you want to use this feature. .Sp .Vb 5 \& $gd\->stringFT($black,\*(Aq/dosc/windows/Fonts/pala.ttf\*(Aq,40,0,20,90, \& "hi there\er\enbye now", \& {linespacing=>0.6, \& charmap => \*(AqUnicode\*(Aq, \& }); .Ve .Sp For backward compatibility with older versions of the FreeType library, the alias \fBstringTTF()\fR is also recognized. Also be aware that relative font paths are not recognized due to problems in the libgd library. .ie n .IP "$hasfontconfig = $image\->useFontConfig($flag)" 4 .el .IP "\f(CW$hasfontconfig\fR = \f(CW$image\fR\->useFontConfig($flag)" 4 .IX Item "$hasfontconfig = $image->useFontConfig($flag)" Call \fBuseFontConfig()\fR with a value of 1 in order to enable support for fontconfig font patterns (see stringFT). Regardless of the value of \&\f(CW$flag\fR, this method will return a true value if the fontconfig library is present, or false otherwise. .Sp \&\s-1NOT IMPLEMENTED\s0 .SS "Alpha Channels" .IX Subsection "Alpha Channels" .ie n .IP "$image\->alphaBlending($blending)" 4 .el .IP "\f(CW$image\fR\->alphaBlending($blending)" 4 .IX Item "$image->alphaBlending($blending)" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$image\->saveAlpha($saveAlpha)" 4 .el .IP "\f(CW$image\fR\->saveAlpha($saveAlpha)" 4 .IX Item "$image->saveAlpha($saveAlpha)" \&\s-1NOT IMPLEMENTED\s0 .SS "Miscellaneous Image Methods" .IX Subsection "Miscellaneous Image Methods" .ie n .IP "$image\->interlaced([$flag])" 4 .el .IP "\f(CW$image\fR\->interlaced([$flag])" 4 .IX Item "$image->interlaced([$flag])" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "($width,$height) = $image\->\fBgetBounds()\fR" 4 .el .IP "($width,$height) = \f(CW$image\fR\->\fBgetBounds()\fR" 4 .IX Item "($width,$height) = $image->getBounds()" \&\fBgetBounds()\fR returns the height and width of the image. .ie n .IP "$is_truecolor = $image\->\fBisTrueColor()\fR" 4 .el .IP "\f(CW$is_truecolor\fR = \f(CW$image\fR\->\fBisTrueColor()\fR" 4 .IX Item "$is_truecolor = $image->isTrueColor()" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$flag = $image1\->compare($image2)" 4 .el .IP "\f(CW$flag\fR = \f(CW$image1\fR\->compare($image2)" 4 .IX Item "$flag = $image1->compare($image2)" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$image\->clip($x1,$y1,$x2,$y2) ($x1,$y1,$x2,$y2) = $image\->clip" 4 .el .IP "\f(CW$image\fR\->clip($x1,$y1,$x2,$y2) ($x1,$y1,$x2,$y2) = \f(CW$image\fR\->clip" 4 .IX Item "$image->clip($x1,$y1,$x2,$y2) ($x1,$y1,$x2,$y2) = $image->clip" \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$flag = $image\->boundsSafe($x,$y)" 4 .el .IP "\f(CW$flag\fR = \f(CW$image\fR\->boundsSafe($x,$y)" 4 .IX Item "$flag = $image->boundsSafe($x,$y)" \&\s-1NOT IMPLEMENTED\s0 .SH "GD::SVG::Polygon METHODS" .IX Header "GD::SVG::Polygon METHODS" \&\s-1SVG\s0 is much more adept at creating polygons than \s-1GD.\s0 That said, \s-1GD\s0 does provide some rudimentary support for polygons but must be created as seperate objects point by point. .ie n .IP "$poly = GD::SVG::Polygon\->new" 4 .el .IP "\f(CW$poly\fR = GD::SVG::Polygon\->new" 4 .IX Item "$poly = GD::SVG::Polygon->new" Create an empty polygon with no vertices. .Sp .Vb 1 \& $poly = new GD::SVG::Polygon; .Ve .ie n .IP "$poly\->addPt($x,$y)" 4 .el .IP "\f(CW$poly\fR\->addPt($x,$y)" 4 .IX Item "$poly->addPt($x,$y)" Add point (x,y) to the polygon. .Sp .Vb 3 \& $poly\->addPt(0,0); \& $poly\->addPt(0,50); \& $poly\->addPt(25,25); .Ve .ie n .IP "($x,$y) = $poly\->getPt($index)" 4 .el .IP "($x,$y) = \f(CW$poly\fR\->getPt($index)" 4 .IX Item "($x,$y) = $poly->getPt($index)" Retrieve the point at the specified vertex. .Sp .Vb 1 \& ($x,$y) = $poly\->getPt(2); .Ve .ie n .IP "$poly\->setPt($index,$x,$y)" 4 .el .IP "\f(CW$poly\fR\->setPt($index,$x,$y)" 4 .IX Item "$poly->setPt($index,$x,$y)" Change the value of an already existing vertex. It is an error to set a vertex that isn't already defined. .Sp .Vb 1 \& $poly\->setPt(2,100,100); .Ve .ie n .IP "($x,$y) = $poly\->deletePt($index)" 4 .el .IP "($x,$y) = \f(CW$poly\fR\->deletePt($index)" 4 .IX Item "($x,$y) = $poly->deletePt($index)" Delete the specified vertex, returning its value. .Sp .Vb 1 \& ($x,$y) = $poly\->deletePt(1); .Ve .ie n .IP "$poly\->toPt($dx,$dy)" 4 .el .IP "\f(CW$poly\fR\->toPt($dx,$dy)" 4 .IX Item "$poly->toPt($dx,$dy)" Draw from current vertex to a new vertex, using relative (dx,dy) coordinates. If this is the first point, act like \fBaddPt()\fR. .Sp .Vb 3 \& $poly\->addPt(0,0); \& $poly\->toPt(0,50); \& $poly\->toPt(25,\-25); .Ve .Sp \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$vertex_count = $poly\->\fBlength()\fR" 4 .el .IP "\f(CW$vertex_count\fR = \f(CW$poly\fR\->\fBlength()\fR" 4 .IX Item "$vertex_count = $poly->length()" Return the number of vertices in the polygon. .ie n .IP "@vertices = $poly\->\fBvertices()\fR" 4 .el .IP "\f(CW@vertices\fR = \f(CW$poly\fR\->\fBvertices()\fR" 4 .IX Item "@vertices = $poly->vertices()" Return a list of all the verticies in the polygon object. Each mem\- ber of the list is a reference to an (x,y) array. .Sp .Vb 4 \& @vertices = $poly\->vertices; \& foreach $v (@vertices) \& print join(",",@$v),"\en"; \& } .Ve .ie n .IP "@rect = $poly\->\fBbounds()\fR" 4 .el .IP "\f(CW@rect\fR = \f(CW$poly\fR\->\fBbounds()\fR" 4 .IX Item "@rect = $poly->bounds()" Return the smallest rectangle that completely encloses the polygon. The return value is an array containing the (left,top,right,bottom) of the rectangle. .Sp .Vb 1 \& ($left,$top,$right,$bottom) = $poly\->bounds; .Ve .ie n .IP "$poly\->offset($dx,$dy)" 4 .el .IP "\f(CW$poly\fR\->offset($dx,$dy)" 4 .IX Item "$poly->offset($dx,$dy)" Offset all the vertices of the polygon by the specified horizontal (dh) and vertical (dy) amounts. Positive numbers move the polygon down and to the right. Returns the number of vertices affected. .Sp .Vb 1 \& $poly\->offset(10,30); .Ve .ie n .IP "$poly\->map($srcL,$srcT,$srcR,$srcB,$destL,$dstT,$dstR,$dstB)" 4 .el .IP "\f(CW$poly\fR\->map($srcL,$srcT,$srcR,$srcB,$destL,$dstT,$dstR,$dstB)" 4 .IX Item "$poly->map($srcL,$srcT,$srcR,$srcB,$destL,$dstT,$dstR,$dstB)" Map the polygon from a source rectangle to an equivalent position in a destination rectangle, moving it and resizing it as necessary. See polys.pl for an example of how this works. Both the source and destination rectangles are given in (left,top,right,bottom) coordi\- nates. For convenience, you can use the polygon's own bounding box as the source rectangle. .Sp .Vb 2 \& # Make the polygon really tall \& $poly\->map($poly\->bounds,0,0,50,200); .Ve .Sp \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$poly\->scale($sx,$sy)" 4 .el .IP "\f(CW$poly\fR\->scale($sx,$sy)" 4 .IX Item "$poly->scale($sx,$sy)" Scale each vertex of the polygon by the X and Y factors indicated by sx and sy. For example scale(2,2) will make the polygon twice as large. For best results, move the center of the polygon to position (0,0) before you scale, then move it back to its previous position. .Sp \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$poly\->transform($sx,$rx,$sy,$ry,$tx,$ty)" 4 .el .IP "\f(CW$poly\fR\->transform($sx,$rx,$sy,$ry,$tx,$ty)" 4 .IX Item "$poly->transform($sx,$rx,$sy,$ry,$tx,$ty)" Run each vertex of the polygon through a transformation matrix, where sx and sy are the X and Y scaling factors, rx and ry are the X and Y rotation factors, and tx and ty are X and Y offsets. See the Adobe PostScript Reference, page 154 for a full explanation, or experiment. .Sp \&\s-1NOT IMPLEMENTED\s0 .SS "GD::Polyline" .IX Subsection "GD::Polyline" Please see GD::Polyline for information on creating open polygons and splines. .SH "GD::SVG::Font METHODS" .IX Header "GD::SVG::Font METHODS" \&\s-1NOTE:\s0 The object-oriented implementation to font utilites is not yet supported. .PP The libgd library (used by the Perl \s-1GD\s0 library) has built-in support for about half a dozen fonts, which were converted from public-domain X Windows fonts. For more fonts, compile libgd with TrueType support and use the \fBstringFT()\fR call. .PP \&\s-1GD::SVG\s0 replicates the internal fonts of \s-1GD\s0 by hardcoding fonts which resemble the design and point size of the original. Each of these fonts is available both as an imported global (e.g. gdSmallFont) and as a package method (e.g. GD::Font\->Small). .IP "gdTinyFont" 4 .IX Item "gdTinyFont" .PD 0 .IP "GD::Font\->Tiny" 4 .IX Item "GD::Font->Tiny" .PD This is a tiny, almost unreadable font, 5x8 pixels wide. .IP "gdSmallFont" 4 .IX Item "gdSmallFont" .PD 0 .IP "GD::Font\->Small" 4 .IX Item "GD::Font->Small" .PD This is the basic small font, \*(L"borrowed\*(R" from a well known public domain 6x12 font. .IP "gdMediumBoldFont" 4 .IX Item "gdMediumBoldFont" .PD 0 .IP "GD::Font\->MediumBold" 4 .IX Item "GD::Font->MediumBold" .PD This is a bold font intermediate in size between the small and large fonts, borrowed from a public domain 7x13 font; .IP "gdLargeFont" 4 .IX Item "gdLargeFont" .PD 0 .IP "GD::Font\->Large" 4 .IX Item "GD::Font->Large" .PD This is the basic large font, \*(L"borrowed\*(R" from a well known public domain 8x16 font. .IP "gdGiantFont" 4 .IX Item "gdGiantFont" .PD 0 .IP "GD::Font\->Giant" 4 .IX Item "GD::Font->Giant" .PD This is a 9x15 bold font converted by Jan Pazdziora from a sans serif X11 font. .ie n .IP "$font\->nchars" 4 .el .IP "\f(CW$font\fR\->nchars" 4 .IX Item "$font->nchars" This returns the number of characters in the font. .Sp .Vb 1 \& print "The large font contains ",gdLargeFont\->nchars," characters\en"; .Ve .Sp \&\s-1NOT IMPLEMENTED\s0 .ie n .IP "$font\->\fBoffset()\fR" 4 .el .IP "\f(CW$font\fR\->\fBoffset()\fR" 4 .IX Item "$font->offset()" This returns the \s-1ASCII\s0 value of the first character in the font .ie n .IP "$width = $font\->width" 4 .el .IP "\f(CW$width\fR = \f(CW$font\fR\->width" 4 .IX Item "$width = $font->width" .PD 0 .ie n .IP "$height = $font\->height" 4 .el .IP "\f(CW$height\fR = \f(CW$font\fR\->height" 4 .IX Item "$height = $font->height" .PD These return the width and height of the font. .Sp .Vb 1 \& ($w,$h) = (gdLargeFont\->width,gdLargeFont\->height); .Ve .SH "REAL WORLD EXAMPLES" .IX Header "REAL WORLD EXAMPLES" .IP "BioPerl" 4 .IX Item "BioPerl" The Bio::Graphics package of the BioPerl project makes use of \s-1GD::SVG\s0 to export \s-1SVG\s0 graphics. .Sp .Vb 1 \& http://www.bioperl.org/ .Ve .IP "Generic Genome Browser" 4 .IX Item "Generic Genome Browser" The Generic Genome Browser (GBrowse) utilizes Bio::Graphics and enables \s-1SVG\s0 dumping of genomics views. You can see a real-world example of \s-1SVG\s0 output from GBrowse at WormBase: .Sp .Vb 1 \& http://www.wormbase.org/cgi\-bin/gbrowse/ .Ve .Sp Further information about the Generic Genome Browser is available at the Generic Model Organism Project home page: .Sp .Vb 1 \& http://www.gmod.org/ .Ve .IP "toddot" 4 .IX Item "toddot" I've also prepared a number of comparative images at my website (shameless plug, hehe): .Sp .Vb 1 \& http://www.toddot.net/projects/GD\-SVG/ .Ve .SH "INTERNAL METHODS" .IX Header "INTERNAL METHODS" The following internal methods are private and documented only for those wishing to extend the \s-1GD::SVG\s0 interface. .IP "\fB_distill_gdSpecial()\fR" 4 .IX Item "_distill_gdSpecial()" When a drawing method is passed a stylized brush via gdBrushed, the internal \fB_distill_gdSpecial()\fR method attempts to make sense of this by setting line thickness and foreground color. Since stylized brushes are GD::SVG::Image objects, it does this by fetching the width of the image using the getBounds method. This width is then used to setThickness. The last color set by colorAllocate is then used for the foreground color. .Sp In setting line thickness, \s-1GD::SVG\s0 temporarily overrides any previously set line thickness. In \s-1GD,\s0 setThickness is persistent through uses of stylized brushes. To accomodate this behavior, \&\fB_distill_gdSpecial()\fR temporarily stores the previous line_thickness in the \f(CW$self\fR\->{previous_line_thickness} flag. .IP "\fB_reset()\fR" 4 .IX Item "_reset()" The \fB_reset()\fR method is used to restore persistent drawing settings between uses of stylized brushes. Currently, this involves .Sp .Vb 1 \& \- restoring line thickness .Ve .SH "IMPORTANT NOTE! GD::SVG / SVG::GD" .IX Header "IMPORTANT NOTE! GD::SVG / SVG::GD" A second module (\s-1SVG::GD\s0), written by Ronan Oger also provides similar functionality as this module. Ronan and I are concurrently developing these modules with an eye towards integrating them in the future. In principle, the primary difference is that \s-1GD::SVG\s0 aims to generate \s-1SVG\s0 and \s-1SVG\s0 only. That is, it: .PP .Vb 1 \& 1. Does not store an internal representation of the GD image \& \& 2. Does not enable JPG, PNG, OR SVG output from a single pass \& through data \& \& 3. Only occasioanally uses inherited methods from GD .Ve .PP Instead \s-1GD::SVG\s0 depends on the user to choose which output format they would like in advance, \*(L"use\*(R"ing the appropriate module for that output. As described at the start of this document, module selection between \s-1GD\s0 and \s-1GD::SVG\s0 can be made dynamically using eval statements and variables for the differnet classes that \s-1GD\s0 and \s-1GD::SVG\s0 create. .PP There is a second reason for not maintaining a double representation of the data in \s-1GD\s0 and \s-1SVG\s0 format: \s-1SVG\s0 documents can quickly become very large, especially with large datasets. In cases where scripts are primarily generating png images in a server environment and would only occasionally need to export \s-1SVG,\s0 gernerating an \s-1SVG\s0 image in parallel would result in an unacceptable performance hit. .PP Thus \s-1GD::SVG\s0 aims to be a plugin for existing configurations that depend on \s-1GD\s0 but would like to take advantage of \s-1SVG\s0 output. .PP \&\s-1SVG::GD,\s0 on the other hand, aims to tie in the raster-editing ability of \s-1GD\s0 with the power of \s-1SVG\s0 output. In part, it aims to do this by inheriting many methods from \s-1GD\s0 directly and bringing them into the functional space of \s-1GD.\s0 This makes \s-1SVG::GD\s0 easier to set up initially (simply by adding the \*(L"use \s-1SVG::GD\*(R"\s0 below the \*(L"use \s-1GD\*(R"\s0 statement of your script. \s-1GD::SVG\s0 sacrfices this initial ease-of-setup for more targeted applications. .SH "ACKNOWLEDGEMENTS" .IX Header "ACKNOWLEDGEMENTS" Lincoln Stein, my postdoctoral mentor, author of \s-1GD\s0.pm, and all around Perl stud. Ronan Oger, author of \s-1SVG\s0.pm conceptualized and implemented another wrapper around \s-1GD\s0 at about the exact same time as this module. He also provided helpful discussions on implementing \s-1GD\s0 functions into \&\s-1SVG.\s0 Oliver Drechsel and Marc Lohse provided patches to actually make the stringUP method functional. .SH "AUTHOR" .IX Header "AUTHOR" Todd Harris, PhD .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright @ 2003\-2005 Todd Harris and the Cold Spring Harbor Laboratory .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\s-1GD\s0, \&\s-1SVG\s0, SVG::Manual, \&\s-1SVG::DOM\s0