diff --git a/external-libs/Artichow/Artichow.cfg.php b/external-libs/Artichow/Artichow.cfg.php new file mode 100644 index 00000000000..4a8790b1b72 --- /dev/null +++ b/external-libs/Artichow/Artichow.cfg.php @@ -0,0 +1,79 @@ + \ No newline at end of file diff --git a/external-libs/Artichow/BarPlot.class.php b/external-libs/Artichow/BarPlot.class.php new file mode 100644 index 00000000000..812c4c548f1 --- /dev/null +++ b/external-libs/Artichow/BarPlot.class.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/external-libs/Artichow/Graph.class.php b/external-libs/Artichow/Graph.class.php new file mode 100644 index 00000000000..e665e0f7fb3 --- /dev/null +++ b/external-libs/Artichow/Graph.class.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/external-libs/Artichow/Image.class.php b/external-libs/Artichow/Image.class.php new file mode 100644 index 00000000000..065db04e0fc --- /dev/null +++ b/external-libs/Artichow/Image.class.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/external-libs/Artichow/Pie.class.php b/external-libs/Artichow/Pie.class.php new file mode 100644 index 00000000000..ec81bed4aff --- /dev/null +++ b/external-libs/Artichow/Pie.class.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/external-libs/Artichow/php4/AntiSpam.class.php b/external-libs/Artichow/php4/AntiSpam.class.php new file mode 100644 index 00000000000..f104ffbb475 --- /dev/null +++ b/external-libs/Artichow/php4/AntiSpam.class.php @@ -0,0 +1,217 @@ +string = (string)$string; + + } + + /** + * Create a random string + * + * @param int $length String length + * @return string String created + */ + function setRand($length) { + + $length = (int)$length; + + $this->string = ''; + + $letters = 'aAbBCDeEFgGhHJKLmMnNpPqQRsStTuVwWXYZz2345679'; + $number = strlen($letters); + + for($i = 0; $i < $length; $i++) { + $this->string .= $letters{mt_rand(0, $number - 1)}; + } + + return $this->string; + + } + + /** + * Set noise on image + * + * @param int $nois Noise intensity (from 0 to 10) + */ + function setNoise($noise) { + if($noise < 0) { + $noise = 0; + } + if($noise > 10) { + $noise = 10; + } + $this->noise = (int)$noise; + } + + /** + * Save string value in session + * You can use check() to verify the value later + * + * @param string $qName A name that identify the anti-spam image + */ + function save($qName) { + $this->session(); + $session = 'artichow_'.(string)$qName; + $_SESSION[$session] = $this->string; + } + + /** + * Verify user entry + * + * @param string $qName A name that identify the anti-spam image + * @param string $value User-defined value + * @param bool $case TRUE for case insensitive check, FALSE for case sensitive check ? (default to TRUE) + * @return bool TRUE if the value is correct, FALSE otherwise + */ + function check($qName, $value, $case = TRUE) { + + $this->session(); + + $session = 'artichow_'.(string)$qName; + + return ( + array_key_exists($session, $_SESSION) === TRUE and + $case ? + (strtolower($_SESSION[$session]) === strtolower((string)$value)) : + ($_SESSION[$session] === (string)$value) + ); + + } + + /** + * Draw image + */ + function draw() { + + $fonts = array( + ARTICHOW_FONT.DIRECTORY_SEPARATOR.'Tuffy.ttf', + ARTICHOW_FONT.DIRECTORY_SEPARATOR.'TuffyBold.ttf', + ARTICHOW_FONT.DIRECTORY_SEPARATOR.'TuffyItalic.ttf', + ARTICHOW_FONT.DIRECTORY_SEPARATOR.'TuffyBoldItalic.ttf' + ); + + $sizes = array(12, 12.5, 13, 13.5, 14, 15, 16, 17, 18, 19); + + $widths = array(); + $heights = array(); + $texts = array(); + + for($i = 0; $i < strlen($this->string); $i++) { + + $fontKey = array_rand($fonts); + $sizeKey = array_rand($sizes); + + $font = new awTTFFont( + $fonts[$fontKey], $sizes[$sizeKey] + ); + + $text = new awText( + $this->string{$i}, + $font, + NULL, + mt_rand(-15, 15) + ); + + $widths[] = $font->getTextWidth($text); + $heights[] = $font->getTextHeight($text); + $texts[] = $text; + + } + + $width = array_sum($widths); + $height = array_max($heights); + + $totalWidth = $width + 10 + count($texts) * 10; + $totalHeight = $height + 20; + + $this->setSize($totalWidth, $totalHeight); + + $this->create(); + + for($i = 0; $i < strlen($this->string); $i++) { + + $this->drawer->string( + $texts[$i], + new awPoint( + 5 + array_sum(array_slice($widths, 0, $i)) + $widths[$i] / 2 + $i * 10, + 10 + ($height - $heights[$i]) / 2 + ) + ); + + } + + $this->drawNoise($totalWidth, $totalHeight); + + $this->send(); + + } + + function drawNoise($width, $height) { + + $points = $this->noise * 30; + $color = new awColor(0, 0, 0); + + for($i = 0; $i < $points; $i++) { + $this->drawer->point( + $color, + new awPoint( + mt_rand(0, $width), + mt_rand(0, $height) + ) + ); + } + + } + + function session() { + + // Start session if needed + if(!session_id()) { + session_start(); + } + + } + +} + +registerClass('AntiSpam'); +?> diff --git a/external-libs/Artichow/php4/BarPlot.class.php b/external-libs/Artichow/php4/BarPlot.class.php new file mode 100644 index 00000000000..38cb51f201d --- /dev/null +++ b/external-libs/Artichow/php4/BarPlot.class.php @@ -0,0 +1,364 @@ +label = new awLabel; + + $this->barPadding = new awSide(0.08, 0.08, 0, 0); + $this->barShadow = new awShadow(SHADOW_RIGHT_TOP); + $this->barBorder = new awBorder; + + $this->setValues($values); + + $this->identifier = (int)$identifier; + $this->number = (int)$number; + $this->depth = (int)$depth; + + $this->move = new awSide; + + // Hide vertical grid + $this->grid->hideVertical(TRUE); + + } + + /** + * Change bars padding + * This method is not compatible with awBarPlot::setBarPadding() + * + * @param float $left Left padding (between 0 and 1) + * @param float $right Right padding (between 0 and 1) + */ + function setBarPadding($left = NULL, $right = NULL) { + $this->barPadding->set($left, $right); + } + + /** + * Change bars size + * This method is not compatible with awBarPlot::setBarPadding() + * + * @param int $width Bars size (between 0 and 1) + */ + function setBarSize($size) { + $padding = (1 - $size) / 2; + $this->barPadding->set($padding, $padding); + } + + /** + * Move bars + * + * @param int $x + * @param int $y + */ + function move($x, $y) { + $this->move->set($x, NULL, $y, NULL); + } + + /** + * Change bars space + * + * @param int $space Space in pixels + */ + function setBarSpace($space) { + $this->barSpace = (int)$space; + } + + /** + * Change line background color + * + * @param $color + */ + function setBarColor($color) { + $this->barBackground = $color; + } + + /** + * Change line background gradient + * + * @param $gradient + */ + function setBarGradient($gradient) { + $this->barBackground = $gradient; + } + + /** + * Get the line thickness + * + * @return int + */ + function getLegendLineThickness() { + } + + /** + * Get the line type + * + * @return int + */ + function getLegendLineStyle() { + } + + /** + * Get the color of line + * + * @return Color + */ + function getLegendLineColor() { + } + + /** + * Get the background color or gradient of an element of the component + * + * @return Color, Gradient + */ + function getLegendBackground() { + return $this->barBackground; + } + + /** + * Get a mark object + * + * @return Mark + */ + function getLegendMark() { + } + + function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) { + + $count = count($this->datay); + $max = $this->getRealYMax(NULL); + $min = $this->getRealYMin(NULL); + + // Find zero for bars + if($this->xAxisZero and $min <= 0 and $max >= 0) { + $zero = 0; + } else if($max < 0) { + $zero = $max; + } else { + $zero = $min; + } + + // Get base position + $zero = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint(0, $zero)); + + // Distance between two values on the graph + $distance = $this->xAxis->getDistance(0, 1); + + // Compute paddings + $leftPadding = $this->barPadding->left * $distance; + $rightPadding = $this->barPadding->right * $distance; + + $padding = $leftPadding + $rightPadding; + $space = $this->barSpace * ($this->number - 1); + + $barSize = ($distance - $padding - $space) / $this->number; + $barPosition = $leftPadding + $barSize * ($this->identifier - 1); + + for($key = 0; $key < $count; $key++) { + + $value = $this->datay[$key]; + + if($value !== NULL) { + + $position = awAxis::toPosition( + $this->xAxis, + $this->yAxis, + new awPoint($key, $value) + ); + + $barStart = $barPosition + ($this->identifier - 1) * $this->barSpace + $position->x; + $barStop = $barStart + $barSize; + + $t1 = min($zero->y, $position->y); + $t2 = max($zero->y, $position->y); + + if(round($t2 - $t1) == 0) { + continue; + } + + $p1 = new awPoint( + round($barStart) + $this->depth + $this->move->left, + round($t1) - $this->depth + $this->move->top + ); + + $p2 = new awPoint( + round($barStop) + $this->depth + $this->move->left, + round($t2) - $this->depth + $this->move->top + ); + + $this->drawBar($drawer, $p1, $p2); + + } + + } + + // Draw labels + foreach($this->datay as $key => $value) { + + if($value !== NULL) { + + $position = awAxis::toPosition( + $this->xAxis, + $this->yAxis, + new awPoint($key, $value) + ); + + $point = new awPoint( + $barPosition + ($this->identifier - 1) * $this->barSpace + $position->x + $barSize / 2 + 1 + $this->depth, + $position->y - $this->depth + ); + + $this->label->draw($drawer, $point, $key); + + } + + } + + } + + function getXAxisNumber() { + return count($this->datay) + 1; + } + // ça bidouille à fond ici ! + function getXMax() { + return array_max($this->datax) + 1; + } + + function getXCenter() { + return TRUE; + } + + function drawBar($drawer, $p1, $p2) { + + // Draw shadow + $this->barShadow->draw( + $drawer, + $p1, + $p2, + SHADOW_OUT + ); + + if(abs($p2->y - $p1->y) > 1) { + + $this->barBorder->rectangle( + $drawer, + $p1, + $p2 + ); + + if($this->barBackground !== NULL) { + + $size = $this->barBorder->visible() ? 1 : 0; + + $b1 = $p1->move($size, $size); + $b2 = $p2->move(-1 * $size, -1 * $size); + + // Draw background + $drawer->filledRectangle( + $this->barBackground, + new awLine($b1, $b2) + ); + + } + + } + } + +} + +registerClass('BarPlot'); +?> diff --git a/external-libs/Artichow/php4/Component.class.php b/external-libs/Artichow/php4/Component.class.php new file mode 100644 index 00000000000..4c7e36b5ac9 --- /dev/null +++ b/external-libs/Artichow/php4/Component.class.php @@ -0,0 +1,415 @@ +components = array(); + } + + /** + * Add a component to the group + * + * @param &$component A component + */ + function add(&$component) { + $this->components[] = $component; + } + +} + +registerClass('ComponentGroup', TRUE); + + class awComponent { + + /** + * Component drawer + * + * @var Drawer + */ + var $drawer; + + /** + * Component width + * + * @var float + */ + var $width = 1.0; + + /** + * Component height + * + * @var float + */ + var $height = 1.0; + + /** + * Position X of the center the graph (from 0 to 1) + * + * @var float + */ + var $x = 0.5; + + /** + * Position Y of the center the graph (from 0 to 1) + * + * @var float + */ + var $y = 0.5; + + /** + * Component absolute width (in pixels) + * + * + * @var int + */ + var $w; + + /** + * Component absolute height (in pixels) + * + * + * @var int + */ + var $h; + + /** + * Left-top corner Y position + * + * @var float + */ + var $top; + + /** + * Left-top corner X position + * + * @var float + */ + var $left; + + /** + * Component background color + * + * @var Color + */ + var $background; + + /** + * Component padding + * + * @var Side + */ + var $padding; + + /** + * Component space + * + * @var Side + */ + var $space; + + /** + * Component title + * + * @var Label + */ + var $title; + + /** + * Adjust automatically the component ? + * + * @var bool + */ + var $auto = TRUE; + + /** + * Legend + * + * @var Legend + */ + var $legend; + + /** + * Build the component + */ + function awComponent() { + + // Component legend + $this->legend = new awLegend(); + + $this->padding = new awSide(25, 25, 25, 25); + $this->space = new awSide(0, 0, 0, 0); + + // Component title + $this->title = new awLabel( + NULL, + new awTuffy(10), + NULL, + 0 + ); + $this->title->setAlign(LABEL_CENTER, LABEL_TOP); + + } + + /** + * Adjust automatically the component ? + * + * @param bool $auto + */ + function auto($auto) { + $this->auto = (bool)$auto; + } + + /** + * Change the size of the component + * + * @param int $width Component width (from 0 to 1) + * @param int $height Component height (from 0 to 1) + */ + function setSize($width, $height) { + + $this->width = (float)$width; + $this->height = (float)$height; + + } + + /** + * Change the absolute size of the component + * + * @param int $w Component width (in pixels) + * @param int $h Component height (in pixels) + */ + function setAbsSize($w, $h) { + + $this->w = (int)$w; + $this->h = (int)$h; + + } + + /** + * Change component background color + * + * @param $color (can be null) + */ + function setBackgroundColor($color) { + if($color === NULL or is_a($color, 'awColor')) { + $this->background = $color; + } + } + + /** + * Change component background gradient + * + * @param $gradient (can be null) + */ + function setBackgroundGradient($gradient) { + if($gradient === NULL or is_a($gradient, 'awGradient')) { + $this->background = $gradient; + } + } + + /** + * Change component background image + * + * @param &$image (can be null) + */ + function setBackgroundImage($image) { + if($image === NULL or is_a($image, 'awImage')) { + $this->background = $image; + } + } + + /** + * Return the component background + * + * @return Color, Gradient + */ + function getBackground() { + return $this->background; + } + + /** + * Change component padding + * + * @param int $left Padding in pixels (NULL to keep old value) + * @param int $right Padding in pixels (NULL to keep old value) + * @param int $top Padding in pixels (NULL to keep old value) + * @param int $bottom Padding in pixels (NULL to keep old value) + */ + function setPadding($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) { + $this->padding->set($left, $right, $top, $bottom); + } + + /** + * Change component space + * + * @param float $left Space in % (NULL to keep old value) + * @param float $right Space in % (NULL to keep old value) + * @param float $bottom Space in % (NULL to keep old value) + * @param float $top Space in % (NULL to keep old value) + */ + function setSpace($left = NULL, $right = NULL, $bottom = NULL, $top = NULL) { + $this->space->set($left, $right, $bottom, $top); + } + + /** + * Change the absolute position of the component on the graph + * + * @var int $x Left-top corner X position + * @var int $y Left-top corner Y position + */ + function setAbsPosition($left, $top) { + + $this->left = (int)$left; + $this->top = (int)$top; + + } + + /** + * Set the center of the component + * + * @param int $x Position on X axis of the center of the component + * @param int $y Position on Y axis of the center of the component + */ + function setCenter($x, $y) { + + $this->x = (float)$x; + $this->y = (float)$y; + + } + + /** + * Get component coords with its padding + * + * @return array Coords of the component + */ + function getPosition() { + + // Get component coords + $x1 = $this->padding->left; + $y1 = $this->padding->top; + $x2 = $this->w - $this->padding->right; + $y2 = $this->h - $this->padding->bottom; + + return array($x1, $y1, $x2, $y2); + + } + + /** + * Init the drawing of the component + */ + function init($drawer) { + + // Set component background + $background = $this->getBackground(); + + if($background !== NULL) { + + $p1 = new awPoint(0, 0); + $p2 = new awPoint($this->w - 1, $this->h - 1); + + if(is_a($background, 'awImage')) { + + $drawer->copyImage( + $background, + $p1, + $p2 + ); + + } else { + + $drawer->filledRectangle( + $background, + new awLine($p1, $p2) + ); + + } + + } + } + + /** + * Finalize the drawing of the component + */ + function finalize($drawer) { + + // Draw component title + $point = new awPoint( + $this->w / 2, + $this->padding->top - 8 + ); + $this->title->draw($drawer, $point); + + // Draw legend + $this->legend->draw($drawer); + + } + + /** + * Draw the grid around your component + * + * @param Drawer A drawer + * @return array Coords for the component + */ + + + /** + * Draw the component on the graph + * Component should be drawed into specified coords + * + * @param Drawer A drawer + * @param int $x1 + * @param int $y1 + * @param int $x2 + * @param int $y2 + * @param bool $aliasing Use anti-aliasing to draw the component ? + */ + + + /** + * Get space width in pixels + * + * @param int $width Component width + * @param int $height Component height + * @return array + */ + function getSpace($width, $height) { + + $left = (int)($width * $this->space->left / 100); + $right = (int)($width * $this->space->right / 100); + $top = (int)($height * $this->space->top / 100); + $bottom = (int)($height * $this->space->bottom / 100); + + return array($left, $right, $top, $bottom); + + } + +} + +registerClass('Component', TRUE); +?> diff --git a/external-libs/Artichow/php4/Graph.class.php b/external-libs/Artichow/php4/Graph.class.php new file mode 100644 index 00000000000..47f5b5f55dc --- /dev/null +++ b/external-libs/Artichow/php4/Graph.class.php @@ -0,0 +1,389 @@ +setSize($width, $height); + + if(ARTICHOW_CACHE) { + + $this->name = $name; + $this->timeout = $timeout; + + // Clean sometimes all the cache + if(mt_rand(0, 5000) === 0) { + awGraph::cleanCache(); + } + + if($this->name !== NULL) { + + $file = ARTICHOW_CACHE_DIRECTORY."/".$this->name."-time"; + + if(is_file($file)) { + + $type = awGraph::cleanGraphCache($file); + + if($type === NULL) { + awGraph::deleteFromCache($this->name); + } else { + header("Content-Type: image/".$type); + readfile(ARTICHOW_CACHE_DIRECTORY."/".$this->name.""); + exit; + } + + } + + } + + } + + $this->title = new awLabel( + NULL, + new awTuffy(16), + NULL, + 0 + ); + $this->title->setAlign(LABEL_CENTER, LABEL_BOTTOM); + + } + + /** + * Delete a graph from the cache + * + * @param string $name Graph name + * @return bool TRUE on success, FALSE on failure + */ + function deleteFromCache($name) { + + if(ARTICHOW_CACHE) { + + if(is_file(ARTICHOW_CACHE_DIRECTORY."/".$name."-time")) { + unlink(ARTICHOW_CACHE_DIRECTORY."/".$name.""); + unlink(ARTICHOW_CACHE_DIRECTORY."/".$name."-time"); + } + + } + + } + + /** + * Delete all graphs from the cache + */ + function deleteAllCache() { + + if(ARTICHOW_CACHE) { + + $dp = opendir(ARTICHOW_CACHE_DIRECTORY); + + while($file = readdir($dp)) { + if($file !== '.' and $file != '..') { + unlink(ARTICHOW_CACHE_DIRECTORY."/".$file); + } + } + + } + + } + + /** + * Clean cache + */ + function cleanCache() { + + if(ARTICHOW_CACHE) { + + $glob = glob(ARTICHOW_CACHE_DIRECTORY."/*-time"); + + foreach($glob as $file) { + + $type = awGraph::cleanGraphCache($file); + + if($type === NULL) { + $name = ereg_replace(".*/(.*)\-time", "\\1", $file); + awGraph::deleteFromCache($name); + } + + } + + } + + } + + /** + * Enable/Disable Graph timing + * + * @param bool $timing + */ + function setTiming($timing) { + $this->timing = (bool)$timing; + } + + /** + * Add a component to the graph + * + * @param &$component + */ + function add(&$component) { + + $this->components[] = $component; + + } + + /** + * Add a label to the component + * + * @param &$label + * @param int $x Position on X axis of the center of the text + * @param int $y Position on Y axis of the center of the text + */ + function addLabel(&$label, $x, $y) { + + $this->labels[] = array( + $label, $x, $y + ); + + } + + /** + * Add a label to the component with aboslute position + * + * @param &$label + * @param $point Text position + */ + function addAbsLabel(&$label, $point) { + + $this->labels[] = array( + $label, $point + ); + + } + + /** + * Build the graph and draw component on it + * Image is sent to the user browser + * + * @param string $file Save the image in the specified file. Let it null to print image to screen. + */ + function draw($file = NULL) { + + if($this->timing) { + $time = microtimeFloat(); + } + + $this->create(); + + foreach($this->components as $component) { + + $this->drawComponent($component); + + } + + $this->drawTitle(); + $this->drawShadow(); + $this->drawLabels(); + + if($this->timing) { + $this->drawTiming(microtimeFloat() - $time); + } + + if(ARTICHOW_CACHE and $this->name !== NULL) { + ob_start(); + } + + $this->send($file); + + if(ARTICHOW_CACHE and $this->name !== NULL) { + + $data = ob_get_contents(); + + if(is_writable(ARTICHOW_CACHE_DIRECTORY) === FALSE) { + trigger_error("Cache directory is not writable"); + } + + $file = ARTICHOW_CACHE_DIRECTORY."/".$this->name.""; + file_put_contents($file, $data); + + $file .= "-time"; + file_put_contents($file, $this->timeout."\n".$this->getFormat()); + + ob_clean(); + + echo $data; + + } + + } + + function drawLabels() { + + $drawer = $this->getDrawer(); + + foreach($this->labels as $array) { + + if(count($array) === 3) { + + // Text in relative position + list($label, $x, $y) = $array; + + $point = new awPoint( + $x * $this->width, + $y * $this->height + ); + + } else { + + // Text in absolute position + list($label, $point) = $array; + + } + + $label->draw($drawer, $point); + + } + + } + + function drawTitle() { + + $drawer = $this->getDrawer(); + + $point = new awPoint( + $this->width / 2, + 10 + ); + + $this->title->draw($drawer, $point); + + } + + function drawTiming($time) { + + $drawer = $this->getDrawer(); + + $label = new awLabel; + $label->set("(".sprintf("%.3f", $time)." s)"); + $label->setAlign(LABEL_LEFT, LABEL_TOP); + $label->border->show(); + $label->setPadding(1, 0, 0, 0); + $label->setBackgroundColor(new awColor(230, 230, 230, 25)); + + $label->draw($drawer, new awPoint(5, $drawer->height - 5)); + + } + + function cleanGraphCache($file) { + + list( + $time, + $type + ) = explode("\n", file_get_contents($file)); + + $time = (int)$time; + + if($time !== 0 and $time < time()) { + return NULL; + } else { + return $type; + } + + + } + +} + +registerClass('Graph'); + +/* + * To preserve PHP 4 compatibility + */ +function microtimeFloat() { + list($usec, $sec) = explode(" ", microtime()); + return (float)$usec + (float)$sec; +} +?> diff --git a/external-libs/Artichow/php4/Image.class.php b/external-libs/Artichow/php4/Image.class.php new file mode 100644 index 00000000000..86b2e93df6f --- /dev/null +++ b/external-libs/Artichow/php4/Image.class.php @@ -0,0 +1,421 @@ + */ + +define("IMAGE_JPEG", 1); +define("IMAGE_PNG", 2); +define("IMAGE_GIF", 3); + +/* */ + +/* + * Check for GD2 + */ +if(function_exists('imagecreatetruecolor') === FALSE) { + trigger_error("You must compile PHP with GD2 support to use Artichow", E_USER_ERROR); +} + +require_once ARTICHOW."/inc/Shadow.class.php"; +require_once ARTICHOW."/inc/Border.class.php"; + +/** + * An image for a graph + * + * @package Artichow + */ +class awImage { + + /** + * Graph width + * + * @var int + */ + var $width; + + /** + * Graph height + * + * @var int + */ + var $height; + + /** + * Use anti-aliasing ? + * + * @var bool + */ + var $antiAliasing = FALSE; + + /** + * Image format + * + * @var int + */ + var $format = IMAGE_PNG; + + /** + * Image background color + * + * @var Color + */ + var $background; + + /** + * GD resource + * + * @var resource + */ + var $resource; + + /** + * Image drawer + * + * @var Drawer + */ + var $drawer; + + /** + * Shadow + * + * @var Shadow + */ + var $shadow; + + /** + * Image border + * + * @var Border + */ + var $border; + + /** + * Use JPEG for image + * + * @var int + */ + + + /** + * Use PNG for image + * + * @var int + */ + + + /** + * Use GIF for image + * + * @var int + */ + + + /** + * Build the image + */ + function awImage() { + + $this->background = new awColor(255, 255, 255); + $this->shadow = new awShadow(SHADOW_RIGHT_BOTTOM); + $this->border = new awBorder; + + } + + /** + * Get drawer of the image + * + * @param int $w Drawer width (from 0 to 1) (default to 1) + * @param int $h Drawer height (from 0 to 1) (default to 1) + * @param float $x Position on X axis of the center of the drawer (default to 0.5) + * @param float $y Position on Y axis of the center of the drawer (default to 0.5) + * @return Drawer + */ + function getDrawer($w = 1, $h = 1, $x = 0.5, $y = 0.5) { + $this->create(); + $this->drawer->setSize($w, $h); + $this->drawer->setPosition($x, $y); + return $this->drawer; + } + + /** + * Change the image size + * + * @var int $width Image width + * @var int $height Image height + */ + function setSize($width, $height) { + + if($width !== NULL) { + $this->width = (int)$width; + } + if($height !== NULL) { + $this->height = (int)$height; + } + + } + + /** + * Change image background color + * + * @param $color + */ + function setBackgroundColor($color) { + $this->background = $color; + } + + /** + * Change image background gradient + * + * @param $gradient + */ + function setBackgroundGradient($gradient) { + $this->background = $gradient; + } + + /** + * Can we use anti-aliasing ? + * + * @var bool $bool + */ + function setAntiAliasing($bool) { + $this->antiAliasing = (bool)$bool; + } + + /** + * Change image format + * + * @var int $format New image format + */ + function setFormat($format) { + if($format === IMAGE_JPEG or $format === IMAGE_PNG or $format === IMAGE_GIF) { + $this->format = $format; + } + } + + /** + * Create a new awimage + */ + function create() { + + if($this->resource === NULL) { + + // Create image + + $this->resource = imagecreatetruecolor($this->width, $this->height); + if(!$this->resource) { + trigger_error("Unable to create a graph", E_USER_ERROR); + } + + imagealphablending($this->resource, TRUE); + + if($this->antiAliasing and function_exists('imageantialias')) { + imageantialias($this->resource, TRUE); + } + + $this->drawer = new awDrawer($this->resource); + $this->drawer->setImageSize($this->width, $this->height); + + // Original color + $this->drawer->filledRectangle( + new awWhite, + new awLine( + new awPoint(0, 0), + new awPoint($this->width, $this->height) + ) + ); + + $shadow = $this->shadow->getSpace(); + + $p1 = new awPoint($shadow->left, $shadow->top); + $p2 = new awPoint($this->width - $shadow->right - 1, $this->height - $shadow->bottom - 1); + + // Draw image background + $this->drawer->filledRectangle($this->background, new awLine($p1, $p2)); + $this->background->free(); + + // Draw image border + $this->border->rectangle($this->drawer, $p1, $p2); + + } + + } + + /** + * Draw a component on the image + * + * @var &$component A component + */ + function drawComponent(&$component) { + + $shadow = $this->shadow->getSpace(); // Image shadow + $border = $this->border->visible() ? 1 : 0; // Image border size + + $drawer = $this->drawer; + $drawer->setImageSize( + $this->width - $shadow->left - $shadow->right - $border * 2, + $this->height - $shadow->top - $shadow->bottom - $border * 2 + ); + + // No absolute size specified + if($component->w === NULL and $component->h === NULL) { + + list($width, $height) = $drawer->setSize($component->width, $component->height); + + // Set component size in pixels + $component->setAbsSize($width, $height); + + } else { + + $drawer->setAbsSize($component->w, $component->h); + + } + + if($component->top !== NULL and $component->left !== NULL) { + $drawer->setAbsPosition( + $border + $shadow->left + $component->left, + $border + $shadow->top + $component->top + ); + } else { + $drawer->setPosition($component->x, $component->y); + } + + $drawer->movePosition($border + $shadow->left, $border + $shadow->top); + + list($x1, $y1, $x2, $y2) = $component->getPosition(); + + $component->init($drawer); + + $component->drawComponent($drawer, $x1, $y1, $x2, $y2, $this->antiAliasing); + $component->drawEnvelope($drawer, $x1, $y1, $x2, $y2); + + $component->finalize($drawer); + + } + + function drawShadow() { + + $drawer = $this->getDrawer(); + + $this->shadow->draw( + $drawer, + new awPoint(0, 0), + new awPoint($this->width, $this->height), + SHADOW_IN + ); + + } + + /** + * Send the image into a file or to the user browser + * + * @var string $file Save image into a file if you provide a file name + */ + function send($file = NULL) { + + // Test if format is available + if((imagetypes() & $this->format) === FALSE) { + trigger_error("Format '".$this->format."' is not available on your system. Check that your PHP has been compiled with the good libraries."); + } + + // Get some infos about this image + + switch($this->format) { + case IMAGE_JPEG : + $function = 'imagejpeg'; + break; + case IMAGE_PNG : + $function = 'imagepng'; + break; + case IMAGE_GIF : + $function = 'imagegif'; + break; + } + + // Create image + + if($file !== NULL) { + + $function($this->resource, $file); + + } else { + + // Send headers to the browser + if(headers_sent() === FALSE) { + header("Content-type: image/".$this->getFormat()); + } + + $function($this->resource); + + } + + } + + function getFormat() { + + switch($this->format) { + case IMAGE_JPEG : + return 'jpeg'; + case IMAGE_PNG : + return 'png'; + case IMAGE_GIF : + return 'gif'; + } + + } + +} + +registerClass('Image'); + + +/** + * Load an image from a file + * + * @package Artichow + */ +class awFileImage extends awImage { + + /** + * Build a new awimage + * + * @param string $file Image file name + */ + function awFileImage($file) { + + $image = @getimagesize($file); + + if($image and in_array($image[2], array(2, 3))) { + + $this->setSize($image[0], $image[1]); + + switch($image[2]) { + + case 2 : + $this->resource = imagecreatefromjpeg($file); + break; + + case 3 : + $this->resource = imagecreatefrompng($file); + break; + + } + + $this->drawer = new awDrawer($this->resource); + $this->drawer->setImageSize($this->width, $this->height); + + } else { + trigger_error("Artichow does not support this image (must be in PNG or JPEG)", E_USER_ERROR); + } + + } + +} + +registerClass('FileImage'); +?> diff --git a/external-libs/Artichow/php4/LinePlot.class.php b/external-libs/Artichow/php4/LinePlot.class.php new file mode 100644 index 00000000000..e24114b9f42 --- /dev/null +++ b/external-libs/Artichow/php4/LinePlot.class.php @@ -0,0 +1,596 @@ + */ + +define("LINEPLOT_LINE", 0); +define("LINEPLOT_MIDDLE", 1); + +/* */ + +/** + * LinePlot + * + * @package Artichow + */ +class awLinePlot extends awPlot { + + /** + * Add marks to your line plot + * + * @var Mark + */ + var $mark; + + /** + * Labels on your line plot + * + * @var Label + */ + var $label; + + /** + * Filled areas + * + * @var bool + */ + var $areas = array(); + + /** + * Is the line hidden + * + * @var bool + */ + var $lineHide = FALSE; + + /** + * Line color + * + * @var Color + */ + var $lineColor; + + /** + * Line mode + * + * @var int + */ + var $lineMode = LINEPLOT_LINE; + + /** + * Line type + * + * @var int + */ + var $lineStyle = LINE_SOLID; + + /** + * Line thickness + * + * @var int + */ + var $lineThickness = 1; + + /** + * Line background + * + * @var Color, Gradient + */ + var $lineBackground; + + /** + * Line mode + * + * @var int + */ + + + /** + * Line in the middle + * + * @var int + */ + + + /** + * Construct a new awLinePlot + * + * @param array $values Some numeric values for Y axis + * @param int $mode + */ + function awLinePlot($values, $mode = LINEPLOT_LINE) { + + parent::awPlot(); + + $this->mark = new awMark; + $this->label = new awLabel; + + $this->lineMode = (int)$mode; + + $this->setValues($values); + + } + + /** + * Hide line + * + * @param bool $hide + */ + function hideLine($hide) { + $this->lineHide = (bool)$hide; + } + + /** + * Add a filled area + * + * @param int $start Begining of the area + * @param int $end End of the area + * @param mixed $background Background color or gradient of the area + */ + function setFilledArea($start, $stop, $background) { + + if($stop <= $start) { + trigger_error("End position can not be greater than begin position in awLinePlot::setFilledArea()", E_USER_ERROR); + } + + $this->areas[] = array((int)$start, (int)$stop, $background); + + } + + /** + * Change line color + * + * @param $color + */ + function setColor($color) { + $this->lineColor = $color; + } + + /** + * Change line style + * + * @param int $style + */ + function setStyle($style) { + $this->lineStyle = (int)$style; + } + + /** + * Change line tickness + * + * @param int $tickness + */ + function setThickness($tickness) { + $this->lineThickness = (int)$tickness; + } + + /** + * Change line background color + * + * @param $color + */ + function setFillColor($color) { + $this->lineBackground = $color; + } + + /** + * Change line background gradient + * + * @param $gradient + */ + function setFillGradient($gradient) { + $this->lineBackground = $gradient; + } + + /** + * Get the line thickness + * + * @return int + */ + function getLegendLineThickness() { + return $this->lineThickness; + } + + /** + * Get the line type + * + * @return int + */ + function getLegendLineStyle() { + return $this->lineStyle; + } + + /** + * Get the color of line + * + * @return Color + */ + function getLegendLineColor() { + return $this->lineColor; + } + + /** + * Get the background color or gradient of an element of the component + * + * @return Color, Gradient + */ + function getLegendBackground() { + return $this->lineBackground; + } + + /** + * Get a mark object + * + * @return Mark + */ + function getLegendMark() { + return $this->mark; + } + + function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) { + + $max = $this->getRealYMax(); + $min = $this->getRealYMin(); + + // Get start and stop values + list($start, $stop) = $this->getLimit(); + + if($this->lineMode === LINEPLOT_MIDDLE) { + $inc = $this->xAxis->getDistance(0, 1) / 2; + } else { + $inc = 0; + } + + // Build the polygon + $polygon = new awPolygon; + + for($key = $start; $key <= $stop; $key++) { + + $value = $this->datay[$key]; + + if($value !== NULL) { + + $p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($key, $value)); + $p = $p->move($inc, 0); + $polygon->set($key, $p); + + } + + } + + // Draw backgrounds + if(is_a($this->lineBackground, 'awColor') or is_a($this->lineBackground, 'awGradient')) { + + $backgroundPolygon = new awPolygon; + + $p = $this->xAxisPoint($start); + $p = $p->move($inc, 0); + $backgroundPolygon->append($p); + + // Add others points + foreach($polygon->all() as $point) { + $backgroundPolygon->append($point); + } + + $p = $this->xAxisPoint($stop); + $p = $p->move($inc, 0); + $backgroundPolygon->append($p); + + // Draw polygon background + $drawer->filledPolygon($this->lineBackground, $backgroundPolygon); + + } + + $this->drawArea($drawer, $polygon); + + // Draw line + $prev = NULL; + + // Line color + if($this->lineHide === FALSE) { + + if($this->lineColor === NULL) { + $this->lineColor = new awColor(0, 0, 0); + } + + foreach($polygon->all() as $point) { + + if($prev !== NULL) { + $drawer->line( + $this->lineColor, + new awLine( + $prev, + $point, + $this->lineStyle, + $this->lineThickness + ) + ); + } + $prev = $point; + + } + + $this->lineColor->free(); + + } + + // Draw marks and labels + foreach($polygon->all() as $key => $point) { + + $this->mark->draw($drawer, $point); + $this->label->draw($drawer, $point, $key); + + } + + } + + function drawArea($drawer, &$polygon) { + + $starts = array(); + foreach($this->areas as $area) { + list($start) = $area; + $starts[$start] = TRUE; + } + + // Draw filled areas + foreach($this->areas as $area) { + + list($start, $stop, $background) = $area; + + $polygonArea = new awPolygon; + + $p = $this->xAxisPoint($start); + $polygonArea->append($p); + + for($i = $start; $i <= $stop; $i++) { + $p = $polygon->get($i); + if($i === $stop and array_key_exists($stop, $starts)) { + $p = $p->move(-1, 0); + } + $polygonArea->append($p); + } + + $p = $this->xAxisPoint($stop); + if(array_key_exists($stop, $starts)) { + $p = $p->move(-1, 0); + } + $polygonArea->append($p); + + // Draw area + $drawer->filledPolygon($background, $polygonArea); + + } + + } + + function getXAxisNumber() { + if($this->lineMode === LINEPLOT_MIDDLE) { + return count($this->datay) + 1; + } else { + return count($this->datay); + } + } + + function xAxisPoint($position) { + $y = $this->xAxisZero ? 0 : $this->getRealYMin(); + return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y)); + } + + function getXCenter() { + return ($this->lineMode === LINEPLOT_MIDDLE); + } + +} + +registerClass('LinePlot'); + + +/** + * Simple LinePlot + * Useful to draw simple horizontal lines + * + * @package Artichow + */ +class awSimpleLinePlot extends awPlot { + + /** + * Line color + * + * @var Color + */ + var $lineColor; + + /** + * Line start + * + * @var int + */ + var $lineStart; + + /** + * Line stop + * + * @var int + */ + var $lineStop; + + /** + * Line value + * + * @var flaot + */ + var $lineValue; + + /** + * Line mode + * + * @var int + */ + var $lineMode = LINEPLOT_LINE; + + /** + * Line type + * + * @var int + */ + var $lineStyle = LINE_SOLID; + + /** + * Line thickness + * + * @var int + */ + var $lineThickness = 1; + + /** + * Line mode + * + * @var int + */ + + + /** + * Line in the middle + * + * @var int + */ + + + /** + * Construct a new awLinePlot + * + * @param float $value A Y value + * @param int $start Line start index + * @param int $stop Line stop index + * @param int $mode Line mode + */ + function awSimpleLinePlot($value, $start, $stop, $mode = LINEPLOT_LINE) { + + parent::awPlot(); + + $this->lineMode = (int)$mode; + + $this->lineStart = (int)$start; + $this->lineStop = (int)$stop; + $this->lineValue = (float)$value; + + $this->lineColor = new awColor(0, 0, 0); + + } + + /** + * Change line color + * + * @param $color + */ + function setColor($color) { + $this->lineColor = $color; + } + + /** + * Change line style + * + * @param int $style + */ + function setStyle($style) { + $this->lineStyle = (int)$style; + } + + /** + * Change line tickness + * + * @param int $tickness + */ + function setThickness($tickness) { + $this->lineThickness = (int)$tickness; + } + + /** + * Get the line thickness + * + * @return int + */ + function getLegendLineThickness() { + return $this->lineThickness; + } + + /** + * Get the line type + * + * @return int + */ + function getLegendLineStyle() { + return $this->lineStyle; + } + + /** + * Get the color of line + * + * @return Color + */ + function getLegendLineColor() { + return $this->lineColor; + } + + function getLegendBackground() { + return NULL; + } + + function getLegendMark() { + return NULL; + } + + function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) { + + if($this->lineMode === LINEPLOT_MIDDLE) { + $inc = $this->xAxis->getDistance(0, 1) / 2; + } else { + $inc = 0; + } + + $p1 = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($this->lineStart, $this->lineValue)); + $p2 = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($this->lineStop, $this->lineValue)); + + $drawer->line( + $this->lineColor, + new awLine( + $p1->move($inc, 0), + $p2->move($inc, 0), + $this->lineStyle, + $this->lineThickness + ) + ); + + $this->lineColor->free(); + + } + + function getXAxisNumber() { + if($this->lineMode === LINEPLOT_MIDDLE) { + return count($this->datay) + 1; + } else { + return count($this->datay); + } + } + + function xAxisPoint($position) { + $y = $this->xAxisZero ? 0 : $this->getRealYMin(); + return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y)); + } + + function getXCenter() { + return ($this->lineMode === LINEPLOT_MIDDLE); + } + +} + +registerClass('SimpleLinePlot'); +?> diff --git a/external-libs/Artichow/php4/MathPlot.class.php b/external-libs/Artichow/php4/MathPlot.class.php new file mode 100644 index 00000000000..86f8e2b3fa8 --- /dev/null +++ b/external-libs/Artichow/php4/MathPlot.class.php @@ -0,0 +1,439 @@ +f = (string)$f; + $this->fromX = is_null($fromX) ? NULL : (float)$fromX; + $this->toX = is_null($toX) ? NULL : (float)$toX; + + $this->line = new awLine; + $this->mark = new awMark; + $this->color = new awBlack; + + } + + /** + * Change line color + * + * @param $color A new awcolor + */ + function setColor($color) { + $this->color = $color; + } + + /** + * Get line color + * + * @return Color + */ + function getColor() { + return $this->color; + } + + /** + * Get the background color or gradient of an element of the component + * + * @return Color, Gradient + */ + function getLegendBackground() { + } + + /** + * Get the line thickness + * + * @return NULL + */ + function getLegendLineThickness() { + return $this->line->getThickness(); + } + + /** + * Get the line type + * + * @return NULL + */ + function getLegendLineStyle() { + return $this->line->getStyle(); + } + + /** + * Get the color of line + * + * @return NULL + */ + function getLegendLineColor() { + return $this->color; + } + + /** + * Get a mark object + * + * @return NULL + */ + function getLegendMark() { + return $this->mark; + } + +} + +registerClass('MathFunction'); + +/** + * For mathematics functions + * + * @package Artichow + */ +class awMathPlot extends awComponent { + + /** + * Functions + * + * @var array + */ + var $functions = array(); + + /** + * Grid properties + * + * @var Grid + */ + var $grid; + + /** + * X axis + * + * @var Axis + */ + var $xAxis; + + /** + * Y axis + * + * @var Axis + */ + var $yAxis; + + /** + * Extremum + * + * @var Side + */ + var $extremum = NULL; + + /** + * Interval + * + * @var float + */ + var $interval = 1; + + /** + * Build the plot + * + * @param int $xMin Minimum X value + * @param int $xMax Maximum X value + * @param int $yMax Maximum Y value + * @param int $yMin Minimum Y value + */ + function awMathPlot($xMin, $xMax, $yMax, $yMin) { + + parent::awComponent(); + + $this->setPadding(8, 8, 8, 8); + + $this->grid = new awGrid; + + // Hide grid by default + $this->grid->hide(TRUE); + + // Set extremum + $this->extremum = new awSide($xMin, $xMax, $yMax, $yMin); + + // Create axis + $this->xAxis = new awAxis; + $this->xAxis->setTickStyle(TICK_IN); + $this->xAxis->label->hideValue(0); + $this->initAxis($this->xAxis); + + $this->yAxis = new awAxis; + $this->yAxis->setTickStyle(TICK_IN); + $this->yAxis->label->hideValue(0); + $this->initAxis($this->yAxis); + + } + + function initAxis(&$axis) { + + $axis->setLabelPrecision(1); + $axis->addTick('major', new awTick(0, 5)); + $axis->addTick('minor', new awTick(0, 3)); + $axis->addTick('micro', new awTick(0, 1)); + $axis->setNumberByTick('minor', 'major', 1); + $axis->setNumberByTick('micro', 'minor', 4); + $axis->label->setFont(new awTuffy(7)); + + } + + /** + * Interval to calculate values + * + * @param float $interval + */ + function setInterval($interval) { + $this->interval = (float)$interval; + } + + /** + * Add a formula f(x) + * + * @param &$function + * @param string $name Name for the legend (can be NULL if you don't want to set a legend) + * @param int $type Type for the legend + */ + function add(&$function, $name = NULL, $type = LEGEND_LINE) { + + $this->functions[] = $function; + + if($name !== NULL) { + $this->legend->add($function, $name, $type); + } + + } + + function init($drawer) { + + list($x1, $y1, $x2, $y2) = $this->getPosition(); + + $this->xAxis->line->setX($x1, $x2); + $this->xAxis->label->setAlign(NULL, LABEL_BOTTOM); + $this->xAxis->label->move(0, 3); + $this->xAxis->setRange($this->extremum->left, $this->extremum->right); + + $this->yAxis->line->setY($y2, $y1); + $this->yAxis->label->setAlign(LABEL_RIGHT); + $this->yAxis->label->move(-6, 0); + $this->yAxis->reverseTickStyle(); + $this->yAxis->setRange($this->extremum->bottom, $this->extremum->top); + + + $this->xAxis->setYCenter($this->yAxis, 0); + $this->yAxis->setXCenter($this->xAxis, 0); + + if($this->yAxis->getLabelNumber() === NULL) { + $number = $this->extremum->top - $this->extremum->bottom + 1; + $this->yAxis->setLabelNumber($number); + } + + if($this->xAxis->getLabelNumber() === NULL) { + $number = $this->extremum->right - $this->extremum->left + 1; + $this->xAxis->setLabelNumber($number); + } + + // Set ticks + + $this->xAxis->ticks['major']->setNumber($this->xAxis->getLabelNumber()); + $this->yAxis->ticks['major']->setNumber($this->yAxis->getLabelNumber()); + + + // Set axis labels + $labels = array(); + for($i = 0, $count = $this->xAxis->getLabelNumber(); $i < $count; $i++) { + $labels[] = $i; + } + $this->xAxis->label->set($labels); + + $labels = array(); + for($i = 0, $count = $this->yAxis->getLabelNumber(); $i < $count; $i++) { + $labels[] = $i; + } + $this->yAxis->label->set($labels); + + parent::init($drawer); + + // Create the grid + $this->createGrid(); + + // Draw the grid + $this->grid->draw($drawer, $x1, $y1, $x2, $y2); + + } + + function drawEnvelope($drawer) { + + // Draw axis + $this->xAxis->draw($drawer); + $this->yAxis->draw($drawer); + + } + + function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) { + + foreach($this->functions as $function) { + + $f = $function->f; + $fromX = is_null($function->fromX) ? $this->extremum->left : $function->fromX; + $toX = is_null($function->toX) ? $this->extremum->right : $function->toX; + + $old = NULL; + + for($i = $fromX; $i <= $toX; $i += $this->interval) { + + $p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($i, $f($i))); + + if($p->y >= $y1 and $p->y <= $y2) { + $function->mark->draw($drawer, $p); + } + + if($old !== NULL) { + + $line = $function->line; + $line->setLocation($old, $p); + + if( + ($line->p1->y >= $y1 and $line->p1->y <= $y2) or + ($line->p2->y >= $y1 and $line->p2->y <= $y2) + ) { + $drawer->line( + $function->getColor(), + $line + ); + } + + } + + $old = $p; + + } + + // Draw last point if needed + if($old !== NULL and $i - $this->interval != $toX) { + + $p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($toX, $f($toX))); + + if($p->y >= $y1 and $p->y <= $y2) { + $function->mark->draw($drawer, $p); + } + + + $line = $function->line; + $line->setLocation($old, $p); + + if( + ($line->p1->y >= $y1 and $line->p1->y <= $y2) or + ($line->p2->y >= $y1 and $line->p2->y <= $y2) + ) { + $drawer->line( + $function->getColor(), + $line + ); + } + + } + + } + + } + + function createGrid() { + + // Horizontal lines of the grid + + $major = $this->yAxis->tick('major'); + $interval = $major->getInterval(); + $number = $this->yAxis->getLabelNumber() - 1; + + $h = array(); + if($number > 0) { + for($i = 0; $i <= $number; $i++) { + $h[] = $i / $number; + } + } + + // Vertical lines + + $major = $this->xAxis->tick('major'); + $interval = $major->getInterval(); + $number = $this->xAxis->getLabelNumber() - 1; + + $w = array(); + if($number > 0) { + for($i = 0; $i <= $number; $i++) { + if($i%$interval === 0) { + $w[] = $i / $number; + } + } + } + + $this->grid->setGrid($w, $h); + + } + +} + +registerClass('MathPlot'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/Pattern.class.php b/external-libs/Artichow/php4/Pattern.class.php new file mode 100644 index 00000000000..ff0f300e2e1 --- /dev/null +++ b/external-libs/Artichow/php4/Pattern.class.php @@ -0,0 +1,97 @@ +args[$name] = $value; + } + } + + /** + * Get an argument + * + * @param string $name + * @param mixed $default Default value if the argument does not exist (default to NULL) + * @return mixed Argument value + */ + function getArg($name, $default = NULL) { + if(array_key_exists($name, $this->args)) { + return $this->args[$name]; + } else { + return $default; + } + } + + /** + * Change several arguments + * + * @param array $args New arguments + */ + function setArgs($args) { + if(is_array($args)) { + foreach($args as $name => $value) { + $this->setArg($name, $value); + } + } + } + +} + +registerClass('Pattern', TRUE); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/Pie.class.php b/external-libs/Artichow/php4/Pie.class.php new file mode 100644 index 00000000000..88a5630f2b8 --- /dev/null +++ b/external-libs/Artichow/php4/Pie.class.php @@ -0,0 +1,680 @@ + */ + +define("PIE_DARK", 1); +define("PIE_COLORED", 2); +define("PIE_AQUA", 3); +define("PIE_EARTH", 4); + +/* */ + +/** + * Pie + * + * @package Artichow + */ +class awPie extends awComponent { + + /** + * A dark theme for pies + * + * + * @var int + */ + + + /** + * A colored theme for pies + * + * @var int + */ + + + /** + * A water theme for pies + * + * @var int + */ + + + /** + * A earth theme for pies + * + * @var int + */ + + + /** + * Pie values + * + * @var array + */ + var $values; + + /** + * Pie colors + * + * @var array + */ + var $colors; + + /** + * Pie legend + * + * @var array + */ + var $legendValues = array(); + + /** + * Intensity of the 3D effect + * + * @var int + */ + var $size; + + /** + * Border color + * + * @var Color + */ + var $border; + + /** + * Pie explode + * + * @var array + */ + var $explode = array(); + + /** + * Initial angle + * + * @var int + */ + var $angle = 0; + + /** + * Labels precision + * + * @var int + */ + var $precision; + + /** + * Labels number + * + * @var int + */ + var $number; + + /** + * Labels minimum + * + * @var int + */ + var $minimum; + + /** + * Labels position + * + * @var int + */ + var $position = 15; + + /** + * Labels of your pie + * + * @var Label + */ + var $label; + + /** + * Build the plot + * + * @param array $values Pie values + */ + function awPie($values, $colors = PIE_COLORED) { + + $this->setValues($values); + + if(is_array($colors)) { + $this->colors = $colors; + } else { + + switch($colors) { + + case PIE_AQUA : + $this->colors = array( + new awColor(131, 220, 215), + new awColor(131, 190, 215), + new awColor(131, 160, 215), + new awColor(160, 140, 215), + new awColor(190, 131, 215), + new awColor(220, 131, 215) + ); + break; + + case PIE_EARTH : + $this->colors = array( + new awColor(97, 179, 110), + new awColor(130, 179, 97), + new awColor(168, 179, 97), + new awColor(179, 147, 97), + new awColor(179, 108, 97), + new awColor(99, 107, 189), + new awColor(99, 165, 189) + ); + break; + + case PIE_DARK : + $this->colors = array( + new awColor(140, 100, 170), + new awColor(130, 170, 100), + new awColor(160, 160, 120), + new awColor(150, 110, 140), + new awColor(130, 150, 160), + new awColor(90, 170, 140) + ); + break; + + default : + $this->colors = array( + new awColor(187, 213, 151), + new awColor(223, 177, 151), + new awColor(111, 186, 132), + new awColor(197, 160, 230), + new awColor(165, 169, 63), + new awColor(218, 177, 89), + new awColor(116, 205, 121), + new awColor(200, 201, 78), + new awColor(127, 205, 177), + new awColor(205, 160, 160), + new awColor(190, 190, 190) + ); + break; + + } + + } + + parent::awComponent(); + + $this->label = new awLabel; + $this->label->setCallbackFunction('callbackPerCent'); + + } + + /** + * Change legend values + * + * @param array $legend An array of values for each part of the pie + */ + function setLegend($legend) { + + $this->legendValues = (array)$legend; + + } + + /** + * Set a border all around the pie + * + * @param $color A color for the border + */ + function setBorder($color) { + $this->border = $color; + } + + /** + * Change 3D effect intensity + * + * @param int $size Effect size + */ + function set3D($size) { + $this->size = (int)$size; + } + + /** + * Change initial angle + * + * @param int $angle New angle in degrees + */ + function setStartAngle($angle) { + $this->angle = (int)$angle; + } + + /** + * Change label precision + * + * @param int $precision New precision + */ + function setLabelPrecision($precision) { + $this->precision = (int)$precision; + } + + /** + * Change label position + * + * @param int $position New position in pixels + */ + function setLabelPosition($position) { + $this->position = (int)$position; + } + + /** + * Change label number + * + * @param int $number New number + */ + function setLabelNumber($number) { + $this->number = is_null($number) ? $number : (int)$number; + } + + /** + * Change label minimum + * + * @param int $minimum New minimum + */ + function setLabelMinimum($minimum) { + $this->minimum = is_null($minimum) ? $minimum : (int)$minimum; + } + + /** + * Change Pie explode + * + * @param array $explode + */ + function explode($explode) { + $this->explode = (array)$explode; + } + + function drawEnvelope($drawer) { + + } + + function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) { + + $count = count($this->values); + $sum = array_sum($this->values); + + $width = $x2 - $x1; + $height = $y2 - $y1; + + if($aliasing) { + $x = $width / 2; + $y = $height / 2; + } else { + $x = $width / 2 + $x1; + $y = $height / 2 + $y1; + } + + $position = $this->angle; + $values = array(); + $parts = array(); + $angles = 0; + + if($aliasing) { + $side = new awSide(0, 0, 0, 0); + } + + foreach($this->values as $key => $value) { + + $angle = ($value / $sum * 360); + + if($key === $count - 1) { + $angle = 360 - $angles; + } + + $angles += $angle; + + if(array_key_exists($key, $this->explode)) { + $middle = 360 - ($position + $angle / 2); + $posX = $this->explode[$key] * cos($middle * M_PI / 180); + $posY = $this->explode[$key] * sin($middle * M_PI / 180) * -1; + + if($aliasing) { + $explode = new awPoint( + $posX * 2, + $posY * 2 + ); + $side->set( + max($side->left, $posX * -2), + max($side->right, $posX * 2), + max($side->top, $posY * -2), + max($side->bottom, $posY * 2) + ); + } else { + $explode = new awPoint( + $posX, + $posY + ); + } + + } else { + $explode = new awPoint(0, 0); + } + + $values[$key] = array( + $position, ($position + $angle), $explode + ); + + $color = $this->colors[$key % count($this->colors)]; + $parts[$key] = new awPiePart($color); + + // Add part to the legend + $legend = array_key_exists($key, $this->legendValues) ? $this->legendValues[$key] : $key; + $this->legend->add($parts[$key], $legend, LEGEND_BACKGROUND); + + $position += $angle; + + } + + if($aliasing) { + + $mainDrawer = $drawer; + + $x *= 2; + $y *= 2; + $width *= 2; + $height *= 2; + $this->size *= 2; + + $image = new awImage; + $image->border->hide(); + $image->setSize( + $width + $side->left + $side->right, + $height + $side->top + $side->bottom + $this->size + 1 /* bugs.php.net ! */ + ); + + $drawer = $image->getDrawer( + $width / $image->width, + $height / $image->height, + ($width / 2 + $side->left) / $image->width, + ($height / 2 + $side->top) / $image->height + ); + + } + + // Draw 3D effect + for($i = $this->size; $i > 0; $i--) { + + foreach($values as $key => $value) { + + $color = $this->colors[$key % count($this->colors)]; + $color->brightness(-50); + + list($from, $to, $explode) = $value; + + $drawer->filledArc($color, $explode->move($x, $y + $i), $width, $height, $from, $to); + + $color->free(); + unset($color); + + if(is_a($this->border, 'awColor')) { + + $point = $explode->move($x, $y); + + if($i === $this->size) { + + $drawer->arc($this->border, $point->move(0, $this->size), $width, $height, $from, $to); + + } + + } + + } + + } + + foreach($values as $key => $value) { + + $color = $this->colors[$key % count($this->colors)]; + + list($from, $to, $explode) = $value; + + $drawer->filledArc($color, $explode->move($x, $y), $width, $height, $from, $to); + + if(is_a($this->border, 'awColor')) { + + $point = $explode->move($x, $y); + $drawer->arc($this->border, $point, $width, $height, $from, $to); + } + + } + + if($aliasing) { + + $x = $x / 2 + $x1; + $y = $y / 2 + $y1; + $width /= 2; + $height /= 2; + $this->size /= 2; + + foreach($values as $key => $value) { + $old = $values[$key][2]; + $values[$key][2] = new awPoint( + $old->x / 2, $old->y / 2 + ); + } + + $mainDrawer->copyResizeImage( + $image, + new awPoint($x1 - $side->left / 2, $y1 - $side->top / 2), + new awPoint($x1 - $side->left / 2 + $image->width / 2, $y1 - $side->top / 2 + $image->height/ 2), + new awPoint(0, 0), + new awPoint($image->width, $image->height), + TRUE + ); + + $drawer = $mainDrawer; + + } + + // Get labels values + $pc = array(); + foreach($this->values as $key => $value) { + $pc[$key] = round($value / $sum * 100, $this->precision); + } + if($this->label->count() === 0) { // Check that there is no user defined values + $this->label->set($pc); + } + + $position = 0; + + foreach($pc as $key => $value) { + + // Limit number of labels to display + if($position === $this->number) { + break; + } + + if(is_null($this->minimum) === FALSE and $value < $this->minimum) { + continue; + } + + $position++; + + list($from, $to, $explode) = $values[$key]; + + $angle = $from + ($to - $from) / 2; + $angleRad = (360 - $angle) * M_PI / 180; + + $point = new awPoint( + $x + $explode->x + cos($angleRad) * ($width / 2 + $this->position), + $y + $explode->y - sin($angleRad) * ($height / 2 + $this->position) + ); + + $angle %= 360; + + // We don't display labels on the 3D effect + if($angle > 0 and $angle < 180) { + $point = $point->move(0, -1 * sin($angleRad) * $this->size); + } + + if($angle >= 45 and $angle < 135) { + $this->label->setAlign(LABEL_CENTER, LABEL_BOTTOM); + } else if($angle >= 135 and $angle < 225) { + $this->label->setAlign(LABEL_RIGHT, LABEL_MIDDLE); + } else if($angle >= 225 and $angle < 315) { + $this->label->setAlign(LABEL_CENTER, LABEL_TOP); + } else { + $this->label->setAlign(LABEL_LEFT, LABEL_MIDDLE); + } + + $this->label->draw( + $drawer, + $point, + $key + ); + + } + + } + + /** + * Return margins around the component + * + * @return array Left, right, top and bottom margins + */ + function getMargin() { + + // Get axis informations + + $leftAxis = $this->padding->left; + $rightAxis = $this->padding->right; + $topAxis = $this->padding->top; + $bottomAxis = $this->padding->bottom; + + return array($leftAxis, $rightAxis, $topAxis, $bottomAxis); + + } + + + /** + * Change values of Y axis + * This method ignores not numeric values + * + * @param array $values + */ + function setValues($values) { + + $this->checkArray($values); + $this->values = $values; + + } + + + /** + * Return values of Y axis + * + * @return array + */ + function getValues() { + return $this->values; + } + + function checkArray(&$array) { + + if(is_array($array) === FALSE) { + trigger_error("You tried to set values that are not an array"); + } + + foreach($array as $key => $value) { + if(is_numeric($value) === FALSE) { + unset($array[$key]); + } + } + + if(count($array) < 1) { + trigger_error("Your graph must have at least 1 value"); + } + + } + +} + +registerClass('Pie'); + +/** + * Pie + * + * @package Artichow + */ +class awPiePart { + + /** + * Pie part color + * + * @var Color + */ + var $color; + + /** + * Build a new awPiePart + * + * @param $color Pie part color + */ + function awPiePart($color) { + + $this->color = $color; + + } + + /** + * Get the background color or gradient of an element of the component + * + * @return Color, Gradient + */ + function getLegendBackground() { + return $this->color; + } + + /** + * Get the line thickness + * + * @return NULL + */ + function getLegendLineThickness() { + } + + /** + * Get the line type + * + * @return NULL + */ + function getLegendLineStyle() { + } + + /** + * Get the color of line + * + * @return NULL + */ + function getLegendLineColor() { + } + + /** + * Get a mark object + * + * @return NULL + */ + function getLegendMark() { + } + +} + +registerClass('PiePart'); + +function callbackPerCent($value) { + return $value.'%'; +} +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/Plot.class.php b/external-libs/Artichow/php4/Plot.class.php new file mode 100644 index 00000000000..8eea0d56ac3 --- /dev/null +++ b/external-libs/Artichow/php4/Plot.class.php @@ -0,0 +1,1464 @@ + */ + +define("PLOT_LEFT", 'left'); +define("PLOT_RIGHT", 'right'); +define("PLOT_TOP", 'top'); +define("PLOT_BOTTOM", 'bottom'); +define("PLOT_BOTH", 'both'); + +/* */ + +/** + * Graph using X and Y axis + * + * @package Artichow + */ + class awPlot extends awComponent { + + /** + * Values for Y axis + * + * @var array + */ + var $datay; + + /** + * Values for X axis + * + * @var array + */ + var $datax; + + /** + * Grid properties + * + * @var Grid + */ + var $grid; + + /** + * X axis + * + * @var Axis + */ + var $xAxis; + + /** + * Y axis + * + * @var Axis + */ + var $yAxis; + + /** + * Position of X axis + * + * @var int + */ + var $xAxisPosition = PLOT_BOTTOM; + + /** + * Set X axis on zero ? + * + * @var bool + */ + var $xAxisZero = TRUE; + + /** + * Set Y axis on zero ? + * + * @var bool + */ + var $yAxisZero = FALSE; + + /** + * Position of Y axis + * + * @var int + */ + var $yAxisPosition = PLOT_LEFT; + + /** + * Change min value for Y axis + * + * @var mixed + */ + var $yMin = NULL; + + /** + * Change max value for Y axis + * + * @var mixed + */ + var $yMax = NULL; + + /** + * Change min value for X axis + * + * @var mixed + */ + var $xMin = NULL; + + /** + * Change max value for X axis + * + * @var mixed + */ + var $xMax = NULL; + + /** + * Left axis + * + * @var int + */ + + + /** + * RIGHT axis + * + * @var int + */ + + + /** + * Top axis + * + * @var int + */ + + + /** + * Bottom axis + * + * @var int + */ + + + /** + * Both left/right or top/bottom axis + * + * @var int + */ + + + /** + * Build the plot + * + */ + function awPlot() { + + parent::awComponent(); + + $this->grid = new awGrid; + $this->grid->setBackgroundColor(new awWhite); + + $this->padding->add(20, 0, 0, 20); + + $this->xAxis = new awAxis; + $this->xAxis->addTick('major', new awTick(0, 5)); + $this->xAxis->addTick('minor', new awTick(0, 3)); + $this->xAxis->setTickStyle(TICK_OUT); + $this->xAxis->label->setFont(new awTuffy(7)); + + $this->yAxis = new awAxis; + $this->yAxis->auto(TRUE); + $this->yAxis->addTick('major', new awTick(0, 5)); + $this->yAxis->addTick('minor', new awTick(0, 3)); + $this->yAxis->setTickStyle(TICK_OUT); + $this->yAxis->setNumberByTick('minor', 'major', 3); + $this->yAxis->label->setFont(new awTuffy(7)); + $this->yAxis->title->setAngle(90); + + } + + /** + * Get plot values + * + * @return array + */ + function getValues() { + return $this->datay; + } + + /** + * Reduce number of values in the plot + * + * @param int $number Reduce number of values to $number + */ + function reduce($number) { + + $count = count($this->datay); + $ratio = ceil($count / $number); + + if($ratio > 1) { + + $tmpy = $this->datay; + $datay = array(); + + $datax = array(); + $cbLabel = $this->xAxis->label->getCallbackFunction(); + + for($i = 0; $i < $count; $i += $ratio) { + + $slice = array_slice($tmpy, $i, $ratio); + $datay[] = array_sum($slice) / count($slice); + + // Reduce data on X axis if needed + if($cbLabel !== NULL) { + $datax[] = $cbLabel($i + round($ratio / 2)); + } + + } + + $this->setValues($datay); + + if($cbLabel !== NULL) { + $this->xAxis->setLabelText($datax); + } + + + } + + } + + /** + * Count values in the plot + * + * @return int + */ + function getXAxisNumber() { + list($min, $max) = $this->xAxis->getRange(); + return ($max - $min + 1); + } + + /** + * Change X axis + * + * @param int $axis + */ + function setXAxis($axis) { + $this->xAxisPosition = $axis; + } + + /** + * Get X axis + * + * @return int + */ + function getXAxis() { + return $this->xAxisPosition; + } + + /** + * Set X axis on zero + * + * @param bool $zero + */ + function setXAxisZero($zero) { + $this->xAxisZero = (bool)$zero; + } + + /** + * Set Y axis on zero + * + * @param bool $zero + */ + function setYAxisZero($zero) { + $this->yAxisZero = (bool)$zero; + } + + /** + * Change Y axis + * + * @param int $axis + */ + function setYAxis($axis) { + $this->yAxisPosition = $axis; + } + + /** + * Get Y axis + * + * @return int + */ + function getYAxis() { + return $this->yAxisPosition; + } + + /** + * Change min value for Y axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setYMin($value) { + $this->yMin = $value; + $this->yAxis->auto(FALSE); + $this->updateAxis(); + } + + /** + * Change max value for Y axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setYMax($value) { + $this->yMax = $value; + $this->yAxis->auto(FALSE); + $this->updateAxis(); + } + + /** + * Change min value for X axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setXMin($value) { + $this->xMin = $value; + $this->updateAxis(); + } + + /** + * Change max value for X axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setXMax($value) { + $this->xMax = $value; + $this->updateAxis(); + } + + /** + * Get min value for Y axis + * + * @return float $value + */ + function getYMin() { + if($this->auto) { + if(is_null($this->yMin)) { + $min = array_min($this->datay); + if($min > 0) { + return 0; + } + } + } + return is_null($this->yMin) ? array_min($this->datay) : (float)$this->yMin; + } + + /** + * Get max value for Y axis + * + * @return float $value + */ + function getYMax() { + if($this->auto) { + if(is_null($this->yMax)) { + $max = array_max($this->datay); + if($max < 0) { + return 0; + } + } + } + return is_null($this->yMax) ? array_max($this->datay) : (float)$this->yMax; + } + + /** + * Get min value for X axis + * + * @return float $value + */ + function getXMin() { + return floor(is_null($this->xMin) ? array_min($this->datax) : $this->xMin); + } + + /** + * Get max value for X axis + * + * @return float $value + */ + function getXMax() { + return (ceil(is_null($this->xMax) ? array_max($this->datax) : (float)$this->xMax)) + ($this->getXCenter() ? 1 : 0); + } + + /** + * Get min value with spaces for Y axis + * + * @return float $value + */ + function getRealYMin() { + $min = $this->getYMin(); + if($this->space->bottom !== NULL) { + $interval = ($this->getYMax() - $min) * $this->space->bottom / 100; + return $min - $interval; + } else { + return is_null($this->yMin) ? $min : (float)$this->yMin; + } + } + + /** + * Get max value with spaces for Y axis + * + * @return float $value + */ + function getRealYMax() { + $max = $this->getYMax(); + if($this->space->top !== NULL) { + $interval = ($max - $this->getYMin()) * $this->space->top / 100; + return $max + $interval; + } else { + return is_null($this->yMax) ? $max : (float)$this->yMax; + } + } + + function init($drawer) { + + list($x1, $y1, $x2, $y2) = $this->getPosition(); + + // Get space informations + list($leftSpace, $rightSpace, $topSpace, $bottomSpace) = $this->getSpace($x2 - $x1, $y2 - $y1); + + $this->xAxis->setPadding($leftSpace, $rightSpace); + + if($this->space->bottom > 0 or $this->space->top > 0) { + + list($min, $max) = $this->yAxis->getRange(); + $interval = $max - $min; + + $this->yAxis->setRange( + $min - $interval * $this->space->bottom / 100, + $max + $interval * $this->space->top / 100 + ); + + } + + // Auto-scaling mode + $this->yAxis->autoScale(); + + // Number of labels is not specified + if($this->yAxis->getLabelNumber() === NULL) { + $number = round(($y2 - $y1) / 75) + 2; + $this->yAxis->setLabelNumber($number); + } + + $this->xAxis->line->setX($x1, $x2); + $this->yAxis->line->setY($y2, $y1); + + // Set ticks + + $this->xAxis->ticks['major']->setNumber($this->getXAxisNumber()); + $this->yAxis->ticks['major']->setNumber($this->yAxis->getLabelNumber()); + + + // Center X axis on zero + if($this->xAxisZero) { + $this->xAxis->setYCenter($this->yAxis, 0); + } + + // Center Y axis on zero + if($this->yAxisZero) { + $this->yAxis->setXCenter($this->xAxis, 0); + } + + // Set axis labels + $labels = array(); + for($i = 0, $count = $this->getXAxisNumber(); $i < $count; $i++) { + $labels[] = $i; + } + $this->xAxis->label->set($labels); + + parent::init($drawer); + + list($x1, $y1, $x2, $y2) = $this->getPosition(); + + list($leftSpace, $rightSpace) = $this->getSpace($x2 - $x1, $y2 - $y1); + + // Create the grid + $this->createGrid(); + + // Draw the grid + $this->grid->setSpace($leftSpace, $rightSpace, 0, 0); + $this->grid->draw($drawer, $x1, $y1, $x2, $y2); + + } + + function drawEnvelope($drawer) { + + list($x1, $y1, $x2, $y2) = $this->getPosition(); + + if($this->getXCenter()) { + $size = $this->xAxis->getDistance(0, 1); + $this->xAxis->label->move($size / 2, 0); + $this->xAxis->label->hideLast(TRUE); + } + + // Draw top axis + if($this->xAxisPosition === PLOT_TOP or $this->xAxisPosition === PLOT_BOTH) { + $top = $this->xAxis; + if($this->xAxisZero === FALSE) { + $top->line->setY($y1, $y1); + } + $top->label->setAlign(NULL, LABEL_TOP); + $top->label->move(0, -3); + $top->title->move(0, -25); + $top->draw($drawer); + } + + // Draw bottom axis + if($this->xAxisPosition === PLOT_BOTTOM or $this->xAxisPosition === PLOT_BOTH) { + $bottom = $this->xAxis; + if($this->xAxisZero === FALSE) { + $bottom->line->setY($y2, $y2); + } + $bottom->label->setAlign(NULL, LABEL_BOTTOM); + $bottom->label->move(0, 3); + $bottom->reverseTickStyle(); + $bottom->title->move(0, 25); + $bottom->draw($drawer); + } + + // Draw left axis + if($this->yAxisPosition === PLOT_LEFT or $this->yAxisPosition === PLOT_BOTH) { + $left = $this->yAxis; + if($this->yAxisZero === FALSE) { + $left->line->setX($x1, $x1); + } + $left->label->setAlign(LABEL_RIGHT); + $left->label->move(-6, 0); + $left->title->move(-25, 0); + $left->draw($drawer); + } + + // Draw right axis + if($this->yAxisPosition === PLOT_RIGHT or $this->yAxisPosition === PLOT_BOTH) { + $right = $this->yAxis; + if($this->yAxisZero === FALSE) { + $right->line->setX($x2, $x2); + } + $right->label->setAlign(LABEL_LEFT); + $right->label->move(6, 0); + $right->reverseTickStyle(); + $right->title->move(25, 0); + $right->draw($drawer); + } + + } + + function createGrid() { + + $max = $this->getRealYMax(); + $min = $this->getRealYMin(); + + $number = $this->yAxis->getLabelNumber() - 1; + + if($number < 1) { + return; + } + + // Horizontal lines of the grid + + $h = array(); + for($i = 0; $i <= $number; $i++) { + $h[] = $i / $number; + } + + // Vertical lines + + $major = $this->yAxis->tick('major'); + $interval = $major->getInterval(); + $number = $this->getXAxisNumber() - 1; + + $w = array(); + + if($number > 0) { + + for($i = 0; $i <= $number; $i++) { + if($i%$interval === 0) { + $w[] = $i / $number; + } + } + + } + + $this->grid->setGrid($w, $h); + + } + + /** + * Change values of Y axis + * This method ignores not numeric values + * + * @param array $datay + * @param array $datax + */ + function setValues($datay, $datax = NULL) { + + $this->checkArray($datay); + + foreach($datay as $key => $value) { + unset($datay[$key]); + $datay[(int)$key] = $value; + } + + if($datax === NULL) { + $datax = array(); + for($i = 0; $i < count($datay); $i++) { + $datax[] = $i; + } + } else { + foreach($datax as $key => $value) { + unset($datax[$key]); + $datax[(int)$key] = $value; + } + } + + $this->checkArray($datax); + + if(count($datay) === count($datax)) { + + // Set values + $this->datay = $datay; + $this->datax = $datax; + // Update axis with the new awvalues + $this->updateAxis(); + } else { + trigger_error("Plots must have the same number of X and Y points", E_USER_ERROR); + } + + } + + /** + * Return begin and end values + * + * @return array + */ + function getLimit() { + + $i = 0; + while(array_key_exists($i, $this->datay) and $this->datay[$i] === NULL) { + $i++; + } + $start = $i; + $i = count($this->datay) - 1; + while(array_key_exists($i, $this->datay) and $this->datay[$i] === NULL) { + $i--; + } + $stop = $i; + + return array($start, $stop); + + } + + /** + * Return TRUE if labels must be centered on X axis, FALSE otherwise + * + * @return bool + */ + + + function updateAxis() { + + $this->xAxis->setRange( + $this->getXMin(), + $this->getXMax() + ); + $this->yAxis->setRange( + $this->getRealYMin(), + $this->getRealYMax() + ); + + } + + function checkArray(&$array) { + + if(is_array($array) === FALSE) { + trigger_error("You tried to set a value that is not an array", E_USER_ERROR); + } + + foreach($array as $key => $value) { + if(is_numeric($value) === FALSE and is_null($value) === FALSE) { + trigger_error("Expected numeric values for the plot", E_USER_ERROR); + } + } + + if(count($array) < 1) { + trigger_error("Your plot must have at least 1 value", E_USER_ERROR); + } + + } + +} + +registerClass('Plot', TRUE); + +class awPlotAxis { + + /** + * Left axis + * + * @var Axis + */ + var $left; + + /** + * Right axis + * + * @var Axis + */ + var $right; + + /** + * Top axis + * + * @var Axis + */ + var $top; + + /** + * Bottom axis + * + * @var Axis + */ + var $bottom; + + /** + * Build the group of axis + */ + function awPlotAxis() { + + $this->left = new awAxis; + $this->left->auto(TRUE); + $this->left->label->setAlign(LABEL_RIGHT); + $this->left->label->move(-6, 0); + $this->yAxis($this->left); + $this->left->setTickStyle(TICK_OUT); + $this->left->title->move(-25, 0); + + $this->right = new awAxis; + $this->right->auto(TRUE); + $this->right->label->setAlign(LABEL_LEFT); + $this->right->label->move(6, 0); + $this->yAxis($this->right); + $this->right->setTickStyle(TICK_IN); + $this->right->title->move(25, 0); + + $this->top = new awAxis; + $this->top->label->setAlign(NULL, LABEL_TOP); + $this->top->label->move(0, -3); + $this->xAxis($this->top); + $this->top->setTickStyle(TICK_OUT); + $this->top->title->move(0, -25); + + $this->bottom = new awAxis; + $this->bottom->label->setAlign(NULL, LABEL_BOTTOM); + $this->bottom->label->move(0, 3); + $this->xAxis($this->bottom); + $this->bottom->setTickStyle(TICK_IN); + $this->bottom->title->move(0, 25); + + } + + function xAxis(&$axis) { + + $axis->addTick('major', new awTick(0, 5)); + $axis->addTick('minor', new awTick(0, 3)); + $axis->label->setFont(new awTuffy(7)); + + } + + function yAxis(&$axis) { + + $axis->addTick('major', new awTick(0, 5)); + $axis->addTick('minor', new awTick(0, 3)); + $axis->setNumberByTick('minor', 'major', 3); + $axis->label->setFont(new awTuffy(7)); + $axis->title->setAngle(90); + + } + +} + +registerClass('PlotAxis'); + +/** + * A graph with axis can contain some groups of components + * + * @package Artichow + */ +class awPlotGroup extends awComponentGroup { + + /** + * Grid properties + * + * @var Grid + */ + var $grid; + + /** + * Left, right, top and bottom axis + * + * @var PlotAxis + */ + var $axis; + + /** + * Set the X axis on zero + * + * @var bool + */ + var $xAxisZero = TRUE; + + /** + * Set the Y axis on zero + * + * @var bool + */ + var $yAxisZero = FALSE; + + /** + * Real axis used for Y axis + * + * @var string + */ + var $yRealAxis = PLOT_LEFT; + + /** + * Real axis used for X axis + * + * @var string + */ + var $xRealAxis = PLOT_BOTTOM; + + /** + * Change min value for Y axis + * + * @var mixed + */ + var $yMin = NULL; + + /** + * Change max value for Y axis + * + * @var mixed + */ + var $yMax = NULL; + + /** + * Change min value for X axis + * + * @var mixed + */ + var $xMin = NULL; + + /** + * Change max value for X axis + * + * @var mixed + */ + var $xMax = NULL; + + /** + * Build the PlotGroup + * + */ + function awPlotGroup() { + + parent::awComponentGroup(); + + $this->grid = new awGrid; + $this->grid->setBackgroundColor(new awWhite); + + $this->axis = new awPlotAxis; + + } + + /** + * Set the X axis on zero or not + * + * @param bool $zero + */ + function setXAxisZero($zero) { + $this->xAxisZero = (bool)$zero; + } + + /** + * Set the Y axis on zero or not + * + * @param bool $zero + */ + function setYAxisZero($zero) { + $this->yAxisZero = (bool)$zero; + } + + /** + * Change min value for Y axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setYMin($value) { + $this->axis->left->auto(FALSE); + $this->axis->right->auto(FALSE); + $this->yMin = $value; + } + + /** + * Change max value for Y axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setYMax($value) { + $this->axis->left->auto(FALSE); + $this->axis->right->auto(FALSE); + $this->yMax = $value; + } + + /** + * Change min value for X axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setXMin($value) { + $this->xMin = $value; + } + + /** + * Change max value for X axis + * Set NULL for auto selection. + * + * @param float $value + */ + function setXMax($value) { + $this->xMax = $value; + } + + /** + * Get min value for X axis + * + * @return float $value + */ + function getXMin() { + + return $this->getX('min'); + + } + + /** + * Get max value for X axis + * + * @return float $value + */ + function getXMax() { + + return $this->getX('max'); + + } + + function getX($type) { + + switch($type) { + case 'max' : + if($this->xMax !== NULL) { + return $this->xMax; + } + break; + case 'min' : + if($this->xMin !== NULL) { + return $this->xMin; + } + break; + } + + $value = NULL; + $get = 'getX'.ucfirst($type); + + for($i = 0; $i < count($this->components); $i++) { + + $component = $this->components[$i]; + + if($value === NULL) { + $value = $component->$get(); + } else { + $value = $type($value, $component->$get()); + } + + } + + return $value; + + } + + /** + * Get min value with spaces for Y axis + * + * @param string $axis Axis name + * @return float $value + */ + function getRealYMin($axis = NULL) { + + if($axis === NULL) { + return NULL; + } + + $min = $this->getRealY('min', $axis); + $max = $this->getRealY('max', $axis); + + if($this->space->bottom !== NULL) { + $interval = ($min - $max) * $this->space->bottom / 100; + return $min + $interval; + } else { + return $min; + } + + } + + /** + * Get max value with spaces for Y axis + * + * @param string $axis Axis name + * @return float $value + */ + function getRealYMax($axis = NULL) { + + if($axis === NULL) { + return NULL; + } + + $min = $this->getRealY('min', $axis); + $max = $this->getRealY('max', $axis); + + if($this->space->top !== NULL) { + $interval = ($max - $min) * $this->space->top / 100; + return $max + $interval; + } else { + return $max; + } + + } + + function getRealY($type, $axis) { + + switch($type) { + case 'max' : + if($this->yMax !== NULL) { + return $this->yMax; + } + break; + case 'min' : + if($this->yMin !== NULL) { + return $this->yMin; + } + break; + } + + $value = NULL; + $get = 'getY'.ucfirst($type); + + for($i = 0; $i < count($this->components); $i++) { + + $component = $this->components[$i]; + + switch($axis) { + + case PLOT_LEFT : + case PLOT_RIGHT : + $test = ($component->getYAxis() === $axis); + break; + default : + $test = FALSE; + + } + + if($test) { + if($value === NULL) { + $value = $component->$get(); + } else { + $value = $type($value, $component->$get()); + } + } + + } + + return $value; + + } + + function init($drawer) { + + list($x1, $y1, $x2, $y2) = $this->getPosition(); + + // Get PlotGroup space + list($leftSpace, $rightSpace, $topSpace, $bottomSpace) = $this->getSpace($x2 - $x1, $y2 - $y1); + + // Count values in the group + $values = $this->getXAxisNumber(); + + // Init the PlotGroup + $this->axis->top->line->setX($x1, $x2); + $this->axis->bottom->line->setX($x1, $x2); + $this->axis->left->line->setY($y2, $y1); + $this->axis->right->line->setY($y2, $y1); + + $this->axis->top->setPadding($leftSpace, $rightSpace); + $this->axis->bottom->setPadding($leftSpace, $rightSpace); + + $xMin = $this->getXMin(); + $xMax = $this->getXMax(); + + $this->axis->top->setRange($xMin, $xMax); + $this->axis->bottom->setRange($xMin, $xMax); + + for($i = 0; $i < count($this->components); $i++) { + + + $component = &$this->components[$i]; + + $component->auto($this->auto); + + // Copy space to the component + + $component->setSpace($this->space->left, $this->space->right, $this->space->top, $this->space->bottom); + + $component->xAxis->setPadding($leftSpace, $rightSpace); + $component->xAxis->line->setX($x1, $x2); + + $component->yAxis->line->setY($y2, $y1); + + } + + // Set Y axis range + foreach(array('left', 'right') as $axis) { + + if($this->isAxisUsed($axis)) { + + $min = $this->getRealYMin($axis); + $max = $this->getRealYMax($axis); + + $interval = $max - $min; + + $this->axis->{$axis}->setRange( + $min - $interval * $this->space->bottom / 100, + $max + $interval * $this->space->top / 100 + ); + + // Auto-scaling mode + $this->axis->{$axis}->autoScale(); + + } + + } + + if($this->axis->left->getLabelNumber() === NULL) { + $number = round(($y2 - $y1) / 75) + 2; + $this->axis->left->setLabelNumber($number); + } + + if($this->axis->right->getLabelNumber() === NULL) { + $number = round(($y2 - $y1) / 75) + 2; + $this->axis->right->setLabelNumber($number); + } + + // Center labels on X axis if needed + $test = array(PLOT_TOP => FALSE, PLOT_BOTTOM => FALSE); + + for($i = 0; $i < count($this->components); $i++) { + + + $component = &$this->components[$i]; + + + if($component->getValues() !== NULL) { + + $axis = $component->getXAxis(); + + if($test[$axis] === FALSE) { + + // Center labels for bar plots + if($component->getXCenter()) { + $size = $this->axis->{$axis}->getDistance(0, 1); + $this->axis->{$axis}->label->move($size / 2, 0); + $this->axis->{$axis}->label->hideLast(TRUE); + $test[$axis] = TRUE; + } + + } + + } + + + } + + // Set axis labels + $labels = array(); + for($i = $xMin; $i <= $xMax; $i++) { + $labels[] = $i; + } + if($this->axis->top->label->count() === 0) { + $this->axis->top->label->set($labels); + } + if($this->axis->bottom->label->count() === 0) { + $this->axis->bottom->label->set($labels); + } + + // Set ticks + + $this->axis->top->ticks['major']->setNumber($values); + $this->axis->bottom->ticks['major']->setNumber($values); + $this->axis->left->ticks['major']->setNumber($this->axis->left->getLabelNumber()); + $this->axis->right->ticks['major']->setNumber($this->axis->right->getLabelNumber()); + + + // Set X axis on zero + if($this->xAxisZero) { + $axis = $this->selectYAxis(); + $this->axis->bottom->setYCenter($axis, 0); + $this->axis->top->setYCenter($axis, 0); + } + + // Set Y axis on zero + if($this->yAxisZero) { + $axis = $this->selectXAxis(); + $this->axis->left->setXCenter($axis, 1); + $this->axis->right->setXCenter($axis, 1); + } + + parent::init($drawer); + + list($leftSpace, $rightSpace, $topSpace, $bottomSpace) = $this->getSpace($x2 - $x1, $y2 - $y1); + + // Create the grid + $this->createGrid(); + + // Draw the grid + $this->grid->setSpace($leftSpace, $rightSpace, 0, 0); + $this->grid->draw($drawer, $x1, $y1, $x2, $y2); + + } + + function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) { + + $xMin = $this->getXMin(); + $xMax = $this->getXMax(); + + $maxLeft = $this->getRealYMax(PLOT_LEFT); + $maxRight = $this->getRealYMax(PLOT_RIGHT); + + $minLeft = $this->getRealYMin(PLOT_LEFT); + $minRight = $this->getRealYMin(PLOT_RIGHT); + + foreach($this->components as $component) { + + $min = $component->getYMin(); + $max = $component->getYMax(); + + // Set component minimum and maximum + if($component->getYAxis() === PLOT_LEFT) { + + list($min, $max) = $this->axis->left->getRange(); + + $component->setYMin($min); + $component->setYMax($max); + + } else { + + list($min, $max) = $this->axis->right->getRange(); + + $component->setYMin($min); + $component->setYMax($max); + + } + + $component->setXAxisZero($this->xAxisZero); + $component->setYAxisZero($this->yAxisZero); + + $component->xAxis->setRange($xMin, $xMax); + + $component->drawComponent( + $drawer, + $x1, $y1, + $x2, $y2, + $aliasing + ); + + $component->setYMin($min); + $component->setYMax($max); + + } + + } + + function drawEnvelope($drawer) { + + list($x1, $y1, $x2, $y2) = $this->getPosition(); + + // Hide unused axis + foreach(array(PLOT_LEFT, PLOT_RIGHT, PLOT_TOP, PLOT_BOTTOM) as $axis) { + if($this->isAxisUsed($axis) === FALSE) { + $this->axis->{$axis}->hide(TRUE); + } + } + + // Draw top axis + $top = $this->axis->top; + if($this->xAxisZero === FALSE) { + $top->line->setY($y1, $y1); + } + $top->draw($drawer); + + // Draw bottom axis + $bottom = $this->axis->bottom; + if($this->xAxisZero === FALSE) { + $bottom->line->setY($y2, $y2); + } + $bottom->draw($drawer); + + // Draw left axis + $left = $this->axis->left; + if($this->yAxisZero === FALSE) { + $left->line->setX($x1, $x1); + } + $left->draw($drawer); + + // Draw right axis + $right = $this->axis->right; + if($this->yAxisZero === FALSE) { + $right->line->setX($x2, $x2); + } + $right->draw($drawer); + + } + + /** + * Is the specified axis used ? + * + * @param string $axis Axis name + * @return bool + */ + function isAxisUsed($axis) { + + for($i = 0; $i < count($this->components); $i++) { + + $component = $this->components[$i]; + + switch($axis) { + + case PLOT_LEFT : + case PLOT_RIGHT : + if($component->getYAxis() === $axis) { + return TRUE; + } + break; + + case PLOT_TOP : + case PLOT_BOTTOM : + if($component->getXAxis() === $axis) { + return TRUE; + } + break; + + } + + } + + return FALSE; + + } + + function createGrid() { + + $max = $this->getRealYMax(PLOT_LEFT); + $min = $this->getRealYMin(PLOT_RIGHT); + + // Select axis (left if possible, right otherwise) + $axis = $this->selectYAxis(); + + $number = $axis->getLabelNumber() - 1; + + if($number < 1) { + return; + } + + // Horizontal lines of grid + + $h = array(); + for($i = 0; $i <= $number; $i++) { + $h[] = $i / $number; + } + + // Vertical lines + + $major = $axis->tick('major'); + $interval = $major->getInterval(); + $number = $this->getXAxisNumber() - 1; + + $w = array(); + + if($number > 0) { + + for($i = 0; $i <= $number; $i++) { + if($i%$interval === 0) { + $w[] = $i / $number; + } + } + + } + + $this->grid->setGrid($w, $h); + + } + + function selectYAxis(){ + + // Select axis (left if possible, right otherwise) + if($this->isAxisUsed(PLOT_LEFT)) { + $axis = $this->axis->left; + } else { + $axis = $this->axis->right; + } + + return $axis; + + } + + function selectXAxis(){ + + // Select axis (bottom if possible, top otherwise) + if($this->isAxisUsed(PLOT_BOTTOM)) { + $axis = $this->axis->bottom; + } else { + $axis = $this->axis->top; + } + + return $axis; + + } + + function getXAxisNumber() { + $offset = $this->components[0]; + $max = $offset->getXAxisNumber(); + for($i = 1; $i < count($this->components); $i++) { + $offset = $this->components[$i]; + $max = max($max, $offset->getXAxisNumber()); + } + return $max; + } + +} + +registerClass('PlotGroup'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/ScatterPlot.class.php b/external-libs/Artichow/php4/ScatterPlot.class.php new file mode 100644 index 00000000000..e82b664c73d --- /dev/null +++ b/external-libs/Artichow/php4/ScatterPlot.class.php @@ -0,0 +1,303 @@ +mark = new awMark; + $this->mark->setType(MARK_CIRCLE); + $this->mark->setSize(7); + $this->mark->border->show(); + + $this->label = new awLabel; + + $this->setValues($datay, $datax); + $this->setColor(new awBlack); + + } + + /** + * Display plot as impulses + * + * @param $impulse Impulses color (or NULL to disable impulses) + */ + function setImpulse($color) { + $this->impulse = $color; + } + + /** + * Link scatter plot points + * + * @param bool $link + * @param $color Line color (default to black) + */ + function link($link, $color = NULL) { + $this->link = (bool)$link; + if(is_a($color, 'awColor')) { + $this->setColor($color); + } + } + + /** + * Ignore null values for Y data and continue linking + * + * @param bool $link + */ + function linkNull($link) { + $this->linkNull = (bool)$link; + } + + /** + * Change line color + * + * @param $color + */ + function setColor($color) { + $this->lineColor = $color; + } + + /** + * Change line style + * + * @param int $style + */ + function setStyle($style) { + $this->lineStyle = (int)$style; + } + + /** + * Change line tickness + * + * @param int $tickness + */ + function setThickness($tickness) { + $this->lineThickness = (int)$tickness; + } + + /** + * Get the line thickness + * + * @return int + */ + function getLegendLineThickness() { + return $this->lineThickness; + } + + /** + * Get the line type + * + * @return int + */ + function getLegendLineStyle() { + return $this->lineStyle; + } + + /** + * Get the color of line + * + * @return Color + */ + function getLegendLineColor() { + return $this->lineColor; + } + + /** + * Get the background color or gradient of an element of the component + * + * @return Color, Gradient + */ + function getLegendBackground() { + return NULL; + } + + /** + * Get a mark object + * + * @return Mark + */ + function getLegendMark() { + return $this->mark; + } + + function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) { + + $count = count($this->datay); + + // Get start and stop values + list($start, $stop) = $this->getLimit(); + + // Build the polygon + $polygon = new awPolygon; + + for($key = 0; $key < $count; $key++) { + + $x = $this->datax[$key]; + $y = $this->datay[$key]; + + if($y !== NULL) { + $p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($x, $y)); + $polygon->set($key, $p); + } else if($this->linkNull === FALSE) { + $polygon->set($key, NULL); + } + + } + + // Link points if needed + if($this->link) { + + $prev = NULL; + + foreach($polygon->all() as $point) { + + if($prev !== NULL and $point !== NULL) { + $drawer->line( + $this->lineColor, + new awLine( + $prev, + $point, + $this->lineStyle, + $this->lineThickness + ) + ); + } + $prev = $point; + + } + + $this->lineColor->free(); + + } + + // Draw impulses + if(is_a($this->impulse, 'awColor')) { + + foreach($polygon->all() as $key => $point) { + + if($point !== NULL) { + + $zero = awAxis::toPosition( + $this->xAxis, + $this->yAxis, + new awPoint($key, 0) + ); + + $drawer->line( + $this->impulse, + new awLine( + $zero, + $point, + LINE_SOLID, + 1 + ) + ); + + } + + } + + } + + // Draw marks and labels + foreach($polygon->all() as $key => $point) { + + $this->mark->draw($drawer, $point); + $this->label->draw($drawer, $point, $key); + + } + + } + + function xAxisPoint($position) { + $y = $this->xAxisZero ? 0 : $this->getRealYMin(); + return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y)); + } + + function getXCenter() { + return FALSE; + } + +} + +registerClass('ScatterPlot'); +?> diff --git a/external-libs/Artichow/php4/common.php b/external-libs/Artichow/php4/common.php new file mode 100644 index 00000000000..d399f73c781 --- /dev/null +++ b/external-libs/Artichow/php4/common.php @@ -0,0 +1,102 @@ + 0) { + + do { + $min = array_pop($array); + if(is_numeric($min === FALSE)) { + $min = NULL; + } + } while(count($array) > 0 and $min === NULL); + + if($min !== NULL) { + $min = (float)$min; + } + + foreach($array as $value) { + if(is_numeric($value) and (float)$value < $min) { + $min = (float)$value; + } + } + + return $min; + + } + + return NULL; + +} + +/* + * Get the maximum of an array and ignore non numeric values + */ +function array_max($array) { + + if(is_array($array) and count($array) > 0) { + + do { + $max = array_pop($array); + if(is_numeric($max === FALSE)) { + $max = NULL; + } + } while(count($array) > 0 and $max === NULL); + + if($max !== NULL) { + $max = (float)$max; + } + + foreach($array as $value) { + if(is_numeric($value) and (float)$value > $max) { + $max = (float)$value; + } + } + + return $max; + + } + + return NULL; + +} + +/* + * Register a class with the prefix in configuration file + */ +function registerClass($class, $abstract = FALSE) { + + if(ARTICHOW_PREFIX === 'aw') { + return; + } + + + $abstract = ''; + + + eval($abstract." class ".ARTICHOW_PREFIX.$class." extends aw".$class." { }"); + +} + +/* + * Register an interface with the prefix in configuration file + */ +function registerInterface($interface) { + + if(ARTICHOW_PREFIX === 'aw') { + return; + } + + +} +?> diff --git a/external-libs/Artichow/php4/inc/Axis.class.php b/external-libs/Artichow/php4/inc/Axis.class.php new file mode 100644 index 00000000000..7cc138ab53c --- /dev/null +++ b/external-libs/Artichow/php4/inc/Axis.class.php @@ -0,0 +1,769 @@ + 'toProportionalValue', + 'toPosition' => 'toProportionalPosition' + ); + + /** + * Build the axis + * + * @param float $min Begin of the range of the axis + * @param float $max End of the range of the axis + */ + function awAxis($min = NULL, $max = NULL) { + + $this->line = new awVector( + new awPoint(0, 0), + new awPoint(0, 0) + ); + + $this->label = new awLabel; + $this->padding = new awSide; + + $this->title = new awLabel( + NULL, + NULL, + NULL, + 0 + ); + + $this->setColor(new awBlack); + + if($min !== NULL and $max !== NULL) { + $this->setRange($min, $max); + } + + } + + /** + * Enable/disable auto-scaling mode + * + * @param bool $auto + */ + function auto($auto) { + $this->auto = (bool)$auto; + } + + /** + * Get auto-scaling mode status + * + * @return bool + */ + function isAuto() { + return $this->auto; + } + + /** + * Hide axis + * + * @param bool $hide + */ + function hide($hide = TRUE) { + $this->hide = (bool)$hide; + } + + /** + * Show axis + * + * @param bool $show + */ + function show($show = TRUE) { + $this->hide = !(bool)$show; + } + + /** + * Return a tick object from its name + * + * @param string $name Tick object name + * @return Tick + */ + function tick($name) { + + if(array_key_exists($name, $this->ticks)) { + return $tick = &$this->ticks[$name]; + } else { + return NULL; + } + + } + + /** + * Add a tick object + * + * @param string $name Tick object name + * @param &$tick Tick object + */ + function addTick($name, &$tick) { + + $this->ticks[$name] = &$tick; + + } + + /** + * Delete a tick object + * + * @param string $name Tick object name + */ + function deleteTick($name) { + if(array_key_exists($name, $this->ticks)) { + unset($this->ticks[$name]); + } + } + + /** + * Hide all ticks + * + * @param bool $hide Hide or not ? + */ + function hideTicks($hide = TRUE) { + + foreach($this->ticks as $key => $tick) { + $this->ticks[$key]->hide($hide); + } + + } + + /** + * Change ticks style + * + * @param int $style Ticks style + */ + function setTickStyle($style) { + + foreach($this->ticks as $key => $tick) { + $this->ticks[$key]->setStyle($style); + } + + } + + /** + * Change ticks interval + * + * @param int $interval Ticks interval + */ + function setTickInterval($interval) { + + foreach($this->ticks as $key => $tick) { + $this->ticks[$key]->setInterval($interval); + } + + } + + /** + * Change number of ticks relative to others ticks + * + * @param &$to Change number of theses ticks + * @param &$from Ticks reference + * @param float $number Number of ticks by the reference + */ + function setNumberByTick($to, $from, $number) { + $this->ticks[$to]->setNumberByTick($this->ticks[$from], $number); + } + + /** + * Reverse ticks style + */ + function reverseTickStyle() { + + foreach($this->ticks as $key => $tick) { + if($this->ticks[$key]->getStyle() === TICK_IN) { + $this->ticks[$key]->setStyle(TICK_OUT); + } else if($this->ticks[$key]->getStyle() === TICK_OUT) { + $this->ticks[$key]->setStyle(TICK_IN); + } + } + + } + + /** + * Change interval of labels + * + * @param int $interval Interval + */ + function setLabelInterval($interval) { + $this->auto(FALSE); + $this->setTickInterval($interval); + $this->label->setInterval($interval); + } + + /** + * Change number of labels + * + * @param int $number Number of labels to display (can be NULL) + */ + function setLabelNumber($number) { + $this->auto(FALSE); + $this->labelNumber = is_null($number) ? NULL : (int)$number; + } + + /** + * Get number of labels + * + * @return int + */ + function getLabelNumber() { + return $this->labelNumber; + } + + /** + * Change precision of labels + * + * @param int $precision Precision + */ + function setLabelPrecision($precision) { + $this->auto(FALSE); + $function = 'axis'.time().'_'.(microtime() * 1000000); + eval('function '.$function.'($value) { + return sprintf("%.'.(int)$precision.'f", $value); + }'); + $this->label->setCallbackFunction($function); + } + + /** + * Change text of labels + * + * @param array $texts Some texts + */ + function setLabelText($texts) { + if(is_array($texts)) { + $this->auto(FALSE); + $function = 'axis'.time().'_'.(microtime() * 1000000); + eval('function '.$function.'($value) { + $texts = '.var_export($texts, TRUE).'; + return isset($texts[$value]) ? $texts[$value] : \'?\'; + }'); + $this->label->setCallbackFunction($function); + } + } + + /** + * Get the position of a point + * + * @param &$xAxis X axis + * @param &$yAxis Y axis + * @param $p Position of the point + * @return Point Position on the axis + */ + function toPosition(&$xAxis, &$yAxis, $p) { + + $p1 = $xAxis->getPointFromValue($p->x); + $p2 = $yAxis->getPointFromValue($p->y); + + return new awPoint( + round($p1->x), + round($p2->y) + ); + + } + + /** + * Change title alignment + * + * @param int $alignment New Alignment + */ + function setTitleAlignment($alignment) { + + switch($alignment) { + + case LABEL_TOP : + $this->setTitlePosition(1); + $this->title->setAlign(NULL, LABEL_BOTTOM); + break; + + case LABEL_BOTTOM : + $this->setTitlePosition(0); + $this->title->setAlign(NULL, LABEL_TOP); + break; + + case LABEL_LEFT : + $this->setTitlePosition(0); + $this->title->setAlign(LABEL_LEFT); + break; + + case LABEL_RIGHT : + $this->setTitlePosition(1); + $this->title->setAlign(LABEL_RIGHT); + break; + + } + + } + + /** + * Change title position on the axis + * + * @param float $position A new awposition between 0 and 1 + */ + function setTitlePosition($position) { + $this->titlePosition = (float)$position; + } + + /** + * Change axis and axis title color + * + * @param $color + */ + function setColor($color) { + $this->color = $color; + $this->title->setColor($color); + } + + /** + * Change axis padding + * + * @param int $left Left padding in pixels + * @param int $right Right padding in pixels + */ + function setPadding($left, $right) { + $this->padding->set($left, $right); + } + + /** + * Get axis padding + * + * @return Side + */ + function getPadding() { + return $this->padding; + } + + /** + * Change axis range + * + * @param float $min + * @param float $max + */ + function setRange($min, $max) { + if($min !== NULL) { + $this->range[0] = (float)$min; + } + if($max !== NULL) { + $this->range[1] = (float)$max; + } + } + + /** + * Get axis range + * + * @return array + */ + function getRange() { + return $this->range; + } + + /** + * Change axis range callback function + * + * @param string $toValue Transform a position between 0 and 1 to a value + * @param string $toPosition Transform a value to a position between 0 and 1 on the axis + */ + function setRangeCallback($toValue, $toPosition) { + $this->rangeCallback = array( + 'toValue' => (string)$toValue, + 'toPosition' => (string)$toPosition + ); + } + + /** + * Center X values of the axis + * + * @param &$axis An axis + * @param float $value The reference value on the axis + */ + function setXCenter(&$axis, $value) { + + // Check vector angle + if($this->line->isVertical() === FALSE) { + trigger_error("setXCenter() can only be used on vertical axes", E_USER_ERROR); + } + + $p = $axis->getPointFromValue($value); + + $this->line->setX( + $p->x, + $p->x + ); + + } + + /** + * Center Y values of the axis + * + * @param &$axis An axis + * @param float $value The reference value on the axis + */ + function setYCenter(&$axis, $value) { + + // Check vector angle + if($this->line->isHorizontal() === FALSE) { + trigger_error("setYCenter() can only be used on horizontal axes", E_USER_ERROR); + } + + $p = $axis->getPointFromValue($value); + + $this->line->setY( + $p->y, + $p->y + ); + + } + + /** + * Get the distance between to values on the axis + * + * @param float $from The first value + * @param float $to The last value + * @return Point + */ + function getDistance($from, $to) { + + $p1 = $this->getPointFromValue($from); + $p2 = $this->getPointFromValue($to); + + return $p1->getDistance($p2); + + } + + /** + * Get a point on the axis from a value + * + * @param float $value + * @return Point + */ + function getPointFromValue($value) { + + $callback = $this->rangeCallback['toPosition']; + + list($min, $max) = $this->range; + $position = $callback($value, $min, $max); + + return $this->getPointFromPosition($position); + + } + + /** + * Get a point on the axis from a position + * + * @param float $position A position between 0 and 1 + * @return Point + */ + function getPointFromPosition($position) { + + $vector = $this->getVector(); + + $angle = $vector->getAngle(); + $size = $vector->getSize(); + + return $vector->p1->move( + cos($angle) * $size * $position, + -1 * sin($angle) * $size * $position + ); + + } + + /** + * Draw axis + * + * @param $drawer A drawer + */ + function draw($drawer) { + + if($this->hide) { + return; + } + + $vector = $this->getVector(); + + // Draw axis ticks + $this->drawTicks($drawer, $vector); + + // Draw axis line + $this->line($drawer); + + // Draw labels + $this->drawLabels($drawer); + + // Draw axis title + $p = $this->getPointFromPosition($this->titlePosition); + $this->title->draw($drawer, $p); + + } + + function autoScale() { + + if($this->isAuto() === FALSE) { + return; + } + + list($min, $max) = $this->getRange(); + $interval = $max - $min; + + if($interval > 0) { + $partMax = $max / $interval; + $partMin = $min / $interval; + } else { + $partMax = 0; + $partMin = 0; + } + + $difference = log($interval) / log(10); + $difference = floor($difference); + + $pow = pow(10, $difference); + + if($pow > 0) { + $intervalNormalize = $interval / $pow; + } else { + $intervalNormalize = 0; + } + + if($difference <= 0) { + + $precision = $difference * -1 + 1; + + if($intervalNormalize > 2) { + $precision--; + } + + } else { + $precision = 0; + } + + if($min != 0 and $max != 0) { + $precision++; + } + + $this->setLabelPrecision($precision); + + if($intervalNormalize <= 1.5) { + $intervalReal = 1.5; + $labelNumber = 4; + } else if($intervalNormalize <= 2) { + $intervalReal = 2; + $labelNumber = 5; + } else if($intervalNormalize <= 3) { + $intervalReal = 3; + $labelNumber = 4; + } else if($intervalNormalize <= 4) { + $intervalReal = 4; + $labelNumber = 5; + } else if($intervalNormalize <= 5) { + $intervalReal = 5; + $labelNumber = 6; + } else if($intervalNormalize <= 8) { + $intervalReal = 8; + $labelNumber = 5; + } else if($intervalNormalize <= 10) { + $intervalReal = 10; + $labelNumber = 6; + } + + if($min == 0) { + + $this->setRange( + $min, + $intervalReal * $pow + ); + + } else if($max == 0) { + + $this->setRange( + $intervalReal * $pow * -1, + 0 + ); + + } + + $this->setLabelNumber($labelNumber); + + } + + function line($drawer) { + + $drawer->line( + $this->color, + $this->line + ); + + } + + function drawTicks($drawer, &$vector) { + + foreach($this->ticks as $tick) { + $tick->setColor($this->color); + $tick->draw($drawer, $vector); + } + + } + + function drawLabels($drawer) { + + if($this->labelNumber !== NULL) { + list($min, $max) = $this->range; + $number = $this->labelNumber - 1; + if($number < 1) { + return; + } + $function = $this->rangeCallback['toValue']; + $labels = array(); + for($i = 0; $i <= $number; $i++) { + $labels[] = $function($i / $number, $min, $max); + } + $this->label->set($labels); + } + + $labels = $this->label->count(); + + for($i = 0; $i < $labels; $i++) { + + $p = $this->getPointFromValue($this->label->get($i)); + $this->label->draw($drawer, $p, $i); + + } + + } + + function getVector() { + + $angle = $this->line->getAngle(); + + // Compute paddings + $vector = new awVector( + $this->line->p1->move( + cos($angle) * $this->padding->left, + -1 * sin($angle) * $this->padding->left + ), + $this->line->p2->move( + -1 * cos($angle) * $this->padding->right, + -1 * -1 * sin($angle) * $this->padding->right + ) + ); + + return $vector; + + } + + function __clone() { + + $this->label = $this->label; + $this->line = $this->line; + $this->title = $this->title; + + foreach($this->ticks as $name => $tick) { + $this->ticks[$name] = $tick; + } + + } + +} + +registerClass('Axis'); + +function toProportionalValue($position, $min, $max) { + return $min + ($max - $min) * $position; +} + +function toProportionalPosition($value, $min, $max) { + if($max - $min == 0) { + return 0; + } + return ($value - $min) / ($max - $min); +} +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Border.class.php b/external-libs/Artichow/php4/inc/Border.class.php new file mode 100644 index 00000000000..5e8f6f50f99 --- /dev/null +++ b/external-libs/Artichow/php4/inc/Border.class.php @@ -0,0 +1,158 @@ +setStyle($style); + + if(is_a($color, 'awColor')) { + $this->setColor($color); + } else { + $this->setColor(new awBlack); + } + + } + + /** + * Change border color + * This method automatically shows the border if it is hidden + * + * @param $color + */ + function setColor($color) { + $this->color = $color; + $this->show(); + } + + /** + * Change border style + * + * @param int $style + */ + function setStyle($style) { + $this->style = (int)$style; + } + + /** + * Hide border ? + * + * @param bool $hide + */ + function hide($hide = TRUE) { + $this->hide = (bool)$hide; + } + + /** + * Show border ? + * + * @param bool $show + */ + function show($show = TRUE) { + $this->hide = (bool)!$show; + } + + /** + * Is the border visible ? + * + * @return bool + */ + function visible() { + return !$this->hide; + } + + /** + * Draw border as a rectangle + * + * @param $drawer + * @param $p1 Top-left corner + * @param $p2 Bottom-right corner + */ + function rectangle($drawer, $p1, $p2) { + + // Border is hidden + if($this->hide) { + return; + } + + $line = new awLine; + $line->setStyle($this->style); + $line->setLocation($p1, $p2); + + $drawer->rectangle($this->color, $line); + + } + + /** + * Draw border as an ellipse + * + * @param $drawer + * @param $center Ellipse center + * @param int $width Ellipse width + * @param int $height Ellipse height + */ + function ellipse($drawer, $center, $width, $height) { + + // Border is hidden + if($this->hide) { + return; + } + + switch($this->style) { + + case LINE_SOLID : + $drawer->ellipse($this->color, $center, $width, $height); + break; + + default : + trigger_error("Dashed and dotted borders and not yet implemented on ellipses", E_USER_ERROR); + break; + + } + + + } + +} + +registerClass('Border'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Color.class.php b/external-libs/Artichow/php4/inc/Color.class.php new file mode 100644 index 00000000000..5b40a5c926a --- /dev/null +++ b/external-libs/Artichow/php4/inc/Color.class.php @@ -0,0 +1,201 @@ +red = (int)$red; + $this->green = (int)$green; + $this->blue = (int)$blue; + $this->alpha = (int)round($alpha * 127 / 100); + + } + + /** + * Return a GDised color + * + * @param resource $resource A GD resource + * @return int + */ + function getColor($resource) { + + $this->resource = $resource; + + if($this->color === NULL) { + + if($this->alpha === 0 or function_exists('imagecolorallocatealpha') === FALSE) { + $this->color = imagecolorallocate($this->resource, $this->red, $this->green, $this->blue); + } else { + $this->color = imagecolorallocatealpha($this->resource, $this->red, $this->green, $this->blue, $this->alpha); + } + + } + + return $this->color; + + } + + /** + * Change color brightness + * + * @param int $brightness Add this intensity to the color (betweeen -255 and +255) + */ + function brightness($brightness) { + + $brightness = (int)$brightness; + + $this->red = min(255, max(0, $this->red + $brightness)); + $this->green = min(255, max(0, $this->green + $brightness)); + $this->blue = min(255, max(0, $this->blue + $brightness)); + + } + + /** + * Get RGB and alpha values of your color + * + * @return array + */ + function rgba() { + + return array($this->red, $this->green, $this->blue, $this->alpha); + + } + + /** + * Free resources used for this color + */ + function free() { + + if($this->resource !== NULL) { + + @imagecolordeallocate($this->resource, $this->color); + $this->resource = NULL; + + } + + } + + function php5Destructor() { + + $this->free(); + + } + +} + +registerClass('Color'); + +$colors = array( + 'Black' => array(0, 0, 0), + 'AlmostBlack' => array(48, 48, 48), + 'VeryDarkGray' => array(88, 88, 88), + 'DarkGray' => array(128, 128, 128), + 'MidGray' => array(160, 160, 160), + 'LightGray' => array(195, 195, 195), + 'VeryLightGray' => array(220, 220, 220), + 'White' => array(255, 255, 255), + 'VeryDarkRed' => array(64, 0, 0), + 'DarkRed' => array(128, 0, 0), + 'MidRed' => array(192, 0, 0), + 'Red' => array(255, 0, 0), + 'LightRed' => array(255, 192, 192), + 'VeryDarkGreen' => array(0, 64, 0), + 'DarkGreen' => array(0, 128, 0), + 'MidGreen' => array(0, 192, 0), + 'Green' => array(0, 255, 0), + 'LightGreen' => array(192, 255, 192), + 'VeryDarkBlue' => array(0, 0, 64), + 'DarkBlue' => array(0, 0, 128), + 'MidBlue' => array(0, 0, 192), + 'Blue' => array(0, 0, 255), + 'LightBlue' => array(192, 192, 255), + 'VeryDarkYellow' => array(64, 64, 0), + 'DarkYellow' => array(128, 128, 0), + 'MidYellow' => array(192, 192, 0), + 'Yellow' => array(255, 255, 2), + 'LightYellow' => array(255, 255, 192), + 'VeryDarkCyan' => array(0, 64, 64), + 'DarkCyan' => array(0, 128, 128), + 'MidCyan' => array(0, 192, 192), + 'Cyan' => array(0, 255, 255), + 'LightCyan' => array(192, 255, 255), + 'VeryDarkMagenta' => array(64, 0, 64), + 'DarkMagenta' => array(128, 0, 128), + 'MidMagenta' => array(192, 0, 192), + 'Magenta' => array(255, 0, 255), + 'LightMagenta' => array(255, 192, 255), + 'DarkOrange' => array(192, 88, 0), + 'Orange' => array(255, 128, 0), + 'LightOrange' => array(255, 168, 88), + 'VeryLightOrange' => array(255, 220, 168), + 'DarkPink' => array(192, 0, 88), + 'Pink' => array(255, 0, 128), + 'LightPink' => array(255, 88, 168), + 'VeryLightPink' => array(255, 168, 220), + 'DarkPurple' => array(88, 0, 192), + 'Purple' => array(128, 0, 255), + 'LightPurple' => array(168, 88, 255), + 'VeryLightPurple' => array(220, 168, 255), +); + + + +$php = ''; + +foreach($colors as $name => $color) { + + list($red, $green, $blue) = $color; + + $php .= ' + class aw'.$name.' extends awColor { + + function aw'.$name.'($alpha = 0) { + parent::awColor('.$red.', '.$green.', '.$blue.', $alpha); + } + + } + '; + + if(ARTICHOW_PREFIX !== 'aw') { + $php .= ' + class '.ARTICHOW_PREFIX.$name.' extends aw'.$name.' { + + } + '; + } + +} + +eval($php); + + + +?> diff --git a/external-libs/Artichow/php4/inc/Drawer.class.php b/external-libs/Artichow/php4/inc/Drawer.class.php new file mode 100644 index 00000000000..e145056a413 --- /dev/null +++ b/external-libs/Artichow/php4/inc/Drawer.class.php @@ -0,0 +1,1131 @@ +resource = $resource; + + } + + /** + * Change the image size + * + * @param int $width Image width + * @param int $height Image height + */ + function setImageSize($width, $height) { + + $this->width = $width; + $this->height = $height; + + } + + /** + * Inform the drawer of the position of your image + * + * @param float $x Position on X axis of the center of the component + * @param float $y Position on Y axis of the center of the component + */ + function setPosition($x, $y) { + + // Calcul absolute position + $this->x = round($x * $this->width - $this->w / 2); + $this->y = round($y * $this->height - $this->h / 2); + + } + + /** + * Inform the drawer of the position of your image + * This method need absolutes values + * + * @param int $x Left-top corner X position + * @param int $y Left-top corner Y position + */ + function setAbsPosition($x, $y) { + + $this->x = $x; + $this->y = $y; + + } + + /** + * Move the position of the image + * + * @param int $x Add this value to X axis + * @param int $y Add this value to Y axis + */ + function movePosition($x, $y) { + + $this->x += (int)$x; + $this->y += (int)$y; + + } + + /** + * Inform the drawer of the size of your image + * Height and width must be between 0 and 1. + * + * @param int $w Image width + * @param int $h Image height + * @return array Absolute width and height of the image + */ + function setSize($w, $h) { + + // Calcul absolute size + $this->w = round($w * $this->width); + $this->h = round($h * $this->height); + + return $this->getSize(); + + } + + /** + * Inform the drawer of the size of your image + * You can set absolute size with this method. + * + * @param int $w Image width + * @param int $h Image height + */ + function setAbsSize($w, $h) { + + $this->w = $w; + $this->h = $h; + + return $this->getSize(); + + } + + /** + * Get the size of the component handled by the drawer + * + * @return array Absolute width and height of the component + */ + function getSize() { + + return array($this->w, $this->h); + + } + + /** + * Draw an image here + * + * @param &$image Image + * @param int $p1 Image top-left point + * @param int $p2 Image bottom-right point + */ + function copyImage(&$image, $p1, $p2) { + + list($x1, $y1) = $p1->getLocation(); + list($x2, $y2) = $p2->getLocation(); + + $drawer = $image->getDrawer(); + imagecopy($this->resource, $drawer->resource, $this->x + $x1, $this->y + $y1, 0, 0, $x2 - $x1, $y2 - $y1); + + } + + /** + * Draw an image here + * + * @param &$image Image + * @param int $d1 Destination top-left position + * @param int $d2 Destination bottom-right position + * @param int $s1 Source top-left position + * @param int $s2 Source bottom-right position + * @param bool $resample Resample image ? (default to TRUE) + */ + function copyResizeImage(&$image, $d1, $d2, $s1, $s2, $resample = TRUE) { + + if($resample) { + $function = 'imagecopyresampled'; + } else { + $function = 'imagecopyresized'; + } + + $drawer = $image->getDrawer(); + + $function( + $this->resource, + $drawer->resource, + $this->x + $d1->x, $this->y + $d1->y, + $s1->x, $s1->y, + $d2->x - $d1->x, $d2->y - $d1->y, + $s2->x - $s1->x, $s2->y - $s1->y + ); + + } + + /** + * Draw a string + * + * @var &$text Text to print + * @param $point Draw the text at this point + */ + function string(&$text, $point) { + + $font = $text->getFont(); + + if($text->getBackground() !== NULL or $text->border->visible()) { + + list($left, $right, $top, $bottom) = $text->getPadding(); + + $width = $font->getTextWidth($text); + $height = $font->getTextHeight($text); + + $x1 = floor($point->x - $left); + $y1 = floor($point->y - $top); + $x2 = $x1 + $width + $left + $right; + $y2 = $y1 + $height + $top + $bottom; + + $this->filledRectangle( + $text->getBackground(), + awLine::build($x1, $y1, $x2, $y2) + ); + + $text->border->rectangle( + $this, + new awPoint($x1 - 1, $y1 - 1), + new awPoint($x2 + 1, $y2 + 1) + ); + + } + + $font->draw($this, $point, $text); + + } + + /** + * Draw a pixel + * + * @param $color Pixel color + * @param $p + */ + function point($color, $p) { + + if($p->isHidden() === FALSE) { + $rgb = $color->getColor($this->resource); + imagesetpixel($this->resource, $this->x + round($p->x), $this->y + round($p->y), $rgb); + } + + } + + /** + * Draw a colored line + * + * @param $color Line color + * @param $line + * @param int $thickness Line tickness + */ + function line($color, $line) { + + if($line->thickness > 0 and $line->isHidden() === FALSE) { + + $rgb = $color->getColor($this->resource); + $thickness = $line->thickness; + + list($p1, $p2) = $line->getLocation(); + + $this->startThickness($thickness); + + switch($line->getStyle()) { + + case LINE_SOLID : + imageline($this->resource, $this->x + round($p1->x), $this->y + round($p1->y), $this->x + round($p2->x), $this->y + round($p2->y), $rgb); + break; + + case LINE_DOTTED : + $size = sqrt(pow($p2->y - $p1->y, 2) + pow($p2->x - $p1->x, 2)); + $cos = ($p2->x - $p1->x) / $size; + $sin = ($p2->y - $p1->y) / $size; + for($i = 0; $i <= $size; $i += 2) { + $p = new awPoint( + round($i * $cos + $p1->x), + round($i * $sin + $p1->y) + ); + $this->point($color, $p); + } + break; + + case LINE_DASHED : + $width = $p2->x - $p1->x; + $height = $p2->y - $p1->y; + $size = sqrt(pow($height, 2) + pow($width, 2)); + + if($size == 0) { + return; + } + + $cos = $width / $size; + $sin = $height / $size; + + for($i = 0; $i <= $size; $i += 6) { + + $t1 = new awPoint( + round($i * $cos + $p1->x), + round($i * $sin + $p1->y) + ); + + $function = ($height > 0) ? 'min' : 'max'; + $t2 = new awPoint( + round(min(($i + 3) * $cos, $width) + $p1->x), + round($function(($i + 3) * $sin, $height) + $p1->y) + ); + + $this->line($color, new awLine($t1, $t2)); + + } + break; + + } + + $this->stopThickness($thickness); + + } + + } + + /** + * Draw a color arc + + * @param $color Arc color + * @param $center Point center + * @param int $width Ellipse width + * @param int $height Ellipse height + * @param int $from Start angle + * @param int $to End angle + */ + function arc($color, $center, $width, $height, $from, $to) { + + imagefilledarc( + $this->resource, + $this->x + $center->x, $this->y + $center->y, + $width, $height, + $from, $to, + $color->getColor($this->resource), + IMG_ARC_EDGED | IMG_ARC_NOFILL + ); + + } + + /** + * Draw an arc with a background color + * + * @param $color Arc background color + * @param $center Point center + * @param int $width Ellipse width + * @param int $height Ellipse height + * @param int $from Start angle + * @param int $to End angle + */ + function filledArc($color, $center, $width, $height, $from, $to) { + + imagefilledarc( + $this->resource, + $this->x + $center->x, $this->y + $center->y, + $width, $height, + $from, $to, + $color->getColor($this->resource), + IMG_ARC_PIE + ); + + } + + /** + * Draw a colored ellipse + * + * @param $color Ellipse color + * @param $center Ellipse center + * @param int $width Ellipse width + * @param int $height Ellipse height + */ + function ellipse($color, $center, $width, $height) { + + list($x, $y) = $center->getLocation(); + + $rgb = $color->getColor($this->resource); + imageellipse( + $this->resource, + $this->x + $x, + $this->y + $y, + $width, + $height, + $rgb + ); + + } + + /** + * Draw an ellipse with a background + * + * @param mixed $background Background (can be a color or a gradient) + * @param $center Ellipse center + * @param int $width Ellipse width + * @param int $height Ellipse height + */ + function filledEllipse($background, $center, $width, $height) { + + if(is_a($background, 'awColor')) { + + list($x, $y) = $center->getLocation(); + + $rgb = $background->getColor($this->resource); + + imagefilledellipse( + $this->resource, + $this->x + $x, + $this->y + $y, + $width, + $height, + $rgb + ); + + } else if(is_a($background, 'awGradient')) { + + list($x, $y) = $center->getLocation(); + + $x1 = $x - round($width / 2); + $y1 = $y - round($height / 2); + $x2 = $x1 + $width; + $y2 = $y1 + $height; + + $gradientDrawer = new awGradientDrawer($this); + $gradientDrawer->filledEllipse( + $background, + $x1, $y1, + $x2, $y2 + ); + + } + + } + + /** + * Draw a colored rectangle + * + * @param $color Rectangle color + * @param $line Rectangle diagonale + * @param $p2 + */ + function rectangle($color, $line) { + + $p1 = $line->p1; + $p2 = $line->p2; + + switch($line->getStyle()) { + + case LINE_SOLID : + $thickness = $line->getThickness(); + $this->startThickness($thickness); + $rgb = $color->getColor($this->resource); + imagerectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb); + $this->stopThickness($thickness); + break; + + default : + + // Top side + $line->setLocation( + new awPoint($p1->x, $p1->y), + new awPoint($p2->x, $p1->y) + ); + $this->line($color, $line); + + // Right side + $line->setLocation( + new awPoint($p2->x, $p1->y), + new awPoint($p2->x, $p2->y) + ); + $this->line($color, $line); + + // Bottom side + $line->setLocation( + new awPoint($p1->x, $p2->y), + new awPoint($p2->x, $p2->y) + ); + $this->line($color, $line); + + // Left side + $line->setLocation( + new awPoint($p1->x, $p1->y), + new awPoint($p1->x, $p2->y) + ); + $this->line($color, $line); + + break; + + } + + } + + /** + * Draw a rectangle with a background + * + * @param mixed $background Background (can be a color or a gradient) + * @param $line Rectangle diagonale + */ + function filledRectangle($background, $line) { + + $p1 = $line->p1; + $p2 = $line->p2; + + if(is_a($background, 'awColor')) { + $rgb = $background->getColor($this->resource); + imagefilledrectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb); + } else if(is_a($background, 'awGradient')) { + $gradientDrawer = new awGradientDrawer($this); + $gradientDrawer->filledRectangle($background, $p1, $p2); + } + + } + + /** + * Draw a polygon + * + * @param $color Polygon color + * @param Polygon A polygon + */ + function polygon($color, &$polygon) { + + switch($polygon->getStyle()) { + + case POLYGON_SOLID : + $thickness = $line->getThickness(); + $this->startThickness($thickness); + $points = $this->getPolygonPoints($polygon); + $rgb = $color->getColor($this->resource); + imagepolygon($this->resource, $points, $polygon->count(), $rgb); + $this->stopThickness($thickness); + break; + + default : + + if($polygon->count() > 1) { + + $prev = $polygon->get(0); + + $line = new awLine; + $line->setStyle($polygon->getStyle()); + $line->setThickness($polygon->getThickness()); + + for($i = 1; $i < $polygon->count(); $i++) { + $current = $polygon->get($i); + $line->setLocation($prev, $current); + $this->line($color, $line); + $prev = $current; + } + + } + + } + + } + + /** + * Draw a polygon with a background + * + * @param mixed $background Background (can be a color or a gradient) + * @param Polygon A polygon + */ + function filledPolygon($background, &$polygon) { + + if(is_a($background, 'awColor')) { + $points = $this->getPolygonPoints($polygon); + $rgb = $background->getColor($this->resource); + imagefilledpolygon($this->resource, $points, $polygon->count(), $rgb); + } else if(is_a($background, 'awGradient')) { + $gradientDrawer = new awGradientDrawer($this); + $gradientDrawer->filledPolygon($background, $polygon); + } + + } + + function getPolygonPoints(&$polygon) { + + $points = array(); + + foreach($polygon->all() as $point) { + $points[] = $point->x + $this->x; + $points[] = $point->y + $this->y; + } + + return $points; + + } + + function startThickness($thickness) { + + if($thickness > 1) { + + // Beurk :'( + if(function_exists('imageantialias')) { + imageantialias($this->resource, FALSE); + } + imagesetthickness($this->resource, $thickness); + + } + + } + + function stopThickness($thickness) { + + if($thickness > 1) { + + if(function_exists('imageantialias')) { + imageantialias($this->resource, TRUE); + } + imagesetthickness($this->resource, 1); + + } + + } + + +} + +registerClass('Drawer'); + +/** + * To your gradients + * + * @package Artichow + */ + +class awGradientDrawer { + + /** + * A drawer + * + * @var Drawer + */ + var $drawer; + + /** + * Build your GradientDrawer + * + * @var $drawer + */ + function awGradientDrawer($drawer) { + + $this->drawer = $drawer; + + } + + function drawFilledFlatTriangle($gradient, $a, $b, $c) { + + if($gradient->angle !== 0) { + trigger_error("Flat triangles can only be used with 0 degree gradients", E_USER_ERROR); + } + + // Look for right-angled triangle + if($a->x !== $b->x and $b->x !== $c->x) { + trigger_error("Not right-angled flat triangles are not supported yet", E_USER_ERROR); + } + + if($a->x === $b->x) { + $d = $a; + $e = $c; + } else { + $d = $c; + $e = $a; + } + + $this->init($gradient, $b->y - $d->y); + + for($i = $c->y + 1; $i < $b->y; $i++) { + + $color = $this->color($i - $d->y); + $pos = ($i - $d->y) / ($b->y - $d->y); + + $p1 = new awPoint($e->x, $i); + $p2 = new awPoint(1 + floor($e->x - $pos * ($e->x - $d->x)), $i); + + $this->drawer->filledRectangle($color, new awLine($p1, $p2)); + + $color->free(); + unset($color); + + } + + } + + function filledRectangle($gradient, $p1, $p2) { + + list($x1, $y1) = $p1->getLocation(); + list($x2, $y2) = $p2->getLocation(); + + if($y1 < $y2) { + $y1 ^= $y2 ^= $y1 ^= $y2; + } + + if($x2 < $x1) { + $x1 ^= $x2 ^= $x1 ^= $x2; + } + + if(is_a($gradient, 'awLinearGradient')) { + $this->rectangleLinearGradient($gradient, new awPoint($x1, $y1), new awPoint($x2, $y2)); + } else { + trigger_error("This gradient is not supported by rectangles", E_USER_ERROR); + } + + } + + function filledPolygon($gradient, &$polygon) { + + if(is_a($gradient, 'awLinearGradient')) { + $this->polygonLinearGradient($gradient, $polygon); + } else { + trigger_error("This gradient is not supported by polygons", E_USER_ERROR); + } + + } + + function rectangleLinearGradient(&$gradient, $p1, $p2) { + + list($x1, $y1) = $p1->getLocation(); + list($x2, $y2) = $p2->getLocation(); + + if($y1 - $y2 > 0) { + + if($gradient->angle === 0) { + + $this->init($gradient, $y1 - $y2); + + for($i = $y2; $i <= $y1; $i++) { + + $color = $this->color($i - $y2); + + $p1 = new awPoint($x1, $i); + $p2 = new awPoint($x2, $i); + + $this->drawer->filledRectangle($color, new awLine($p1, $p2)); + + $color->free(); + unset($color); + + } + + } else if($gradient->angle === 90) { + + $this->init($gradient, $x2 - $x1); + + for($i = $x1; $i <= $x2; $i++) { + + $color = $this->color($i - $x1); + + $p1 = new awPoint($i, $y2); + $p2 = new awPoint($i, $y1); + + $this->drawer->filledRectangle($color, new awLine($p1, $p2)); + + $color->free(); + unset($color); + + } + + } + + } + + } + + function filledEllipse($gradient, $x1, $y1, $x2, $y2) { + + if($y1 < $y2) { + $y1 ^= $y2 ^= $y1 ^= $y2; + } + + if($x2 < $x1) { + $x1 ^= $x2 ^= $x1 ^= $x2; + } + + if(is_a($gradient, 'awRadialGradient')) { + $this->ellipseRadialGradient($gradient, $x1, $y1, $x2, $y2); + } else if(is_a($gradient, 'awLinearGradient')) { + $this->ellipseLinearGradient($gradient, $x1, $y1, $x2, $y2); + } else { + trigger_error("This gradient is not supported by ellipses", E_USER_ERROR); + } + + } + + function ellipseRadialGradient($gradient, $x1, $y1, $x2, $y2) { + + if($y1 - $y2 > 0) { + + if($y1 - $y2 != $x2 - $x1) { + trigger_error("Radial gradients are only implemented on circle, not ellipses"); + } + + $c = new awPoint($x1 + ($x2 - $x1) / 2, $y1 + ($y2 - $y1) / 2); + $r = ($x2 - $x1) / 2; + $ok = array(); + + // Init gradient + $this->init($gradient, $r); + + for($i = 0; $i <= $r; $i += 0.45) { + + $p = ceil((2 * M_PI * $i)); + + if($p > 0) { + $interval = 360 / $p; + } else { + $interval = 360; + } + + $color = $this->color($i); + + for($j = 0; $j < 360; $j += $interval) { + + $rad = ($j / 360) * (2 * M_PI); + + $x = round($i * cos($rad)); + $y = round($i * sin($rad)); + + $l = sqrt($x * $x + $y * $y); + + if($l <= $r) { + + if( + array_key_exists((int)$x, $ok) === FALSE or + array_key_exists((int)$y, $ok[$x]) === FALSE + ) { + + // Print the point + $this->drawer->point($color, new awPoint($c->x + $x, $c->y + $y)); + + $ok[(int)$x][(int)$y] = TRUE; + + } + + } + + } + + $color->free(); + unset($color); + + } + + } + + } + + function ellipseLinearGradient($gradient, $x1, $y1, $x2, $y2) { + + // Gauche->droite : 90° + + if($y1 - $y2 > 0) { + + if($y1 - $y2 != $x2 - $x1) { + trigger_error("Linear gradients are only implemented on circle, not ellipses"); + } + + $r = ($x2 - $x1) / 2; + + // Init gradient + $this->init($gradient, $x2 - $x1); + + for($i = -$r; $i <= $r; $i++) { + + $h = sin(acos($i / $r)) * $r; + + $color = $this->color($i + $r); + + if($gradient->angle === 90) { + + // Print the line + $p1 = new awPoint( + $x1 + $i + $r, + round(max($y2 + $r - $h + 1, $y2)) + ); + + $p2 = new awPoint( + $x1 + $i + $r, + round(min($y1 - $r + $h - 1, $y1)) + ); + + } else { + + // Print the line + $p1 = new awPoint( + round(max($x1 + $r - $h + 1, $x1)), + $y2 + $i + $r + ); + + $p2 = new awPoint( + round(min($x2 - $r + $h - 1, $x2)), + $y2 + $i + $r + ); + + } + + $this->drawer->filledRectangle($color, new awLine($p1, $p2)); + + $color->free(); + unset($color); + + } + + } + + } + + function polygonLinearGradient(&$gradient, &$polygon) { + + $count = $polygon->count(); + + if($count >= 3) { + + $left = $polygon->get(0); + $right = $polygon->get($count - 1); + + if($gradient->angle === 0) { + + // Get polygon maximum and minimum + $offset = $polygon->get(0); + $max = $min = $offset->y; + for($i = 1; $i < $count - 1; $i++) { + $offset = $polygon->get($i); + $max = max($max, $offset->y); + $min = min($min, $offset->y); + } + + $this->init($gradient, $max - $min); + + $prev = $polygon->get(1); + + $sum = 0; + + for($i = 2; $i < $count - 1; $i++) { + + $current = $polygon->get($i); + + $interval = 1; + + if($i !== $count - 2) { + $current->x -= $interval; + } + + if($current->x - $prev->x > 0) { + + // Draw rectangle + $x1 = $prev->x; + $x2 = $current->x; + $y1 = max($prev->y, $current->y); + $y2 = $left->y; + + $gradient = new awLinearGradient( + $this->color($max - $min - ($y2 - $y1)), + $this->color($max - $min), + 0 + ); + + if($y1 > $y2) { + $y2 = $y1; + } + + $this->drawer->filledRectangle( + $gradient, + awLine::build($x1, $y1, $x2, $y2) + ); + + $top = ($prev->y < $current->y) ? $current : $prev; + $bottom = ($prev->y >= $current->y) ? $current : $prev; + + $gradient = new awLinearGradient( + $this->color($bottom->y - $min), + $this->color($max - $min - ($y2 - $y1)), + 0 + ); + + + $gradientDrawer = new awGradientDrawer($this->drawer); + $gradientDrawer->drawFilledFlatTriangle( + $gradient, + new awPoint($prev->x, min($prev->y, $current->y)), + $top, + new awPoint($current->x, min($prev->y, $current->y)) + ); + unset($gradientDrawer); + + $sum += $current->x - $prev->x; + + } + + $prev = $current; + $prev->x += $interval; + + } + + } else if($gradient->angle === 90) { + + $width = $right->x - $left->x; + $this->init($gradient, $width); + + $pos = 1; + $next = $polygon->get($pos++); + + $this->next($polygon, $pos, $prev, $next); + + for($i = 0; $i <= $width; $i++) { + + $x = $left->x + $i; + + $y1 = round($prev->y + ($next->y - $prev->y) * (($i + $left->x - $prev->x) / ($next->x - $prev->x))); + $y2 = $left->y; + + // Draw line + $color = $this->color($i); + // YaPB : PHP does not handle alpha on lines + $this->drawer->filledRectangle($color, awLine::build($x, $y1, $x, $y2)); + $color->free(); + unset($color); + + // Jump to next point + if($next->x == $i + $left->x) { + + $this->next($polygon, $pos, $prev, $next); + + } + + } + + } + + } + + } + + function next($polygon, &$pos, &$prev, &$next) { + + do { + $prev = $next; + $next = $polygon->get($pos++); + } + while($next->x - $prev->x == 0 and $pos < $polygon->count()); + + } + + /** + * Start colors + * + * @var int + */ + var $r1, $g1, $b1, $a1; + + /** + * Stop colors + * + * @var int + */ + var $r2, $g2, $b2, $a2; + + /** + * Gradient size in pixels + * + * @var int + */ + var $size; + + + function init($gradient, $size) { + + list( + $this->r1, $this->g1, $this->b1, $this->a1 + ) = $gradient->from->rgba(); + + list( + $this->r2, $this->g2, $this->b2, $this->a2 + ) = $gradient->to->rgba(); + + $this->size = $size; + } + + function color($pos) { + + return new awColor( + $this->getRed($pos), + $this->getGreen($pos), + $this->getBlue($pos), + $this->getAlpha($pos) + ); + + } + + + function getRed($pos) { + return (int)round($this->r1 + ($pos / $this->size) * ($this->r2 - $this->r1)); + } + + function getGreen($pos) { + return (int)round($this->g1 + ($pos / $this->size) * ($this->g2 - $this->g1)); + } + + function getBlue($pos) { + return (int)round($this->b1 + ($pos / $this->size) * ($this->b2 - $this->b1)); + } + + function getAlpha($pos) { + return (int)round(($this->a1 + ($pos / $this->size) * ($this->a2 - $this->a1)) / 127 * 100); + } + +} + +registerClass('GradientDrawer'); +?> diff --git a/external-libs/Artichow/php4/inc/Font.class.php b/external-libs/Artichow/php4/inc/Font.class.php new file mode 100644 index 00000000000..3648e5dd35a --- /dev/null +++ b/external-libs/Artichow/php4/inc/Font.class.php @@ -0,0 +1,295 @@ +font = $font; + + } + + /** + * Draw a text + * + * @param $drawer + * @param $p Draw text at this point + * @param &$text The text + */ + function draw($drawer, $p, &$text) { + + $angle = $text->getAngle(); + + if($angle !== 90 and $angle !== 0) { + trigger_error("You can only use 0° and 90°", E_USER_ERROR); + } + + if($angle === 90) { + $function = 'imagestringup'; + } else { + $function = 'imagestring'; + } + + if($angle === 90) { + $add = $this->getTextHeight($text); + } else { + $add = 0; + } + + $color = $text->getColor(); + $rgb = $color->getColor($drawer->resource); + + $function( + $drawer->resource, + $this->font, + $drawer->x + $p->x, + $drawer->y + $p->y + $add, + $text->getText(), + $rgb + ); + + } + + /** + * Get the width of a string + * + * @param &$text A string + */ + function getTextWidth(&$text) { + + if($text->getAngle() === 90) { + $text->setAngle(45); + return $this->getTextHeight($text); + } else if($text->getAngle() === 45) { + $text->setAngle(90); + } + + $font = $text->getFont(); + $fontWidth = imagefontwidth($font->font); + + if($fontWidth === FALSE) { + trigger_error("Unable to get font size", E_USER_ERROR); + } + + return (int)$fontWidth * strlen($text->getText()); + + } + + /** + * Get the height of a string + * + * @param &$text A string + */ + function getTextHeight(&$text) { + + if($text->getAngle() === 90) { + $text->setAngle(45); + return $this->getTextWidth($text); + } else if($text->getAngle() === 45) { + $text->setAngle(90); + } + + $font = $text->getFont(); + $fontHeight = imagefontheight($font->font); + + if($fontHeight === FALSE) { + trigger_error("Unable to get font size", E_USER_ERROR); + } + + return (int)$fontHeight; + + } + +} + +registerClass('Font'); + +/** + * TTF fonts + * + * @package Artichow + */ +class awTTFFont extends awFont { + + /** + * Font size + * + * @var int + */ + var $size; + + /** + * Font file + * + * @param string $font Font file + * @param int $size Font size + */ + function awTTFFont($font, $size) { + + parent::awFont($font); + + $this->size = (int)$size; + + } + + /** + * Draw a text + * + * @param $drawer + * @param $p Draw text at this point + * @param &$text The text + */ + function draw($drawer, $p, &$text) { + + // Make easier font positionment + $text->setText($text->getText()." "); + + $color = $text->getColor(); + $rgb = $color->getColor($drawer->resource); + + $box = imagettfbbox($this->size, $text->getAngle(), $this->font, $text->getText()); + + $height = - $box[5]; + + $box = imagettfbbox($this->size, 90, $this->font, $text->getText()); + $width = abs($box[6] - $box[2]); + + // Restore old text + $text->setText(substr($text->getText(), 0, strlen($text->getText()) - 1)); + + imagettftext( + $drawer->resource, + $this->size, + $text->getAngle(), + $drawer->x + $p->x + $width * sin($text->getAngle() / 180 * M_PI), + $drawer->y + $p->y + $height, + $rgb, + $this->font, + $text->getText() + ); + + } + + /** + * Get the width of a string + * + * @param &$text A string + */ + function getTextWidth(&$text) { + + $box = imagettfbbox($this->size, $text->getAngle(), $this->font, $text->getText()); + + if($box === FALSE) { + trigger_error("Unable to get font size", E_USER_ERROR); + return; + } + + list(, , $x2, $y2, , , $x1, $y1) = $box; + + return abs($x2 - $x1); + + } + + /** + * Get the height of a string + * + * @param &$text A string + */ + function getTextHeight(&$text) { + + $box = imagettfbbox($this->size, $text->getAngle(), $this->font, $text->getText()); + + if($box === FALSE) { + trigger_error("Unable to get font size", E_USER_ERROR); + return; + } + + list(, , $x2, $y2, , , $x1, $y1) = $box; + + return abs($y2 - $y1); + + } + +} + +registerClass('TTFFont'); + + + +$php = ''; + +for($i = 1; $i <= 5; $i++) { + + $php .= ' + class awFont'.$i.' extends awFont { + + function awFont'.$i.'() { + parent::awFont('.$i.'); + } + + } + '; + + if(ARTICHOW_PREFIX !== 'aw') { + $php .= ' + class '.ARTICHOW_PREFIX.'Font'.$i.' extends awFont'.$i.' { + } + '; + } + +} + +eval($php); + +$php = ''; + +foreach($fonts as $font) { + + $php .= ' + class aw'.$font.' extends awTTFFont { + + function aw'.$font.'($size) { + parent::awTTFFont(\''.(ARTICHOW_FONT.DIRECTORY_SEPARATOR.$font.'.ttf').'\', $size); + } + + } + '; + + if(ARTICHOW_PREFIX !== 'aw') { + $php .= ' + class '.ARTICHOW_PREFIX.$font.' extends aw'.$font.' { + } + '; + } + +} + +eval($php); + + + +?> diff --git a/external-libs/Artichow/php4/inc/Gradient.class.php b/external-libs/Artichow/php4/inc/Gradient.class.php new file mode 100644 index 00000000000..52abec7e64c --- /dev/null +++ b/external-libs/Artichow/php4/inc/Gradient.class.php @@ -0,0 +1,149 @@ +from = $from; + $this->to = $to; + + } + + /** + * Free memory used by the colors of the gradient + */ + function free() { + + $this->from->free(); + $this->to->free(); + + } + + function php5Destructor( ){ + + $this->free(); + + } + +} + +registerClass('Gradient', TRUE); + + +/** + * Create a linear gradient + * + * @package Artichow + */ +class awLinearGradient extends awGradient { + + /** + * Gradient angle + * + * @var int + */ + var $angle; + + /** + * Build the linear gradient + * + * @param $from From color + * @param $to To color + * @param int $angle Gradient angle + */ + function awLinearGradient($from, $to, $angle) { + + parent::awGradient( + $from, $to + ); + + $this->angle = $angle; + + } + +} + +registerClass('LinearGradient'); + + +/** + * Create a bilinear gradient + * + * @package Artichow + */ +class awBilinearGradient extends awLinearGradient { + + /** + * Gradient center + * + * @var int Center between 0 and 1 + */ + var $center; + + /** + * Build the bilinear gradient + * + * @param $from From color + * @param $to To color + * @param int $angle Gradient angle + * @param int $center Gradient center + */ + function awBilinearGradient($from, $to, $angle, $center = 0.5) { + + parent::awLinearGradient( + $from, $to, $angle + ); + + $this->center = $center; + + } + +} + +registerClass('BilinearGradient'); + +/** + * Create a radial gradient + * + * @package Artichow + */ +class awRadialGradient extends awGradient { + +} + +registerClass('RadialGradient'); +?> diff --git a/external-libs/Artichow/php4/inc/Grid.class.php b/external-libs/Artichow/php4/inc/Grid.class.php new file mode 100644 index 00000000000..d9b86723f3f --- /dev/null +++ b/external-libs/Artichow/php4/inc/Grid.class.php @@ -0,0 +1,289 @@ +color = new awColor(210, 210, 210); + $this->background = new awColor(255, 255, 255, 100); + + } + + /** + * Hide grid ? + * + * @param bool $hide + */ + function hide($hide = TRUE) { + $this->hide = (bool)$hide; + } + + /** + * Hide horizontal lines ? + * + * @param bool $hideHorizontal + */ + function hideHorizontal($hide = TRUE) { + $this->hideHorizontal = (bool)$hide; + } + + /** + * Hide vertical lines ? + * + * @param bool $hideVertical + */ + function hideVertical($hide = TRUE) { + $this->hideVertical = (bool)$hide; + } + + /** + * Change grid color + * + * @param $color + */ + function setColor($color) { + $this->color = $color; + } + + /** + * Remove grid background + */ + function setNoBackground() { + $this->background = NULL; + } + + /** + * Change grid background color + * + * @param $color + */ + function setBackgroundColor($color) { + $this->background = $color; + } + + /** + * Change line type + * + * @param int $type + */ + function setType($type) { + $this->type = (int)$type; + } + + /** + * Change grid interval + * + * @param int $hInterval + * @param int $vInterval + */ + function setInterval($hInterval, $vInterval) { + $this->interval = array((int)$hInterval, (int)$vInterval); + } + + /** + * Set grid space + * + * @param int $left Left space in pixels + * @param int $right Right space in pixels + * @param int $top Top space in pixels + * @param int $bottom Bottom space in pixels + */ + function setSpace($left, $right, $top, $bottom) { + $this->space = array((int)$left, (int)$right, (int)$top, (int)$bottom); + } + + /** + * Change the current grid + * + * @param array $xgrid Vertical lines + * @param array $ygrid Horizontal lines + */ + function setGrid($xgrid, $ygrid) { + + $this->xgrid = $xgrid; + $this->ygrid = $ygrid; + + } + + /** + * Draw grids + * + * @param $drawer A drawer object + * @param int $x1 + * @param int $y1 + * @param int $x2 + * @param int $y2 + */ + function draw($drawer, $x1, $y1, $x2, $y2) { + + if(is_a($this->background, 'awColor')) { + + // Draw background color + $drawer->filledRectangle( + $this->background, + awLine::build($x1, $y1, $x2, $y2) + ); + + $this->background->free(); + + } + + if($this->hide === FALSE) { + + $this->drawGrid( + $drawer, + $this->color, + $this->hideVertical ? array() : $this->xgrid, + $this->hideHorizontal ? array() : $this->ygrid, + $x1, $y1, $x2, $y2, + $this->type, + $this->space, + $this->interval[0], + $this->interval[1] + ); + + } + + $this->color->free(); + + } + + function drawGrid( + $drawer, $color, + $nx, $ny, $x1, $y1, $x2, $y2, + $type, $space, $hInterval, $vInterval + ) { + + list($left, $right, $top, $bottom) = $space; + + $width = $x2 - $x1 - $left - $right; + $height = $y2 - $y1 - $top - $bottom; + + foreach($nx as $key => $n) { + + if(($key % $vInterval) === 0) { + + $pos = (int)round($x1 + $left + $n * $width); + $drawer->line( + $color, + new awLine( + new awPoint($pos, $y1), + new awPoint($pos, $y2), + $type + ) + ); + + } + + } + + foreach($ny as $key => $n) { + + if(($key % $hInterval) === 0) { + + $pos = (int)round($y1 + $top + $n * $height); + $drawer->line( + $color, + new awLine( + new awPoint($x1, $pos), + new awPoint($x2, $pos), + $type + ) + ); + + } + + } + + } + +} + +registerClass('Grid'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Label.class.php b/external-libs/Artichow/php4/inc/Label.class.php new file mode 100644 index 00000000000..ac6cb7eb662 --- /dev/null +++ b/external-libs/Artichow/php4/inc/Label.class.php @@ -0,0 +1,596 @@ + */ + +define("LABEL_LEFT", 1); +define("LABEL_RIGHT", 2); +define("LABEL_CENTER", 3); +define("LABEL_TOP", 4); +define("LABEL_BOTTOM", 5); +define("LABEL_MIDDLE", 6); + +/* */ + +/** + * Draw labels + * + * @package Artichow + */ +class awLabel { + + /** + * Label border + * + * @var int + */ + var $border; + + /** + * Label texts + * + * @var array + */ + var $texts; + + /** + * Text font + * + * @var int + */ + var $font; + + /** + * Text angle + * + * @var int + */ + var $angle = 0; + + /** + * Text color + * + * @var Color + */ + var $color; + + /** + * Text background + * + * @var Color, Gradient + */ + var $background; + + /** + * Callback function + * + * @var string + */ + var $function; + + /** + * Padding + * + * @var int + */ + var $padding; + + /** + * Move position from this vector + * + * @var Point + */ + var $move; + + /** + * Label interval + * + * @var int + */ + var $interval = 1; + + /** + * Horizontal align + * + * @var int + */ + var $hAlign = LABEL_CENTER; + + /** + * Vertical align + * + * @var int + */ + var $vAlign = LABEL_MIDDLE; + + /** + * Hide all labels ? + * + * @var bool + */ + var $hide = FALSE; + + /** + * Keys to hide + * + * @var array + */ + var $hideKey = array(); + + /** + * Values to hide + * + * @var array + */ + var $hideValue = array(); + + /** + * Hide first label + * + * @var bool + */ + var $hideFirst = FALSE; + + /** + * Hide last label + * + * @var bool + */ + var $hideLast = FALSE; + + /** + * Build the label + * + * @param string $label First label + */ + function awLabel($label = NULL, $font = NULL, $color = NULL, $angle = 0) { + + if(is_array($label)) { + $this->set($label); + } else if(is_string($label)) { + $this->set(array($label)); + } + + if($font === NULL) { + $font = new awFont2; + } + + $this->setFont($font); + $this->setAngle($angle); + + if(is_a($color, 'awColor')) { + $this->setColor($color); + } else { + $this->setColor(new awColor(0, 0, 0)); + } + + $this->move = new awPoint(0, 0); + + $this->border = new awBorder; + $this->border->hide(); + + } + + /** + * Get an element of the label from its key + * + * @param int $key Element key + * @return string A value + */ + function get($key) { + return array_key_exists($key, $this->texts) ? $this->texts[$key] : NULL; + } + + /** + * Get all labels + * + * @return array + */ + function all() { + return $this->texts; + } + + /** + * Set one or several labels + * + * @param array $labels Array of string or a string + */ + function set($labels) { + + if(is_string($labels)) { + $this->texts = array($labels); + } else if(is_array($labels)) { + $this->texts = $labels; + } + + } + + /** + * Count number of texts in the label + * + * @return int + */ + function count() { + return is_array($this->texts) ? count($this->texts) : 0; + } + + /** + * Set a callback function for labels + * + * @param string $function + */ + function setCallbackFunction($function) { + $this->function = is_null($function) ? $function : (string)$function; + } + + /** + * Return the callback function for labels + * + * @return string + */ + function getCallbackFunction() { + return $this->function; + } + + /** + * Change labels format + * + * @param string $format New format (printf style: %.2f for example) + */ + function setFormat($format) { + $function = 'label'.time().'_'.(microtime() * 1000000); + eval('function '.$function.'($value) { + return sprintf("'.addcslashes($format, '"').'", $value); + }'); + $this->setCallbackFunction($function); + } + + /** + * Change font for label + * + * @param &$font New font + * @param $color Font color (can be NULL) + */ + function setFont(&$font, $color = NULL) { + $this->font = $font; + if(is_a($color, 'awColor')) { + $this->setColor($color); + } + } + + /** + * Change font angle + * + * @param int $angle New angle + */ + function setAngle($angle) { + $this->angle = (int)$angle; + } + + /** + * Change font color + * + * @param $color + */ + function setColor($color) { + $this->color = $color; + } + + /** + * Change text background + * + * @param mixed $background + */ + function setBackground($background) { + $this->background = $background; + } + + /** + * Change text background color + * + * @param Color + */ + function setBackgroundColor($color) { + $this->background = $color; + } + + /** + * Change text background gradient + * + * @param Gradient + */ + function setBackgroundGradient($gradient) { + $this->background = $gradient; + } + + /** + * Change padding + * + * @param int $left Left padding + * @param int $right Right padding + * @param int $top Top padding + * @param int $bottom Bottom padding + */ + function setPadding($left, $right, $top, $bottom) { + $this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom); + } + + /** + * Hide all labels ? + * + * @param bool $hide + */ + function hide($hide = TRUE) { + $this->hide = (bool)$hide; + } + + /** + * Show all labels ? + * + * @param bool $show + */ + function show($show = TRUE) { + $this->hide = (bool)!$show; + } + + /** + * Hide a key + * + * @param int $key The key to hide + */ + function hideKey($key) { + $this->hideKey[$key] = TRUE; + } + + /** + * Hide a value + * + * @param int $value The value to hide + */ + function hideValue($value) { + $this->hideValue[] = $value; + } + + /** + * Hide first label + * + * @param bool $hide + */ + function hideFirst($hide) { + $this->hideFirst = (bool)$hide; + } + + /** + * Hide last label + * + * @param bool $hide + */ + function hideLast($hide) { + $this->hideLast = (bool)$hide; + } + + /** + * Set label interval + * + * @param int + */ + function setInterval($interval) { + + $this->interval = (int)$interval; + + } + + /** + * Change label position + * + * @param int $x Add this interval to X coord + * @param int $y Add this interval to Y coord + */ + function move($x, $y) { + + $this->move = $this->move->move($x, $y); + + } + + /** + * Change alignment + * + * @param int $h Horizontal alignment + * @param int $v Vertical alignment + */ + function setAlign($h = NULL, $v = NULL) { + if($h !== NULL) { + $this->hAlign = (int)$h; + } + if($v !== NULL) { + $this->vAlign = (int)$v; + } + } + + /** + * Get a text from the labele + * + * @param mixed $key Key in the array text + * @return Text + */ + function getText($key) { + + if(is_array($this->texts) and array_key_exists($key, $this->texts)) { + + $value = $this->texts[$key]; + + if(is_string($this->function)) { + $value = call_user_func($this->function, $value); + } + + $text = new awText($value); + $text->setFont($this->font); + $text->setAngle($this->angle); + $text->setColor($this->color); + + if(is_a($this->background, 'awColor')) { + $text->setBackgroundColor($this->background); + } else if(is_a($this->background, 'awGradient')) { + $text->setBackgroundGradient($this->background); + } + + $text->border = $this->border; + + if($this->padding !== NULL) { + call_user_func_array(array($text, 'setPadding'), $this->padding); + } + + return $text; + + } else { + return NULL; + } + + } + + /** + * Get max width of all texts + * + * @param $drawer A drawer + * @return int + */ + function getMaxWidth($drawer) { + + return $this->getMax($drawer, 'getTextWidth'); + + } + + /** + * Get max height of all texts + * + * @param $drawer A drawer + * @return int + */ + function getMaxHeight($drawer) { + + return $this->getMax($drawer, 'getTextHeight'); + + } + + /** + * Draw the label + * + * @param $drawer + * @param $p Label center + * @param int $key Text position in the array of texts (default to zero) + */ + function draw($drawer, $p, $key = 0) { + + if(($key % $this->interval) !== 0) { + return; + } + + // Hide all labels + if($this->hide) { + return; + } + + // Key is hidden + if(array_key_exists($key, $this->hideKey)) { + return; + } + + // Hide first label + if($key === 0 and $this->hideFirst) { + return; + } + + // Hide last label + if($key === count($this->texts) - 1 and $this->hideLast) { + return; + } + + $text = $this->getText($key); + + if($text !== NULL) { + + // Value must be hidden + if(in_array($text->getText(), $this->hideValue)) { + return; + } + + $x = $p->x; + $y = $p->y; + + // Get padding + list($left, $right, $top, $bottom) = $text->getPadding(); + + $font = $text->getFont(); + $width = $font->getTextWidth($text); + $height = $font->getTextHeight($text); + + switch($this->hAlign) { + + case LABEL_RIGHT : + $x -= ($width + $right); + break; + + case LABEL_CENTER : + $x -= ($width - $left + $right) / 2; + break; + + case LABEL_LEFT : + $x += $left; + break; + + } + + switch($this->vAlign) { + + case LABEL_TOP : + $y -= ($height + $bottom); + break; + + case LABEL_MIDDLE : + $y -= ($height - $top + $bottom) / 2; + break; + + case LABEL_BOTTOM : + $y += $top; + break; + + } + + $drawer->string($text, $this->move->move($x, $y)); + + } + + } + + function getMax($drawer, $function) { + + $max = NULL; + + foreach($this->texts as $key => $text) { + + $text = $this->getText($key); + $font = $text->getFont(); + + if(is_null($max)) { + $max = $font->{$function}($text); + } else { + $max = max($max, $font->{$function}($text)); + } + + } + + return $max; + + } + +} + +registerClass('Label'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Legend.class.php b/external-libs/Artichow/php4/inc/Legend.class.php new file mode 100644 index 00000000000..2b2d840d3fc --- /dev/null +++ b/external-libs/Artichow/php4/inc/Legend.class.php @@ -0,0 +1,691 @@ + */ + +define("LEGEND_LINE", 1); +define("LEGEND_BACKGROUND", 2); +define("LEGEND_MARK", 3); +define("LEGEND_MARKONLY", 4); + +define("LEGEND_MODEL_RIGHT", 1); +define("LEGEND_MODEL_BOTTOM", 2); + +define("LEGEND_LEFT", 1); +define("LEGEND_RIGHT", 2); +define("LEGEND_CENTER", 3); +define("LEGEND_TOP", 4); +define("LEGEND_BOTTOM", 5); +define("LEGEND_MIDDLE", 6); + +/* */ + +/** + * Some legends + * + * @package Artichow + */ +class awLegend { + + /** + * Legends added + * + * @var array + */ + var $legends = array(); + + /** + * The current component + * + * @var Component + */ + var $component; + + /** + * Background color or gradient + * + * @var Color, Gradient + */ + var $background; + + /** + * Text color + * + * @var Color + */ + var $textColor; + + /** + * Text font + * + * @var Font + */ + var $textFont; + + /** + * Text margin + * + * @var Side + */ + var $textMargin; + + /** + * Number of columns + * + * @var int + */ + var $columns = NULL; + + /** + * Number of rows + * + * @var int + */ + var $rows = NULL; + + /** + * Legend position + * + * @var Point + */ + var $position; + + /** + * Hide legend ? + * + * @var bool + */ + var $hide = FALSE; + + /** + * Space between each legend + * + * @var int + */ + var $space = 4; + + /** + * Horizontal alignment + * + * @var int + */ + var $hAlign; + + /** + * Vertical alignment + * + * @var int + */ + var $vAlign; + + /** + * Margin + * + * @var array Array for left, right, top and bottom margins + */ + var $margin; + + /** + * Legend shadow + * + * @var Shadow + */ + var $shadow; + + /** + * Legend border + * + * @var Border + */ + var $border; + + /** + * Line legend + * + * @var int + */ + + + /** + * Color/Gradient background legend + * + * @var int + */ + + + /** + * Use marks and line as legend + * + * @var int + */ + + + /** + * Use marks as legend + * + * @var int + */ + + + /** + * Right side model + * + * @var int + */ + + + /** + * Bottom side model + * + * @var int + */ + + + /** + * Build the legend + * + * @param int $model Legend model + */ + function awLegend($model = LEGEND_MODEL_RIGHT) { + + $this->shadow = new awShadow(SHADOW_LEFT_BOTTOM); + $this->border = new awBorder; + + $this->textMargin = new awSide(4); + $this->setModel($model); + + } + + /** + * Set a predefined model for the legend + * + * @param int $model + */ + function setModel($model) { + + $this->setBackgroundColor(new awColor(255, 255, 255, 15)); + $this->setPadding(8, 8, 8, 8); + $this->setTextFont(new awFont2); + $this->shadow->setSize(3); + + switch($model) { + + case LEGEND_MODEL_RIGHT : + + $this->setColumns(1); + $this->setAlign(LEGEND_RIGHT, LEGEND_MIDDLE); + $this->setPosition(0.96, 0.50); + + break; + + case LEGEND_MODEL_BOTTOM : + + $this->setRows(1); + $this->setAlign(LEGEND_CENTER, LEGEND_TOP); + $this->setPosition(0.50, 0.92); + + break; + + default : + + $this->setPosition(0.5, 0.5); + + break; + + } + + } + + /** + * Hide legend ? + * + * @param bool $hide TRUE to hide legend, FALSE otherwise + */ + function hide($hide = TRUE) { + $this->hide = (bool)$hide; + } + + /** + * Show legend ? + * + * @param bool $show + */ + function show($show = TRUE) { + $this->hide = (bool)!$show; + } + + + /** + * Add a Legendable object to the legend + * + * @param &$legendable + * @param string $title Legend title + * @param int $type Legend type (default to LEGEND_LINE) + */ + function add(&$legendable, $title, $type = LEGEND_LINE) { + + $legend = array($legendable, $title, $type); + + $this->legends[] = $legend; + + } + + /** + * Change legend padding + * + * @param int $left + * @param int $right + * @param int $top + * @param int $bottom + */ + function setPadding($left, $right, $top, $bottom) { + $this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom); + } + + /** + * Change space between each legend + * + * @param int $space + */ + function setSpace($space) { + $this->space = (int)$space; + } + + /** + * Change alignment + * + * @param int $h Horizontal alignment + * @param int $v Vertical alignment + */ + function setAlign($h = NULL, $v = NULL) { + if($h !== NULL) { + $this->hAlign = (int)$h; + } + if($v !== NULL) { + $this->vAlign = (int)$v; + } + } + + /** + * Change number of columns + * + * @param int $columns + */ + function setColumns($columns) { + $this->rows = NULL; + $this->columns = (int)$columns; + } + + /** + * Change number of rows + * + * @param int $rows + */ + function setRows($rows) { + $this->columns = NULL; + $this->rows = (int)$rows; + } + + /** + * Change legend position + * X and Y positions must be between 0 and 1. + * + * @param float $x + * @param float $y + */ + function setPosition($x = NULL, $y = NULL) { + $x = (is_null($x) and !is_null($this->position)) ? $this->position->x : $x; + $y = (is_null($y) and !is_null($this->position)) ? $this->position->y : $y; + + $this->position = new awPoint($x, $y); + } + + /** + * Get legend position + * + * @return Point + */ + function getPosition() { + return $this->position; + } + + /** + * Change text font + * + * @param &$font + */ + function setTextFont(&$font) { + $this->textFont = $font; + } + + /** + * Change text margin + * + * @param int $left + * @param int $right + */ + function setTextMargin($left, $right) { + $this->textMargin->set($left, $right); + } + + /** + * Change text color + * + * @param $color + */ + function setTextColor($color) { + $this->textColor = $color; + } + + /** + * Change background + * + * @param mixed $background + */ + function setBackground($background) { + $this->background = $background; + } + + /** + * Change background color + * + * @param $color + */ + function setBackgroundColor($color) { + $this->background = $color; + } + + /** + * Change background gradient + * + * @param $gradient + */ + function setBackgroundGradient($gradient) { + $this->background = $gradient; + } + + /** + * Count the number of Legendable objects in the legend + * + * @return int + */ + function count() { + return count($this->legends); + } + + function draw($drawer) { + + if($this->hide) { + return; + } + + $count = $this->count(); + + // No legend to print + if($count === 0) { + return; + } + + // Get text widths and heights of each element of the legend + $widths = array(); + $heights = array(); + $texts = array(); + for($i = 0; $i < $count; $i++) { + list(, $title, ) = $this->legends[$i]; + $text = new awText( + $title, + $this->textFont, + $this->textColor, + 0 + ); + $font = $text->getFont(); + $widths[$i] = $font->getTextWidth($text) + $this->textMargin->left + $this->textMargin->right; + $heights[$i] = $font->getTextHeight($text); + $texts[$i] = $text; + } + + // Maximum height of the font used + $heightMax = array_max($heights); + + // Get number of columns + if($this->columns !== NULL) { + $columns = $this->columns; + } else if($this->rows !== NULL) { + $columns = ceil($count / $this->rows); + } else { + $columns = $count; + } + + // Number of rows + $rows = (int)ceil($count / $columns); + + // Get maximum with of each column + $widthMax = array(); + for($i = 0; $i < $count; $i++) { + // Get column width + $column = $i % $columns; + if(array_key_exists($column, $widthMax) === FALSE) { + $widthMax[$column] = $widths[$i]; + } else { + $widthMax[$column] = max($widthMax[$column], $widths[$i]); + } + } + + $width = $this->padding[0] + $this->padding[1] - $this->space; + for($i = 0; $i < $columns; $i++) { + $width += $this->space + 5 + 10 + $widthMax[$i]; + } + + $height = ($heightMax + $this->space) * $rows - $this->space + $this->padding[2] + $this->padding[3]; + + // Look for legends position + list($x, $y) = $drawer->getSize(); + + $p = new awPoint( + $this->position->x * $x, + $this->position->y * $y + ); + + switch($this->hAlign) { + + case LEGEND_CENTER : + $p->x -= $width / 2; + break; + + case LEGEND_RIGHT : + $p->x -= $width; + break; + + } + + switch($this->vAlign) { + + case LEGEND_MIDDLE : + $p->y -= $height / 2; + break; + + case LEGEND_BOTTOM : + $p->y -= $height; + break; + + } + + // Draw legend shadow + $this->shadow->draw( + $drawer, + $p, + $p->move($width, $height), + SHADOW_OUT + ); + + // Draw legends base + $this->drawBase($drawer, $p, $width, $height); + + // Draw each legend + for($i = 0; $i < $count; $i++) { + + list($component, $title, $type) = $this->legends[$i]; + + $column = $i % $columns; + $row = (int)floor($i / $columns); + + // Get width of all previous columns + $previousColumns = 0; + for($j = 0; $j < $column; $j++) { + $previousColumns += $this->space + 10 + 5 + $widthMax[$j]; + } + + // Draw legend text + $drawer->string( + $texts[$i], + $p->move( + $this->padding[0] + $previousColumns + 10 + 5 + $this->textMargin->left, + $this->padding[2] + $row * ($heightMax + $this->space) + $heightMax / 2 - $heights[$i] / 2 + ) + ); + + // Draw legend icon + switch($type) { + + case LEGEND_LINE : + case LEGEND_MARK : + case LEGEND_MARKONLY : + + // Get vertical position + $x = $this->padding[0] + $previousColumns; + $y = $this->padding[2] + $row * ($heightMax + $this->space) + $heightMax / 2 - $component->getLegendLineThickness(); + + // Draw two lines + if($component->getLegendLineColor() !== NULL) { + + $color = $component->getLegendLineColor(); + + if(is_a($color, 'awColor') and $type !== LEGEND_MARKONLY) { + + $drawer->line( + $color, + new awLine( + $p->move( + $x, // YaPB ?? + $y + $component->getLegendLineThickness() / 2 + ), + $p->move( + $x + 10, + $y + $component->getLegendLineThickness() / 2 + ), + $component->getLegendLineStyle(), + $component->getLegendLineThickness() + ) + ); + + $color->free(); + unset($color); + + } + + } + + if($type === LEGEND_MARK or $type === LEGEND_MARKONLY) { + + $mark = $component->getLegendMark(); + + if($mark !== NULL) { + $mark->draw( + $drawer, + $p->move( + $x + 5.5, + $y + $component->getLegendLineThickness() / 2 + ) + ); + } + + unset($mark); + + } + + break; + + case LEGEND_BACKGROUND : + + // Get vertical position + $x = $this->padding[0] + $previousColumns; + $y = $this->padding[2] + $row * ($heightMax + $this->space) + $heightMax / 2 - 5; + + $from = $p->move( + $x, + $y + ); + + $to = $p->move( + $x + 10, + $y + 10 + ); + + $background = $component->getLegendBackground(); + + if($background !== NULL) { + + $drawer->filledRectangle( + $component->getLegendBackground(), + new awLine($from, $to) + ); + + // Draw rectangle border + $this->border->rectangle( + $drawer, + $from->move(0, 0), + $to->move(0, 0) + ); + + } + + unset($background, $from, $to); + + break; + + } + + } + + } + + function drawBase($drawer, $p, $width, $height) { + + $this->border->rectangle( + $drawer, + $p, + $p->move($width, $height) + ); + + $size = $this->border->visible() ? 1 : 0; + + $drawer->filledRectangle( + $this->background, + new awLine( + $p->move($size, $size), + $p->move($width - $size, $height - $size) + ) + ); + + } + +} + +registerClass('Legend'); + +/** + * You can add a legend to components which implements this interface + * + * @package Artichow + */ + + +registerInterface('Legendable'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Mark.class.php b/external-libs/Artichow/php4/inc/Mark.class.php new file mode 100644 index 00000000000..c88756f7a43 --- /dev/null +++ b/external-libs/Artichow/php4/inc/Mark.class.php @@ -0,0 +1,335 @@ + */ + +define("MARK_CIRCLE", 1); +define("MARK_SQUARE", 2); +define("MARK_IMAGE", 3); +define("MARK_STAR", 4); +define("MARK_PAPERCLIP", 5); +define("MARK_BOOK", 6); + +/* */ + +/** + * Draw marks + * + * @package Artichow + */ +class awMark { + + /** + * Circle mark + * + * @var int + */ + + + /** + * Quare mark + * + * @var int + */ + + + /** + * Image mark + * + * @var int + */ + + + /** + * Star mark + * + * @var int + */ + + + /** + * Paperclip mark + * + * @var int + */ + + + /** + * Book mark + * + * @var int + */ + + + /** + * Must marks be hidden ? + * + * @var bool + */ + var $hide; + + /** + * Mark type + * + * @var int + */ + var $type; + + /** + * Mark size + * + * @var int + */ + var $size = 8; + + /** + * Fill mark + * + * @var Color, Gradient + */ + var $fill; + + /** + * Mark image + * + * @var Image + */ + var $image; + + /** + * To draw marks + * + * @var Drawer + */ + var $drawer; + + /** + * Move position from this vector + * + * @var Point + */ + var $move; + + /** + * Marks border + * + * @var Border + */ + var $border; + + /** + * Build the mark + */ + function awMark() { + + $this->fill = new awColor(255, 0, 0, 0); + $this->border = new awBorder; + $this->border->hide(); + + $this->move = new awPoint(0, 0); + + } + + /** + * Change mark position + * + * @param int $x Add this interval to X coord + * @param int $y Add this interval to Y coord + */ + function move($x, $y) { + + $this->move = $this->move->move($x, $y); + + } + + /** + * Hide marks ? + * + * @param bool $hide TRUE to hide marks, FALSE otherwise + */ + function hide($hide = TRUE) { + $this->hide = (bool)$hide; + } + + /** + * Show marks ? + * + * @param bool $show + */ + function show($show = TRUE) { + $this->hide = (bool)!$show; + } + + /** + * Change mark type + * + * @param int $size Size in pixels + */ + function setSize($size) { + $this->size = (int)$size; + } + + /** + * Change mark type + * + * @param int $type New mark type + * @param int $size Mark size (can be NULL) + */ + function setType($type, $size = NULL) { + $this->type = (int)$type; + if($size !== NULL) { + $this->setSize($size); + } + } + + /** + * Fill the mark with a color or a gradient + * + * @param mixed $fill A color or a gradient + */ + function setFill($fill) { + if(is_a($fill, 'awColor') or is_a($fill, 'awGradient')) { + $this->fill = $fill; + } + } + + /** + * Set an image + * Only for MARK_IMAGE type. + * + * @param Image An image + */ + function setImage(&$image) { + $this->image = $image; + } + + /** + * Draw the mark + * + * @param $drawer + * @param $point Mark center + */ + function draw($drawer, $point) { + + // Hide marks ? + if($this->hide) { + return; + } + + // Check if we can print marks + if($this->type !== NULL) { + + $this->drawer = $drawer; + $realPoint = $this->move->move($point->x, $point->y); + + switch($this->type) { + + case MARK_CIRCLE : + $this->drawCircle($realPoint); + break; + + case MARK_SQUARE : + $this->drawSquare($realPoint); + break; + + case MARK_IMAGE : + $this->drawImage($realPoint); + break; + + case MARK_STAR : + $this->changeType('star'); + $this->draw($drawer, $point); + break; + + case MARK_PAPERCLIP : + $this->changeType('paperclip'); + $this->draw($drawer, $point); + break; + + case MARK_BOOK : + $this->changeType('book'); + $this->draw($drawer, $point); + break; + + } + + } + + } + + function changeType($image) { + $this->setType(MARK_IMAGE); + $this->setImage(new awFileImage(ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.$image.'.png')); + } + + function drawCircle($point) { + + $this->drawer->filledEllipse( + $this->fill, + $point, + $this->size, $this->size + ); + + $this->border->ellipse( + $this->drawer, + $point, + $this->size, $this->size + ); + + } + + function drawSquare($point) { + + list($x, $y) = $point->getLocation(); + + $x1 = (int)($x - $this->size / 2); + $x2 = $x1 + $this->size; + $y1 = (int)($y - $this->size / 2); + $y2 = $y1 + $this->size; + + $this->border->rectangle($this->drawer, new awPoint($x1, $y1), new awPoint($x2, $y2)); + + $size = $this->border->visible() ? 1 : 0; + + $this->drawer->filledRectangle( + $this->fill, + new awLine( + new awPoint($x1 + $size, $y1 + $size), + new awPoint($x2 - $size, $y2 - $size) + ) + ); + + } + + function drawImage($point) { + + if(is_a($this->image, 'awImage')) { + + $width = $this->image->width; + $height = $this->image->height; + + list($x, $y) = $point->getLocation(); + + $x1 = (int)($x - $width / 2); + $x2 = $x1 + $width; + $y1 = (int)($y - $width / 2); + $y2 = $y1 + $height; + + $this->border->rectangle($this->drawer, new awPoint($x1 - 1, $y1 - 1), new awPoint($x2 + 1, $y2 + 1)); + + $this->drawer->copyImage($this->image, new awPoint($x1, $y1), new awPoint($x2, $y2)); + + } + + } + +} + +registerClass('Mark'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Math.class.php b/external-libs/Artichow/php4/inc/Math.class.php new file mode 100644 index 00000000000..00716756b76 --- /dev/null +++ b/external-libs/Artichow/php4/inc/Math.class.php @@ -0,0 +1,492 @@ +style = (int)$style; + } + + /** + * Return shape style + * + * @return int + */ + function getStyle() { + return $this->style; + } + + /** + * Change shape thickness + * + * @param int $thickness Shape thickness in pixels + */ + function setThickness($thickness) { + $this->thickness = (int)$thickness; + } + + /** + * Return shape thickness + * + * @return int + */ + function getThickness() { + return $this->thickness; + } + + /** + * Hide the shape + * + * @param bool $hide + */ + function hide($hide) { + $this->hide = (bool)$hide; + } + + /** + * Show the shape + * + * @param bool $shape + */ + function show($shape) { + $this->hide = (bool)!$shape; + } + + /** + * Is the line hidden ? + * + * @return bool + */ + function isHidden() { + return $this->hide; + } + +} + +registerClass('Shape', TRUE); + +/** + * Describe a point + * + * @package Artichow + */ +class awPoint extends awShape { + + /** + * X coord + * + * @var float + */ + var $x; + + /** + * Y coord + * + * @var float + */ + var $y; + + /** + * Build a new awpoint + * + * @param float $x + * @param float $y + */ + function awPoint($x, $y) { + + $this->setLocation($x, $y); + + } + + /** + * Change X value + * + * @param float $x + */ + function setX($x) { + $this->x = (float)$x; + } + + /** + * Change Y value + * + * @param float $y + */ + function setY($y) { + $this->y = (float)$y; + } + + /** + * Change point location + * + * @param float $x + * @param float $y + */ + function setLocation($x, $y) { + $this->setX($x); + $this->setY($y); + } + + /** + * Get point location + * + * @param array Point location + */ + function getLocation() { + return array($this->x, $this->y); + } + + /** + * Get distance to another point + * + * @param $p A point + * @return float + */ + function getDistance($p) { + + return sqrt(pow($p->x - $this->x, 2) + pow($p->y - $this->y, 2)); + + } + + /** + * Move the point to another location + * + * @param Point A Point with the new awlocation + */ + function move($x, $y) { + + return new awPoint( + $this->x + $x, + $this->y + $y + ); + + } + +} + +registerClass('Point'); + +/* */ + +define("LINE_SOLID", 1); +define("LINE_DOTTED", 2); +define("LINE_DASHED", 3); + +/* */ + +/** + * Describe a line + * + * @package Artichow + */ +class awLine extends awShape { + + /** + * Line first point + * + * @param Point + */ + var $p1; + + /** + * Line second point + * + * @param Point + */ + var $p2; + + /** + * Build a new awline + * + * @param $p1 First point + * @param $p2 Second point + * @param int $type Style of line (default to solid) + * @param int $thickness Line thickness (default to 1) + */ + function awLine($p1 = NULL, $p2 = NULL, $type = LINE_SOLID, $thickness = 1) { + + $this->setLocation($p1, $p2); + $this->setStyle($type); + $this->setThickness($thickness); + + } + + /** + * Build a line from 4 coords + * + * @param int $x1 Left position + * @param int $y1 Top position + * @param int $x2 Right position + * @param int $y2 Bottom position + */ + function build($x1, $y1, $x2, $y2) { + + return new awLine( + new awPoint($x1, $y1), + new awPoint($x2, $y2) + ); + + } + + /** + * Change X values of the line + * + * @param int $x1 Begin value + * @param int $x2 End value + */ + function setX($x1, $x2) { + $this->p1->setX($x1); + $this->p2->setX($x2); + } + + /** + * Change Y values of the line + * + * @param int $y1 Begin value + * @param int $y2 End value + */ + function setY($y1, $y2) { + $this->p1->setY($y1); + $this->p2->setY($y2); + } + + /** + * Change line location + * + * @param $p1 First point + * @param $p2 Second point + */ + function setLocation($p1, $p2) { + if(is_null($p1) or is_a($p1, 'awPoint')) { + $this->p1 = $p1; + } + if(is_null($p2) or is_a($p2, 'awPoint')) { + $this->p2 = $p2; + } + } + + /** + * Get line location + * + * @param array Line location + */ + function getLocation() { + return array($this->p1, $this->p2); + } + + /** + * Get the line size + * + * @return float + */ + function getSize() { + + $square = pow($this->p2->x - $this->p1->x, 2) + pow($this->p2->y - $this->p1->y, 2); + return sqrt($square); + + } + + /** + * Test if the line can be considered as a point + * + * @return bool + */ + function isPoint() { + return ($this->p1->x === $this->p2->x and $this->p1->y === $this->p2->y); + } + + /** + * Test if the line is a vertical line + * + * @return bool + */ + function isVertical() { + return ($this->p1->x === $this->p2->x); + } + + /** + * Test if the line is an horizontal line + * + * @return bool + */ + function isHorizontal() { + return ($this->p1->y === $this->p2->y); + } + +} + +registerClass('Line'); + +/** + * A vector is a type of line + * The sense of the vector goes from $p1 to $p2. + * + * @package Artichow + */ +class awVector extends awLine { + + /** + * Get vector angle in radians + * + * @return float + */ + function getAngle() { + + if($this->isPoint()) { + return 0.0; + } + + $size = $this->getSize(); + + $width = ($this->p2->x - $this->p1->x); + $height = ($this->p2->y - $this->p1->y) * -1; + + if($width >= 0 and $height >= 0) { + return acos($width / $size); + } else if($width <= 0 and $height >= 0) { + return acos($width / $size); + } else { + $height *= -1; + if($width >= 0 and $height >= 0) { + return 2 * M_PI - acos($width / $size); + } else if($width <= 0 and $height >= 0) { + return 2 * M_PI - acos($width / $size); + } + } + + } + +} + +registerClass('Vector'); + +/* */ + +define("POLYGON_SOLID", 1); +define("POLYGON_DOTTED", 2); +define("POLYGON_DASHED", 3); + +/* */ + +/** + * Describe a polygon + * + * @package Artichow + */ +class awPolygon extends awShape { + + /** + * Polygon points + * + * @var array + */ + var $points = array(); + + /** + * Set a point in the polygon + * + * @param int $pos Point position + * @param $point + */ + function set($pos, $point) { + if(is_null($point) or is_a($point, 'awPoint')) { + $this->points[$pos] = $point; + } + } + + /** + * Add a point at the end of the polygon + * + * @param $point + */ + function append($point) { + if(is_null($point) or is_a($point, 'awPoint')) { + $this->points[] = $point; + } + } + + /** + * Get a point at a position in the polygon + * + * @param int $pos Point position + * @return Point + */ + function get($pos) { + return $this->points[$pos]; + } + + /** + * Count number of points in the polygon + * + * @return int + */ + function count() { + return count($this->points); + } + + /** + * Returns all points in the polygon + * + * @return array + */ + function all() { + return $this->points; + } + +} + +registerClass('Polygon'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Shadow.class.php b/external-libs/Artichow/php4/inc/Shadow.class.php new file mode 100644 index 00000000000..d117e83905b --- /dev/null +++ b/external-libs/Artichow/php4/inc/Shadow.class.php @@ -0,0 +1,415 @@ + */ + +define("SHADOW_LEFT_TOP", 1); +define("SHADOW_LEFT_BOTTOM", 2); +define("SHADOW_RIGHT_TOP", 3); +define("SHADOW_RIGHT_BOTTOM", 4); + +define("SHADOW_IN", 1); +define("SHADOW_OUT", 2); + +/* */ + +/** + * Draw shadows + * + */ +class awShadow { + + /** + * Shadow on left and top sides + * + * @var int + */ + + + /** + * Shadow on left and bottom sides + * + * @var int + */ + + + + /** + * Shadow on right and top sides + * + * @var int + */ + + + /** + * Shadow on right and bottom sides + * + * @var int + */ + + + /** + * In mode + * + * @var int + */ + + + /** + * Out mode + * + * @var int + */ + + + /** + * Shadow size + * + * @var int + */ + var $size = 0; + + /** + * Hide shadow ? + * + * @var bool + */ + var $hide = FALSE; + + /** + * Shadow color + * + * @var Color + */ + var $color; + + /** + * Shadow position + * + * @var int + */ + var $position; + + /** + * Smooth shadow ? + * + * @var bool + */ + var $smooth = FALSE; + + /** + * Shadow constructor + * + * @param int $position Shadow position + */ + function awShadow($position) { + $this->setPosition($position); + } + + /** + * Hide shadow ? + * + * @param bool $hide + */ + function hide($hide = TRUE) { + $this->hide = (bool)$hide; + } + + /** + * Show shadow ? + * + * @param bool $show + */ + function show($show = TRUE) { + $this->hide = (bool)!$show; + } + + /** + * Change shadow size + * + * @param int $size + * @param bool $smooth Smooth the shadow (facultative argument) + */ + function setSize($size, $smooth = NULL) { + $this->size = (int)$size; + if($smooth !== NULL) { + $this->smooth($smooth); + } + } + + /** + * Change shadow color + * + * @param $color + */ + function setColor($color) { + $this->color = $color; + } + + /** + * Change shadow position + * + * @param int $position + */ + function setPosition($position) { + $this->position = (int)$position; + } + + /** + * Smooth shadow ? + * + * @param bool $smooth + */ + function smooth($smooth) { + $this->smooth = (bool)$smooth; + } + + /** + * Get the space taken by the shadow + * + * @return Side + */ + function getSpace() { + + return new awSide( + ($this->position === SHADOW_LEFT_TOP or $this->position === SHADOW_LEFT_BOTTOM) ? $this->size : 0, + ($this->position === SHADOW_RIGHT_TOP or $this->position === SHADOW_RIGHT_BOTTOM) ? $this->size : 0, + ($this->position === SHADOW_LEFT_TOP or $this->position === SHADOW_RIGHT_TOP) ? $this->size : 0, + ($this->position === SHADOW_LEFT_BOTTOM or $this->position === SHADOW_RIGHT_BOTTOM) ? $this->size : 0 + ); + + } + + /** + * Draw shadow + * + * @param $drawer + * @param $p1 Top-left point + * @param $p2 Right-bottom point + * @param int Drawing mode + */ + function draw($drawer, $p1, $p2, $mode) { + + if($this->hide) { + return; + } + + if($this->size <= 0) { + return; + } + + + + $color = (is_a($this->color, 'awColor')) ? $this->color : new awColor(125, 125, 125); + + switch($this->position) { + + case SHADOW_RIGHT_BOTTOM : + + if($mode === SHADOW_OUT) { + $t1 = $p1->move(0, 0); + $t2 = $p2->move($this->size + 1, $this->size + 1); + } else { // PHP 4 compatibility + $t1 = $p1->move(0, 0); + $t2 = $p2->move(0, 0); + } + + $width = $t2->x - $t1->x; + $height = $t2->y - $t1->y; + + $drawer->setAbsPosition($t1->x + $drawer->x, $t1->y + $drawer->y); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint($width - $this->size, $this->size), + new awPoint($width - 1, $height - 1) + ) + ); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint($this->size, $height - $this->size), + new awPoint($width - $this->size - 1, $height - 1) + ) + ); + + $this->smoothPast($drawer, $color, $width, $height); + + break; + + case SHADOW_LEFT_TOP : + + if($mode === SHADOW_OUT) { + $t1 = $p1->move(- $this->size, - $this->size); + $t2 = $p2->move(0, 0); + } else { // PHP 4 compatibility + $t1 = $p1->move(0, 0); + $t2 = $p2->move(0, 0); + } + + $width = $t2->x - $t1->x; + $height = $t2->y - $t1->y; + + $drawer->setAbsPosition($t1->x + $drawer->x, $t1->y + $drawer->y); + + $height = max($height + 1, $this->size); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint(0, 0), + new awPoint($this->size - 1, $height - $this->size - 1) + ) + ); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint($this->size, 0), + new awPoint($width - $this->size - 1, $this->size - 1) + ) + ); + + $this->smoothPast($drawer, $color, $width, $height); + + break; + + case SHADOW_RIGHT_TOP : + + if($mode === SHADOW_OUT) { + $t1 = $p1->move(0, - $this->size); + $t2 = $p2->move($this->size + 1, 0); + } else { // PHP 4 compatibility + $t1 = $p1->move(0, 0); + $t2 = $p2->move(0, 0); + } + + $width = $t2->x - $t1->x; + $height = $t2->y - $t1->y; + + $drawer->setAbsPosition($t1->x + $drawer->x, $t1->y + $drawer->y); + + $height = max($height + 1, $this->size); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint($width - $this->size, 0), + new awPoint($width - 1, $height - $this->size - 1) + ) + ); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint($this->size, 0), + new awPoint($width - $this->size - 1, $this->size - 1) + ) + ); + + $this->smoothFuture($drawer, $color, $width, $height); + + break; + + case SHADOW_LEFT_BOTTOM : + + if($mode === SHADOW_OUT) { + $t1 = $p1->move(- $this->size, 0); + $t2 = $p2->move(0, $this->size + 1); + } else { // PHP 4 compatibility + $t1 = $p1->move(0, 0); + $t2 = $p2->move(0, 0); + } + + $width = $t2->x - $t1->x; + $height = $t2->y - $t1->y; + + $drawer->setAbsPosition($t1->x + $drawer->x, $t1->y + $drawer->y); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint(0, $this->size), + new awPoint($this->size - 1, $height - 1) + ) + ); + + $drawer->filledRectangle( + $color, + new awLine( + new awPoint($this->size, $height - $this->size), + new awPoint($width - $this->size - 1, $height - 1) + ) + ); + + $this->smoothFuture($drawer, $color, $width, $height); + + break; + + } + + } + + function smoothPast($drawer, $color, $width, $height) { + + if($this->smooth) { + + for($i = 0; $i < $this->size; $i++) { + for($j = 0; $j <= $i; $j++) { + $drawer->point( + $color, + new awPoint($i, $j + $height - $this->size) + ); + } + } + + for($i = 0; $i < $this->size; $i++) { + for($j = 0; $j <= $i; $j++) { + $drawer->point( + $color, + new awPoint($width - $this->size + $j, $i) + ); + } + } + + } + + } + + function smoothFuture($drawer, $color, $width, $height) { + + if($this->smooth) { + + for($i = 0; $i < $this->size; $i++) { + for($j = 0; $j <= $i; $j++) { + $drawer->point( + $color, + new awPoint($i, $this->size - $j - 1) + ); + } + } + + for($i = 0; $i < $this->size; $i++) { + for($j = 0; $j <= $i; $j++) { + $drawer->point( + $color, + new awPoint($width - $this->size + $j, $height - $i - 1) + ); + } + } + + } + } + +} + +registerClass('Shadow'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Text.class.php b/external-libs/Artichow/php4/inc/Text.class.php new file mode 100644 index 00000000000..71d9dbe3521 --- /dev/null +++ b/external-libs/Artichow/php4/inc/Text.class.php @@ -0,0 +1,217 @@ +setText($text); + $this->setFont($font); + + // Set default color to black + if($color === NULL) { + $color = new awColor(0, 0, 0); + } + + $this->setColor($color); + $this->setAngle($angle); + + $this->border = new awBorder; + $this->border->hide(); + + } + + /** + * Get text + * + * @return string + */ + function getText() { + return $this->text; + } + + /** + * Change text + * + * @param string $text New text + */ + function setText($text) { + $this->text = (string)$text; + } + + /** + * Change text font + * + * @param Font + */ + function setFont(&$font) { + $this->font = $font; + } + + /** + * Get text font + * + * @return int + */ + function getFont() { + return $this->font; + } + + /** + * Change text angle + * + * @param int + */ + function setAngle($angle) { + $this->angle = (int)$angle; + } + + /** + * Get text angle + * + * @return int + */ + function getAngle() { + return $this->angle; + } + + /** + * Change text color + * + * @param Color + */ + function setColor($color) { + $this->color = $color; + } + + /** + * Get text color + * + * @return Color + */ + function getColor() { + return $this->color; + } + + /** + * Change text background color + * + * @param $color + */ + function setBackgroundColor($color) { + $this->background = $color; + } + + /** + * Change text background gradient + * + * @param $gradient + */ + function setBackgroundGradient($gradient) { + $this->background = $gradient; + } + + /** + * Get text background + * + * @return Color, Gradient + */ + function getBackground() { + return $this->background; + } + + /** + * Change padding + * + * @param int $left Left padding + * @param int $right Right padding + * @param int $top Top padding + * @param int $bottom Bottom padding + */ + function setPadding($left, $right, $top, $bottom) { + $this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom); + } + + /** + * Get current padding + * + * @return array + */ + function getPadding() { + return $this->padding; + } + +} + +registerClass('Text'); +?> diff --git a/external-libs/Artichow/php4/inc/Tick.class.php b/external-libs/Artichow/php4/inc/Tick.class.php new file mode 100644 index 00000000000..468a081cf8e --- /dev/null +++ b/external-libs/Artichow/php4/inc/Tick.class.php @@ -0,0 +1,349 @@ + */ + +define("TICK_IN", 0); +define("TICK_OUT", 1); +define("TICK_IN_OUT", 2); + +/* */ + +/** + * Handle ticks + * + * @package Artichow + */ +class awTick { + + /** + * Ticks style + * + * @var int + */ + var $style = TICK_IN; + + /** + * Ticks size + * + * @var int + */ + var $size; + + /** + * Ticks color + * + * @var Color + */ + var $color; + + /** + * Ticks number + * + * @var int + */ + var $number; + + /** + * Ticks number by other tick + * + * @var array + */ + var $numberByTick; + + /** + * Ticks interval + * + * @var int + */ + var $interval = 1; + + /** + * Hide ticks + * + * @var bool + */ + var $hide = FALSE; + + /** + * Hide first tick + * + * @var bool + */ + var $hideFirst = FALSE; + + /** + * Hide last tick + * + * @var bool + */ + var $hideLast = FALSE; + + /** + * In mode + * + * @param int + */ + + + /** + * Out mode + * + * @param int + */ + + + /** + * In and out mode + * + * @param int + */ + + + /** + * Build the ticks + * + * @param int $number Number of ticks + * @param int $size Ticks size + */ + function awTick($number, $size) { + + $this->setSize($size); + $this->setNumber($number); + $this->setColor(new awBlack); + $this->style = TICK_IN; + + } + + /** + * Change ticks style + * + * @param int $style + */ + function setStyle($style) { + $this->style = (int)$style; + } + + /** + * Get ticks style + * + * @return int + */ + function getStyle() { + return $this->style; + } + + /** + * Change ticks color + * + * @param $color + */ + function setColor($color) { + $this->color = $color; + } + + /** + * Change ticks size + * + * @param int $size + */ + function setSize($size) { + $this->size = (int)$size; + } + + /** + * Change interval of ticks + * + * @param int $interval + */ + function setInterval($interval) { + $this->interval = (int)$interval; + } + + /** + * Get interval between each tick + * + * @return int + */ + function getInterval() { + return $this->interval; + } + + /** + * Change number of ticks + * + * @param int $number + */ + function setNumber($number) { + $this->number = (int)$number; + } + + /** + * Get number of ticks + * + * @return int + */ + function getNumber() { + return $this->number; + } + + /** + * Change number of ticks relative to others ticks + * + * @param &$tick Ticks reference + * @param int $number Number of ticks + */ + function setNumberByTick(&$tick, $number) { + + $this->numberByTick = array(&$tick, (int)$number); + + } + + /** + * Hide ticks + * + * @param bool $hide + */ + function hide($hide) { + $this->hide = (bool)$hide; + } + + /** + * Hide first tick + * + * @param bool $hide + */ + function hideFirst($hide) { + $this->hideFirst = (bool)$hide; + } + + /** + * Hide last tick + * + * @param bool $hide + */ + function hideLast($hide) { + $this->hideLast = (bool)$hide; + } + + /** + * Draw ticks on a vector + * + * @param $drawer A drawer + * @param &$vector A vector + */ + function draw($drawer, &$vector) { + + if($this->numberByTick !== NULL) { + list($tick, $number) = $this->numberByTick; + $this->number = 1 + ($tick->getNumber() - 1) * ($number + 1); + $this->interval = $tick->getInterval(); + } + + if($this->number < 2 or $this->hide) { + return; + } + + $angle = $vector->getAngle(); + // echo "INIT:".$angle."
"; + switch($this->style) { + + case TICK_IN : + $this->drawTicks($drawer, $vector, NULL, $angle + M_PI / 2); + break; + + case TICK_OUT : + $this->drawTicks($drawer, $vector, $angle + 3 * M_PI / 2, NULL); + break; + + default : + $this->drawTicks($drawer, $vector, $angle + M_PI / 2, $angle + 3 * M_PI / 2); + break; + + } + + } + + function drawTicks($drawer, &$vector, $from, $to) { + + // Draw last tick + if($this->hideLast === FALSE) { + + //echo ''; + if(($this->number - 1) % $this->interval === 0) { + $this->drawTick($drawer, $vector->p2, $from, $to); + } + //echo ''; + + } + + $number = $this->number - 1; + $size = $vector->getSize(); + + // Get tick increment in pixels + $inc = $size / $number; + + // Check if we must hide the first tick + $start = $this->hideFirst ? $inc : 0; + $stop = $inc * $number; + + $position = 0; + + for($i = $start; round($i, 6) < $stop; $i += $inc) { + + if($position % $this->interval === 0) { + $p = $vector->p1->move( + round($i * cos($vector->getAngle()), 6), + round($i * sin($vector->getAngle() * -1), 6) + ); + $this->drawTick($drawer, $p, $from, $to); + } + + $position++; + + } + //echo '

'; + } + + function drawTick($drawer, $p, $from, $to) { +// echo $this->size.':'.$angle.'|'.cos($angle).'/'; + // The round avoid some errors in the calcul + // For example, 12.00000008575245 becomes 12 + $p1 = $p; + $p2 = $p; + + if($from !== NULL) { + $p1 = $p1->move( + round($this->size * cos($from), 6), + round($this->size * sin($from) * -1, 6) + ); + } + + if($to !== NULL) { + $p2 = $p2->move( + round($this->size * cos($to), 6), + round($this->size * sin($to) * -1, 6) + ); + } + //echo $p1->x.':'.$p2->x.'('.$p1->y.':'.$p2->y.')'.'/'; + $vector = new awVector( + $p1, $p2 + ); + + $drawer->line( + $this->color, + $vector + ); + + } + +} + +registerClass('Tick'); +?> \ No newline at end of file diff --git a/external-libs/Artichow/php4/inc/Tools.class.php b/external-libs/Artichow/php4/inc/Tools.class.php new file mode 100644 index 00000000000..bdcf36d24bf --- /dev/null +++ b/external-libs/Artichow/php4/inc/Tools.class.php @@ -0,0 +1,121 @@ +set($left, $right, $top, $bottom); + } + + + /** + * Change side values + * + * @param mixed $left + * @param mixed $right + * @param mixed $top + * @param mixed $bottom + */ + function set($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) { + + if($left !== NULL) { + $this->left = (float)$left; + } + if($right !== NULL) { + $this->right = (float)$right; + } + if($top !== NULL) { + $this->top = (float)$top; + } + if($bottom !== NULL) { + $this->bottom = (float)$bottom; + } + + } + + + /** + * Add values to each side + * + * @param mixed $left + * @param mixed $right + * @param mixed $top + * @param mixed $bottom + */ + function add($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) { + + if($left !== NULL) { + $this->left += (float)$left; + } + if($right !== NULL) { + $this->right += (float)$right; + } + if($top !== NULL) { + $this->top += (float)$top; + } + if($bottom !== NULL) { + $this->bottom += (float)$bottom; + } + + } + +} + +registerClass('Side'); +?> \ No newline at end of file