New file |
0,0 → 1,606 |
<?php |
/* |
* This work is hereby released into the Public Domain. |
* To view a copy of the public domain dedication, |
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to |
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. |
* |
*/ |
|
|
if(is_file(dirname(__FILE__)."/Artichow.cfg.php")) { // For PHP 4+5 version |
require_once dirname(__FILE__)."/Artichow.cfg.php"; |
} |
|
|
|
|
/* |
* Register a class with the prefix in configuration file |
*/ |
function registerClass($class, $abstract = FALSE) { |
|
if(ARTICHOW_PREFIX === 'aw') { |
return; |
} |
|
|
if($abstract) { |
$abstract = 'abstract'; |
} else { |
$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; |
} |
|
|
eval("interface ".ARTICHOW_PREFIX.$interface." extends aw".$interface." { }"); |
|
|
} |
|
// Some useful files |
require_once ARTICHOW."/Component.class.php"; |
|
require_once ARTICHOW."/inc/Grid.class.php"; |
require_once ARTICHOW."/inc/Tools.class.php"; |
require_once ARTICHOW."/inc/Driver.class.php"; |
require_once ARTICHOW."/inc/Math.class.php"; |
require_once ARTICHOW."/inc/Tick.class.php"; |
require_once ARTICHOW."/inc/Axis.class.php"; |
require_once ARTICHOW."/inc/Legend.class.php"; |
require_once ARTICHOW."/inc/Mark.class.php"; |
require_once ARTICHOW."/inc/Label.class.php"; |
require_once ARTICHOW."/inc/Text.class.php"; |
require_once ARTICHOW."/inc/Color.class.php"; |
require_once ARTICHOW."/inc/Font.class.php"; |
require_once ARTICHOW."/inc/Gradient.class.php"; |
require_once ARTICHOW."/inc/Shadow.class.php"; |
require_once ARTICHOW."/inc/Border.class.php"; |
|
require_once ARTICHOW."/common.php"; |
|
/** |
* An image for a graph |
* |
* @package Artichow |
*/ |
class awImage { |
|
/** |
* Graph width |
* |
* @var int |
*/ |
public $width; |
|
/** |
* Graph height |
* |
* @var int |
*/ |
public $height; |
|
/** |
* Use anti-aliasing ? |
* |
* @var bool |
*/ |
protected $antiAliasing = FALSE; |
|
/** |
* Image format |
* |
* @var int |
*/ |
protected $format = awImage::PNG; |
|
/** |
* Image background color |
* |
* @var Color |
*/ |
protected $background; |
|
/** |
* GD resource |
* |
* @var resource |
*/ |
protected $resource; |
|
/** |
* A Driver object |
* |
* @var Driver |
*/ |
protected $driver; |
|
/** |
* Driver string |
* |
* @var string |
*/ |
protected $driverString; |
|
/** |
* Shadow |
* |
* @var Shadow |
*/ |
public $shadow; |
|
/** |
* Image border |
* |
* @var Border |
*/ |
public $border; |
|
/** |
* Use JPEG for image |
* |
* @var int |
*/ |
const JPEG = IMG_JPG; |
|
/** |
* Use PNG for image |
* |
* @var int |
*/ |
const PNG = IMG_PNG; |
|
/** |
* Use GIF for image |
* |
* @var int |
*/ |
const GIF = IMG_GIF; |
|
/** |
* Build the image |
*/ |
public function __construct() { |
|
$this->background = new awColor(255, 255, 255); |
$this->shadow = new awShadow(awShadow::RIGHT_BOTTOM); |
$this->border = new awBorder; |
|
} |
|
/** |
* Get driver of the image |
* |
* @param int $w Driver width (from 0 to 1) (default to 1) |
* @param int $h Driver height (from 0 to 1) (default to 1) |
* @param float $x Position on X axis of the center of the driver (default to 0.5) |
* @param float $y Position on Y axis of the center of the driver (default to 0.5) |
* @return Driver |
*/ |
public function getDriver($w = 1, $h = 1, $x = 0.5, $y = 0.5) { |
$this->create(); |
$this->driver->setSize($w, $h); |
$this->driver->setPosition($x, $y); |
return $this->driver; |
} |
|
/** |
* Sets the driver that will be used to draw the graph |
* |
* @param string $driverString |
*/ |
public function setDriver($driverString) { |
$this->driver = $this->selectDriver($driverString); |
|
$this->driver->init($this); |
} |
|
/** |
* Change the image size |
* |
* @var int $width Image width |
* @var int $height Image height |
*/ |
public function setSize($width, $height) { |
|
if($width !== NULL) { |
$this->width = (int)$width; |
} |
if($height !== NULL) { |
$this->height = (int)$height; |
} |
|
} |
|
/** |
* Change image background |
* |
* @param mixed $background |
*/ |
public function setBackground($background) { |
if($background instanceof awColor) { |
$this->setBackgroundColor($background); |
} elseif($background instanceof awGradient) { |
$this->setBackgroundGradient($background); |
} |
} |
|
/** |
* Change image background color |
* |
* @param awColor $color |
*/ |
public function setBackgroundColor(awColor $color) { |
$this->background = $color; |
} |
|
/** |
* Change image background gradient |
* |
* @param awGradient $gradient |
*/ |
public function setBackgroundGradient(awGradient $gradient) { |
$this->background = $gradient; |
} |
|
/** |
* Return image background, whether a Color or a Gradient |
* |
* @return mixed |
*/ |
public function getBackground() { |
return $this->background; |
} |
|
/** |
* Turn antialiasing on or off |
* |
* @var bool $bool |
*/ |
public function setAntiAliasing($bool) { |
$this->antiAliasing = (bool)$bool; |
} |
|
/** |
* Return the antialiasing setting |
* |
* @return bool |
*/ |
public function getAntiAliasing() { |
return $this->antiAliasing; |
} |
|
/** |
* Change image format |
* |
* @var int $format New image format |
*/ |
public function setFormat($format) { |
if($format === awImage::JPEG or $format === awImage::PNG or $format === awImage::GIF) { |
$this->format = $format; |
} |
} |
|
/** |
* Returns the image format as an integer |
* |
* @return unknown |
*/ |
public function getFormat() { |
return $this->format; |
} |
|
/** |
* Returns the image format as a string |
* |
* @return string |
*/ |
public function getFormatString() { |
|
switch($this->format) { |
case awImage::JPEG : |
return 'jpeg'; |
case awImage::PNG : |
return 'png'; |
case awImage::GIF : |
return 'gif'; |
} |
|
} |
|
/** |
* Create a new awimage |
*/ |
public function create() { |
|
if($this->driver === NULL) { |
$driver = $this->selectDriver($this->driverString); |
|
$driver->init($this); |
|
$this->driver = $driver; |
} |
|
} |
|
/** |
* Select the correct driver |
* |
* @param string $driver The desired driver |
* @return mixed |
*/ |
protected function selectDriver($driver) { |
$drivers = array('gd'); |
$driver = strtolower((string)$driver); |
|
if(in_array($driver, $drivers, TRUE)) { |
$string = $driver; |
} else { |
$string = ARTICHOW_DRIVER; |
} |
|
switch ($string) { |
case 'gd': |
require_once ARTICHOW.'/inc/drivers/gd.class.php'; |
$this->driverString = $string; |
return new awGDDriver(); |
|
default: |
// We should never get here, unless the wrong string is used AND the ARTICHOW_DRIVER |
// global has been messed with. |
awImage::drawError('Class Image: Unknown driver type (\''.$string.'\')'); |
break; |
} |
} |
|
/** |
* Draw a component on the image |
* |
* @var awComponent $component A component |
*/ |
public function drawComponent(awComponent $component) { |
|
$shadow = $this->shadow->getSpace(); // Image shadow |
$border = $this->border->visible() ? 1 : 0; // Image border size |
|
$driver = clone $this->driver; |
$driver->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) = $driver->setSize($component->width, $component->height); |
|
// Set component size in pixels |
$component->setAbsSize($width, $height); |
|
} else { |
|
$driver->setAbsSize($component->w, $component->h); |
|
} |
|
if($component->top !== NULL and $component->left !== NULL) { |
$driver->setAbsPosition( |
$border + $shadow->left + $component->left, |
$border + $shadow->top + $component->top |
); |
} else { |
$driver->setPosition($component->x, $component->y); |
} |
|
$driver->movePosition($border + $shadow->left, $border + $shadow->top); |
|
list($x1, $y1, $x2, $y2) = $component->getPosition(); |
|
$component->init($driver); |
|
$component->drawComponent($driver, $x1, $y1, $x2, $y2, $this->antiAliasing); |
$component->drawEnvelope($driver, $x1, $y1, $x2, $y2); |
|
$component->finalize($driver); |
|
} |
|
protected function drawShadow() { |
|
$driver = $this->getDriver(); |
|
$this->shadow->draw( |
$driver, |
new awPoint(0, 0), |
new awPoint($this->width, $this->height), |
awShadow::IN |
); |
|
} |
|
/** |
* Send the image into a file or to the user browser |
* |
*/ |
public function send() { |
$this->driver->send($this); |
} |
|
/** |
* Return the image content as binary data |
* |
*/ |
public function get() { |
return $this->driver->get($this); |
} |
|
/** |
* Send the correct HTTP header according to the image type |
* |
*/ |
public function sendHeaders() { |
|
if(headers_sent() === FALSE) { |
|
switch ($this->driverString) { |
case 'gd' : |
header('Content-type: image/'.$this->getFormatString()); |
break; |
|
} |
|
} |
|
} |
|
|
private static $errorWriting = FALSE; |
|
|
/* |
* Display an error image and exit |
* |
* @param string $message Error message |
*/ |
public static function drawError($message) { |
|
|
if(self::$errorWriting) { |
return; |
} |
|
self::$errorWriting = TRUE; |
|
$message = wordwrap($message, 40, "\n", TRUE); |
|
$width = 400; |
$height = max(100, 40 + 22.5 * (substr_count($message, "\n") + 1)); |
|
$image = new awImage(); |
$image->setSize($width, $height); |
$image->setDriver('gd'); |
|
$driver = $image->getDriver(); |
$driver->init($image); |
|
// Display title |
$driver->filledRectangle( |
new awWhite, |
new awLine( |
new awPoint(0, 0), |
new awPoint($width, $height) |
) |
); |
|
$driver->filledRectangle( |
new awRed, |
new awLine( |
new awPoint(0, 0), |
new awPoint(110, 25) |
) |
); |
|
$text = new awText( |
"Artichow error", |
new awFont3, |
new awWhite, |
0 |
); |
|
$driver->string($text, new awPoint(5, 6)); |
|
// Display red box |
$driver->rectangle( |
new awRed, |
new awLine( |
new awPoint(0, 25), |
new awPoint($width - 90, $height - 1) |
) |
); |
|
// Display error image |
$file = ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.'error.png'; |
|
$imageError = new awFileImage($file); |
$driver->copyImage( |
$imageError, |
new awPoint($width - 81, $height - 81), |
new awPoint($width - 1, $height - 1) |
); |
|
// Draw message |
$text = new awText( |
strip_tags($message), |
new awFont2, |
new awBlack, |
0 |
); |
|
$driver->string($text, new awPoint(10, 40)); |
|
$image->send(); |
|
exit; |
|
} |
|
/* |
* Display an error image located in a file and exit |
* |
* @param string $error Error name |
*/ |
public static function drawErrorFile($error) { |
|
$file = ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.'errors'.DIRECTORY_SEPARATOR.$error.'.png'; |
|
header("Content-Type: image/png"); |
readfile($file); |
exit; |
|
} |
|
} |
|
registerClass('Image'); |
|
|
/** |
* Load an image from a file |
* |
* @package Artichow |
*/ |
class awFileImage extends awImage { |
|
/** |
* Build a new awimage |
* |
* @param string $file Image file name |
*/ |
public function __construct($file) { |
|
$driver = $this->selectDriver($this->driverString); |
|
$driver->initFromFile($this, $file); |
|
$this->driver = $driver; |
|
} |
|
} |
|
registerClass('FileImage'); |
|
?> |