BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * Painter - A PHP GD Library. * @author Nnamdi Onyeyiri * @version 1.0 * @package Painter */ /* Geometric Primitives ----------------------------------------------------- */ /** * Encapsulates a point in 2-dimensional space. * @package Painter */ class Point { /** * X co-ordinate. * @var number */ var $X; /** * Y co-ordinate. * @var number */ var $Y; /** * Creates a new Point object. * @param number $x The X co-ordinate. * @param number $y The Y co-ordinate. */ function Point ($x, $y) { painter_enforce_type ($x, "number"); painter_enforce_type ($y, "number"); $this->X = $x; $this->Y = $y; } } /** * Encapsulates a rectangle. * @package Painter */ class Rect { /** * X co-ordinate of upper left corner. * @var number */ var $X; /** * Y co-ordinate of upper left corner. * @var number */ var $Y; /** * Rectangle width. * @var number */ var $Width; /** * Rectangle height. * @var number */ var $Height; /** * Creates a new Rect object. * @param number $x The upper left corner X co-ordinate. * @param number $y The upper left corner Y co-ordinate. * @param number $w The width of the Rect. * @param number $h The height of the Rect. */ function Rect ($x, $y, $w, $h) { painter_enforce_type ($x, "number"); painter_enforce_type ($y, "number"); painter_enforce_type ($w, "number"); painter_enforce_type ($h, "number"); $this->X = $x; $this->Y = $y; $this->Width = $w; $this->Height = $h; } /** * Srinks the Rect by the specified number of pixels. * @param int $v The number of pixels to shrink the Rect by. * @return Rect */ function Shrink ($v = 1) { painter_enforce_type ($v, "number"); $x = $this->X + $v; $y = $this->Y + $v; $w = $this->Width - ($v * 2); $h = $this->Height - ($v * 2); return new Rect ($x, $y, $w, $h); } /** * Expands the Rect by the specified number of pixels. * @param int $v The number of pixels to expand the Rect by. * @return Rect */ function Grow ($v = 1) { painter_enforce_type ($v, "number"); $x = $this->X - $v; $y = $this->Y - $v; $w = $this->Width + ($v * 2); $h = $this->Height + ($v * 2); return new Rect ($x, $y, $w, $h); } } /** * Encapsulates an ellipse. * @package Painter */ class Ellipse { /** * The X co-ordinate of the center of the ellipse. * @var number */ var $X; /** * The Y co-ordinate of the center of the ellipse. * @var number */ var $Y; /** * Ellipse width. * @var number */ var $Width; /** * Ellipse height. * @var number */ var $Height; /** * Creates a new Ellipse object. * @param number $x The upper left corner X co-ordinate. * @param number $y The upper left corner Y co-ordinate. * @param number $w The width of the Ellipse. * @param number $h The height of the Ellipse. */ function Ellipse ($x, $y, $w, $h) { painter_enforce_type ($x, "number"); painter_enforce_type ($y, "number"); painter_enforce_type ($w, "number"); painter_enforce_type ($h, "number"); $this->X = $x; $this->Y = $y; $this->Width = $w; $this->Height = $h; } /** * Srinks the Ellipse by the specified number of pixels. * @param int $v The number of pixels to shrink the Ellipse by. * @return Ellipse */ function Shrink ($v = 1) { painter_enforce_type ($v, "number"); $w = $this->Width - ($v * 2); $h = $this->Height - ($v * 2); return new Ellipse ($this->X, $this->Y, $w, $h); } /** * Expands the Ellipse by the specified number of pixels. * @param int $v The number of pixels to expand the Ellipse by. * @return Ellipse */ function Grow ($v = 1) { painter_enforce_type ($v, "number"); $w = $this->Width + ($v * 2); $h = $this->Height + ($v * 2); return new Ellipse ($this->X, $this->Y, $w, $h); } } /** * Encapsulates an arc. * @package Painter */ class Arc { /** * The X co-ordinate of the ellipse the arc is a part of. * @var number */ var $X; /** * The Y co-ordinate of the ellipse the arc is a part of. * @var number */ var $Y; /** * The width of the ellipse the arc is a part of. * @var number */ var $Width; /** * The height of the ellipse the arc is a part of. * @var number */ var $Height; /** * The start angle of the arc. * @var number */ var $Start; /** * The end angle of the arc. * @var number */ var $End; /** * Creates a new Arc object. * @param number $x The upper left corner X co-ordinate. * @param number $y The upper left corner Y co-ordinate. * @param number $w The width of the Arc. * @param number $h The height of the Arc. * @param number $s The start angle. * @param number $e The end angle. */ function Arc ($x, $y, $w, $h, $s, $e) { painter_enforce_type ($x, "number"); painter_enforce_type ($y, "number"); painter_enforce_type ($w, "number"); painter_enforce_type ($h, "number"); painter_enforce_type ($s, "number"); painter_enforce_type ($e, "number"); $this->X = $x; $this->Y = $y; $this->Width = $w; $this->Height = $h; $this->Start = $s; $this->End = $e; } /** * Srinks the Arc by the specified number of pixels. * @param int $v The number of pixels to shrink the Arc by. * @return Arc */ function Shrink ($v = 1) { painter_enforce_type ($v, "number"); $w = $this->Width - ($v * 2); $h = $this->Height - ($v * 2); return new Arc ($this->X, $this->Y, $w, $h, $this->Start, $this->End); } /** * Expands the Arc by the specified number of pixels. * @param int $v The number of pixels to expand the Arc by. * @return Arc */ function Grow ($v = 1) { painter_enforce_type ($v, "number"); $w = $this->Width + ($v * 2); $h = $this->Height + ($v * 2); return new Arc ($this->X, $this->Y, $w, $h, $this->Start, $this->End); } } /** * Encapsulates a polygon. * @package Painter */ class Polygon { /** * An array of the points that form the polygon. * @var number */ var $Points; /** * Expands the Arc by the specified number of pixels. * @param array $pts An array of Point objects that form the polygon. */ function Polygon ($pts = null) { $this->Points = array (); if ($pts != null) { painter_enforce_type ($pts, "array"); $this->Points = $pts; } } /** * Adds a new Point to the polygon. * @param Point $pt The Point to add. */ function AddPoint ($pt) { painter_enforce_type ($pt, "Point"); $this->Points[] = $pt; } /** * Makes this Polygon the same as the specified Rect $r. * @param Rect $r The Rect to model. */ function FromRect ($r) { painter_enforce_type ($r, "Rect"); $this->Points = array (); $this->AddPoint (new Point ($r->X, $r->Y)); $this->AddPoint (new Point ($r->X + $r->Width, $r->Y)); $this->AddPoint (new Point ($r->X + $r->Width, $r->Y + $r->Height)); $this->AddPoint (new Point ($r->X, $r->Y + $r->Height)); $this->AddPoint (new Point ($r->X, $r->Y)); } /** * Makes this Polygon the same as the specified Ellipse $el. * @param Ellipse $el The Ellipse to model. */ function FromEllipse ($el) { $arc = new Arc ($el->X, $el->Y, $el->Width, $el->Height, 0, 360); $this->Points = $this->_Arc2Polygon ($arc); } /** * Makes this Polygon the same as the specified Arc $arc. * @param Arc $arc The Arc to model. */ function FromArc ($arc) { $this->Points = $this->_Arc2Polygon ($arc); } /** * Returns the center point of the polygon. * @return Point */ function GetCenter () { $len = count ($this->Points); $x = 0; $y = 0; for ($i = 0; $i < $len; $i++) { $x += $this->Points[$i]->X; $y += $this->Points[$i]->Y; } $x = round ($x / $len); $y = round ($y / $len); return new Point ($x, $y); } /** * @access private */ function _Arc2Polygon ($arc) { $pts = array (); $beta = -deg2rad (90); $sinbeta = sin ($beta); $cosbeta = cos ($beta); $a = $arc->Height / 2; $b = $arc->Width / 2; for ($i = $arc->Start; $i < $arc->End; $i += 10) { $alpha = deg2rad ($i); $sinalpha = sin ($alpha); $cosalpha = cos ($alpha); $cc = $cosalpha * $costbeta; $ss = $sinalpha * $sinbeta; $cas = $cosalpha * $sinbeta; $sac = $sinalpha * $cosbeta; $x = $arc->X + (($a * $cc) - ($b * $ss)); $y = $arc->Y + (($a * $cas) + ($b * $sac)); $pts[] = new Point (round ($x), round ($y)); } return $pts; } } /* Geometric Transformations ------------------------------------------------ */ /** * Encapsulates transformations for Polygon objects. * @package Painter */ class Transform { /** * @access private */ var $matrix; /** * Creates a new Transform object. */ function Transform () { $this->Clear (); } /** * Restores the transformation matrix to the identity matrix. */ function Clear () { $this->matrix = array ( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); } /** * Adds a translation operation. * @param number $x Translation along X axis. * @param number $y Translation along Y axis. */ function Translate ($x, $y) { painter_enforce_type ($x, "int"); painter_enforce_type ($y, "int"); $trans = array ( 1, 0, $x, 0, 1, $y, 0, 0, 1); $this->matrix = $this->_Mult ($this->matrix, $trans); } /** * Adds a rotation operation. * @param number $theta The angle of rotation. */ function Rotate ($theta) { painter_enforce_type ($theta, "number"); $t = deg2rad ($theta); $rotate = array ( cos ($t), -sin ($t), 0, sin ($t), cos ($t), 0, 0, 0, 1); $this->matrix = $this->_Mult ($this->matrix, $rotate); } /** * Adds a sheering operation. * @param number $x The sheering value along the X axis. * @param number $y The sheering value along the Y axis. */ function Sheer ($x = 0, $y = 0) { painter_enforce_type ($x, "number"); painter_enforce_type ($y, "number"); $sheer = array ( 1, $x, 0, $y, 1, 0, 0, 0, 1); $this->matrix = $this->_Mult ($this->matrix, $sheer); } /** * Adds a scaling operation. * @param number $x The value to scale in along the X axis. * @param number $y The value to scale in along the Y axis. */ function Scale ($x = 1, $y = 1) { painter_enforce_type ($x, "number"); painter_enforce_type ($y, "number"); $scale = array ( $x, 0, 0, 0, $y, 0, 0, 0, 1); $this->matrix = $this->_Mult ($this->matrix, $scale); } /** * Adds a custom transformation. * @param array $trans A 3x3 transformation matrix to include. */ function CustomTransform ($trans) { painter_enforce_type ($trans, "array"); if (count ($trans) != 9) { painter_error ("Specified transform array must contain 9 elements"); } $this->matrix = $this->_Mult ($this->matrix, $trans); } /** * Performs the stored transformation on $poly. $cx = $y = -1 will set the * centre of the Polygon as origin. * @param Polygon $poly The Polygon to transform. * @param int $cx The X co-ordinate to act as origin. * @param int $cy The Y co-ordinate to act as origin. * @return Polygon */ function Trans ($poly, $cx = -1, $cy = -1) { painter_enforce_type ($poly, "Polygon"); painter_enforce_type ($cx, "int"); painter_enforce_type ($cy, "int"); if ($cx < 0 || $cy < 0) { $cpt = $poly->GetCenter (); $cx = $cpt->X; $cy = $cpt->Y; } $trans = $this->_CentreOrigin ($cx, $cy); $len = count ($poly->Points); $npoly = new Polygon (); for ($i = 0; $i < $len; $i++) { $pt = $poly->Points[$i]; $v = array (0 => $pt->X, 3 => $pt->Y, 6 => 1); $v = $this->_Mult ($trans, $v); $npoly->AddPoint (new Point (round ($v[0]), round ($v[3]))); } return $npoly; } /** * @access private */ function _CentreOrigin ($cx, $cy) { $origin = array ( 1, 0, -$cx, 0, 1, -$cy, 0, 0, 1); $iorigin = array ( 1, 0, $cx, 0, 1, $cy, 0, 0, 1); $trans = $this->_Mult ($this->matrix, $origin); $trans = $this->_Mult ($iorigin, $trans); return $trans; } /** * @access private */ function _Mult ($a, $b) { $c = array (); $p = count ($b) / 3; for ($j = 0; $j < $p; $j++) { for ($i = 0; $i < 3; $i++) { for ($k = 0; $k < 3; $k++) { $c[($i * 3) + $j] += $a[($i * 3) + $k] * $b[($k * 3) + $j]; } } } return $c; } } /* Colour Representation ---------------------------------------------------- */ /** * Encapsulates a colour. * @package Painter */ class Colour { /** * Red colour value. * @var int */ var $R; /** * Green colour value. * @var int */ var $G; /** * Blue colour value. * @var int */ var $B; /** * Alpha colour value. * @var int */ var $A; /** * Creates a new Colour object. * @param int $r Red. * @param int $g Green. * @param int $b Blue. * @param int $a Alpha. */ function Colour ($r = -1, $g = -1, $b = -1, $a = 0) { painter_enforce_type ($r, "number"); painter_enforce_type ($g, "number"); painter_enforce_type ($b, "number"); painter_enforce_type ($a, "number"); if ($r < 0) $r = rand (0, 255); if ($g < 0) $g = rand (0, 255); if ($b < 0) $b = rand (0, 255); $this->R = $r; $this->G = $g; $this->B = $b; $this->A = $a; } /** * Lightens the colour by the percent specified by $d. * @param int $d The percentage to lighten the colour by. */ function Lighten ($d = 10) { list ($h, $s, $v) = $this->_Rgb2Hsv (); $v += $v * ($d / 100); list ($r, $g, $b) = $this->_Hsv2Rgb ($h, $s, $v); $this->R = min ($r, 255); $this->G = min ($g, 255); $this->B = min ($b, 255); } /** * Darkens the colour by the percent specified by $d. * @param int $d The percentage to darken the colour by. */ function Darken ($d = 10) { list ($h, $s, $v) = $this->_Rgb2Hsv (); $v -= $v * ($d / 100); list ($r, $g, $b) = $this->_Hsv2Rgb ($h, $s, $v); $this->R = max ($r, 0); $this->G = max ($g, 0); $this->B = max ($b, 0); } /** * @access private */ function _Rgb2Hsv () { $r = $this->R / 255; $g = $this->G / 255; $b = $this->B / 255; $max = max ($r, max ($g, $b)); $min = min ($r, min ($g, $b)); $dif = $max - $min; if ($max == $min) { $h = 0; } else if ($max == $r && $g >= $b) { $h = 60 * (($g - $b) / $dif); } else if ($max == $r && $g < $b) { $h = (60 * (($g - $b) / $dif)) + 360; } else if ($max == $g) { $h = (60 * (($b - $r) / $dif)) + 120; } else { $h = (60 * (($r - $g) / $dif)) + 240; } $v = $max; if ($max == 0) { $s = 0; } else { $s = ($max - $min) / $max; } return array ($h, $s, $v); } /** * @access private */ function _Hsv2Rgb ($h, $s, $v) { $hi = floor (($h / 60) % 6); $f = ($h / 60) - floor ($h / 60); $p = $v * (1 - $s); $q = $v * (1 - ($f * $s)); $t = $v * ((1 - (1 - $f) * $s)); switch ($hi) { case 0: $r = $v; $g = $t; $b = $p; break; case 1: $r = $q; $g = $v; $b = $p; break; case 2: $r = $p; $g = $v; $b = $t; break; case 3: $r = $p; $g = $q; $b = $v; break; case 4: $r = $t; $g = $p; $b = $v; break; case 5: $r = $v; $g = $p; $b = $q; break; } return array (round ($r * 255), round ($g * 255), round ($b * 255)); } } /* Font Handling ------------------------------------------------------------ */ /** * Encapsulates a font. * @package Painter */ class Font { /**#@+ * @access private */ var $Handle; var $Size; var $Type; var $Path; /**#@-*/ /** * Creates a new Font object. * @param int $sz The size of a built-in font. */ function Font ($sz = -1) { if ($sz > 0) { $this->LoadDefault ($sz); } } /** * Loads a built-in font. * @param int $sz The size of the built-in font. */ function LoadDefault ($sz) { $this->Type = "default"; $this->Size = $sz; } /** * Loads a TTF font. * @param string $path The path to the font file. * @param int $sz The font size. */ function LoadTtfFont ($path, $sz) { painter_enforce_type ($path, "string"); painter_enforce_type ($sz, "number"); $this->Type = "ttf"; $this->Path = $path; $this->Size = $sz; } /** * Loads a PS font. * @param string $path The path to the font file. * @param int $sz The font size. */ function LoadPsFont ($path, $sz) { painter_enforce_type ($path, "string"); painter_enforce_type ($sz, "number"); $this->Type = "ps"; $this->Path = $path; $this->Size = $sz; $this->Handle = imagepsloadfont ($path); } /** * Loads a GD font. * @param string $path The path to the font file. * @param int $sz The font size. */ function LoadGdFont ($path, $sz) { painter_enforce_type ($path, "string"); painter_enforce_type ($sz, "number"); $this->Type = "gd"; $this->Path = $path; $this->Handle = imageloadfont ($path); $this->Size = $sz; } /** * Frees the resources used by a font. */ function Free () { switch ($this->Type) { case "ps": imagepsfreefont ($this->Handle); break; case "gd": imagefreefont ($this->Handle); break; } } } /* The Painter Class -------------------------------------------------------- */ /** * Wrapper class for some GD operations. * @package Painter */ class Painter { /**#@+ * @access private */ var $img; var $width; var $height; /**#@+*/ /** * Creates a new Painter object. * @param int $w The image width. * @param int $h The image height. */ function Painter ($w, $h) { painter_enforce_type ($w, "int"); painter_enforce_type ($h, "int"); $this->img = imagecreatetruecolor ($w, $h); $this->Antialias (); } /** * Returns the underlying image handle. * @return image */ function GetImage () { return $this->img; } /** * Returns the size of the image. * @return array */ function GetSize () { return array ($this->width, $this->height); } /** * Turns on/off antialiasing. * @param bool $on Set alias state. */ function Antialias ($on = true) { painter_enforce_type ($on, "bool"); if (function_exists ("imageantialias")) { imageantialias ($this->img, $on); } } /** * Sets the thickness of the lines used by drawing functions. * @param int $thickness The line thickness. */ function SetThickness ($thickness) { painter_enforce_type ($thickness, "int"); imagesetthickness ($this->img, $thickness); } /** * Draws a line between $pt1 and $pt2. * @param Point $pt1 Start point. * @param Point $pt2 End point. * @param Colour $clr The colour to use. */ function DrawLine ($pt1, $pt2, $clr) { painter_enforce_type ($pt1, "Point"); painter_enforce_type ($pt2, "Point"); painter_enforce_type ($clr, "Colour"); $img = $this->img; $c = imagecolorallocatealpha ($img, $clr->R, $clr->G, $clr->B, $clr->A); imageline ($img, $pt1->X, $pt1->Y, $pt2->X, $pt2->Y, $c); imagecolordeallocate ($img, $c); } /** * Draw a Rect. * @param Rect $rect The Rect to draw. * @param Colour $clr The colour to use. */ function DrawRect ($rect, $clr) { $this->_Rect ($rect, $clr, false); } /** * Fill a Rect. * @param Rect $rect The Rect to fill. * @param Colour $clr The colour to use. */ function FillRect ($rect, $clr) { $this->_Rect ($rect, $clr, true); } /** * Gradient fill a Rect. * @param Rect $rect The Rect to fill. * @param Colour $clr1 The start colour. * @param Colour $clr2 The end colour. * @param bool $vert True for vertical gradient, otherwise false. */ function GradFillRect ($rect, $clr1, $clr2, $vert = false) { painter_enforce_type ($rect, "Rect"); painter_enforce_type ($clr1, "Colour"); painter_enforce_type ($clr2, "Colour"); painter_enforce_type ($vert, "bool"); $lines = $this->_BoxGradLines ($rect, $vert); $this->_GradFill ($lines, $rect->Width, $rect->Height, $clr1, $clr2); } /** * Draw an Ellipse. * @param Ellipse $el The Ellipse to draw. * @param Colour $clr The colour to use. */ function DrawEllipse ($el, $clr) { $this->_Ellipse ($el, $clr, false); } /** * Fill an Ellipse. * @param Rect $el The Ellipse to fill. * @param Colour $clr The colour to use. */ function FillEllipse ($el, $clr) { $this->_Ellipse ($el, $clr, true); } /** * Draw a Polygon. * @param Polygon $poly The Polygon to draw. * @param Colour $clr The colour to use. */ function DrawPolygon ($poly, $clr) { $this->_Polygon ($poly, $clr, false); } /** * Fill a Polygon. * @param Polygon $poly The Polygon to fill. * @param Colour $clr The colour to use. */ function FillPolygon ($poly, $clr) { $this->_Polygon ($poly, $clr, true); } /** * Draw an Arc. * @param Arc $arc The Arc to draw. * @param Colour $clr The colour to use. */ function DrawArc ($arc, $clr) { $this->_Arc ($arc, $clr, false, 0); } /** * Fill an Arc. * @param Arc $arc The Arc to draw. * @param Colour $clr The colour to use. * @param int $style A bitwise OR of the style options or filling arcs. */ function FillArc ($arc, $clr, $style = 0) { $this->_Arc ($arc, $clr, true, $style); } /** * Writes text. * @param Font $font The font to write. * @param Point $pt The Point to draw the text. * @param string $txt The string to write. * @param Colour $clr The Colour to use. * @param int $angle The angle to draw the text at. */ function WriteText ($font, $pt, $txt, $clr, $angle = 0) { painter_enforce_type ($font, "Font"); painter_enforce_type ($pt, "Point"); painter_enforce_type ($txt, "string"); painter_enforce_type ($clr, "Colour"); painter_enforce_type ($angle, "number"); $img = $this->img; $c = imagecolorallocatealpha ($img, $clr->R, $clr->G, $clr->B, $clr->A); $sz = $font->Size; $p = $font->Path; switch ($font->Type) { case "ttf": imagettftext ($img, $sz, $angle, $pt->X, $pt->Y, $c, $p, $txt); break; case "ps": imagepstext ($img, $txt, $font->Handle, $sz, $c, $c, $pt->X, $pt->Y, null, null, $angle, null); break; default: imagestring ($img, $sz, $pt->X, $pt->Y, $txt, $c); break; } imagecolordeallocate ($img, $c); } /** * Calculate the bounding box of some text. * @param Font $font The font to write. * @param string $txt The string to write. * @param int $angle The angle to draw the text at. * @return Rect */ function MeasureText ($font, $txt, $angle = 0) { painter_enforce_type ($font, "Font"); painter_enforce_type ($txt, "string"); painter_enforce_type ($angle, "number"); $img = $this->img; $c = imagecolorallocatealpha ($img, $clr->R, $clr->G, $clr->B, $clr->A); $sz = $font->Size; $p = $font->Path; $ret = null; switch ($font->Type) { case "ttf": $bb = imagettfbbox ($sz, $angle, $p, $txt); $ret = new Rect (0, 0, $bb[2]-$bb[0], $bb[1]-$bb[7]); break; case "ps": $bb =imagepsbbox ($txt, $font->Handle, $sz, null, null, $angle); $ret = new Rect (0, 0, $bb[2] - $bb[0], $bb[3] - $bb[1]); break; default: $ret = new Rect (0, 0, 0, 0); break; } imagecolordeallocate ($img, $c); return $ret; } /** * Destroys the image. */ function Free () { imagedestroy ($this->img); } /** * @access private */ function _Rect ($rect, $clr, $fill) { painter_enforce_type ($rect, "Rect"); painter_enforce_type ($clr, "Colour"); $x = $rect->X; $y = $rect->Y; $w = $rect->Width; $h = $rect->Height - 1; $img = $this->img; $c = imagecolorallocatealpha ($img, $clr->R, $clr->G, $clr->B, $clr->A); if ($fill) { imagefilledrectangle ($img, $x, $y, $x + $w, $y + $h, $c); } else { imagerectangle ($img, $x, $y, $x + $w, $y + $h, $c); } imagecolordeallocate ($img, $c); } /** * @access private */ function _Ellipse ($el, $clr, $fill) { painter_enforce_type ($el, "Ellipse"); painter_enforce_type ($clr, "Colour"); $x = $el->X; $y = $el->Y; $w = $el->Width; $h = $el->Height; $img = $this->img; $c = imagecolorallocatealpha ($img, $clr->R, $clr->G, $clr->B, $clr->A); if ($fill) { imagefilledellipse ($img, $x, $y, $w, $h, $c); } else { imageellipse ($img, $x, $y, $w, $h, $c); } imagecolordeallocate ($img, $c); } /** * @access private */ function _Polygon ($poly, $clr, $fill) { painter_enforce_type ($poly, "Polygon"); painter_enforce_type ($clr, "Colour"); $cnt = count ($poly->Points); $pts = array (); for ($i = 0; $i < $cnt; $i++) { $pts[] = $poly->Points[$i]->X; $pts[] = $poly->Points[$i]->Y; } $img = $this->img; $c = imagecolorallocatealpha ($img, $clr->R, $clr->G, $clr->B, $clr->A); if ($fill) { imagefilledpolygon ($img, $pts, $cnt, $c); } else { imagepolygon ($img, $pts, $cnt, $c); } imagecolordeallocate ($img, $c); } /** * @access private */ function _Arc ($arc, $clr, $fill, $style) { painter_enforce_type ($arc, "Arc"); painter_enforce_type ($clr, "Colour"); $x = $arc->X; $y = $arc->Y; $w = $arc->Width; $h = $arc->Height; $s = $arc->Start; $e = $arc->End; $img = $this->img; $c = imagecolorallocatealpha ($img, $clr->R, $clr->G, $clr->B, $clr->A); if ($fill) { imagefilledarc ($img, $x, $y, $w, $h, $s, $e, $c, $style); } else { imagearc ($img, $x, $y, $w, $h, $s, $e, $c); } imagecolordeallocate ($img, $c); } /** * @access private */ function _BoxGradLines ($r, $vert) { $lines = array (); $w = $r->Width; $h = $r->Height; $len = (!$vert) ? $h : $w; for ($i = 0; $i <= $len; $i++) { if (!$vert) { $lines[] = array ($r->X, $r->Y + $i, $r->X + $w, $r->Y + $i); } else { $lines[] = array ($r->X + $i, $r->Y, $r->X + $i, $r->Y + $h); } } return $lines; } /** * @access private */ function _GradFill ($lines, $w, $h, $clr1, $clr2) { $r1 = $clr1->R; $g1 = $clr1->G; $b1 = $clr1->B; $r2 = $clr2->R; $g2 = $clr2->G; $b2 = $clr2->B; $img = $this->img; $l = count ($lines); for ($i = 0; $i <= $l; $i++) { $oldr = $r; $oldg = $g; $oldb = $b; $r = ($r2 - $r1 != 0) ? intval ($r1 + ($r2 - $r1) * ($i / $l)) : $r1; $g = ($g2 - $g1 != 0) ? intval ($g1 + ($g2 - $g1) * ($i / $l)) : $g1; $b = ($b2 - $b1 != 0) ? intval ($b1 + ($b2 - $b1) * ($i / $l)) : $b1; if ("$oldr,$oldg,$oldb" != "$r,$g,$b") { if ($fill) imagecolordeallocate ($img, $fill); $fill = imagecolorallocate ($img, $r, $g, $b); } $ln = $lines[$i]; $lx1 = $ln[0]; $ly1 = $ln[1]; $lx2 = $ln[2]; $ly2 = $ln[3]; imagefilledrectangle($img, $lx1, $ly1, $lx2, $ly2, $fill); } } } /* Global functions --------------------------------------------------------- */ /** * @access private */ function painter_enforce_type ($obj, $type) { switch ($type) { case "string": $valid = is_string ($obj); break; case "int": $valid = is_int ($obj); break; case "float": $valid = is_float ($obj); break; case "double": $valid = is_double ($obj); break; case "number": $valid = is_numeric($obj); break; case "array": $valid = is_array($obj); break; case "bool": $valid = is_bool($obj); break; default: $valid = ($type == get_class ($obj)); } if (!$valid) { $trace = debug_backtrace (); $func = $trace[1]['function']; $err = "Invalid argument to function '".$func; $err .= "', required type '".$type."'"; painter_error ($err); } } /** * @access private */ function painter_error ($msg, $trace = true) { echo "Painter Error: ".$msg."
"; if ($trace) { var_dump (debug_backtrace ()); } die (); } ?>