upgrade zend (#1559)
[openemr.git] / vendor / zendframework / zend-barcode / src / Renderer / Image.php
blob8d9e3eeb140028f2c543b5c0d677849040919908
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Barcode\Renderer;
12 use Zend\Barcode\Exception\RendererCreationException;
13 use Zend\Stdlib\ErrorHandler;
15 /**
16 * Class for rendering the barcode as image
18 class Image extends AbstractRenderer
20 /**
21 * List of authorized output format
22 * @var array
24 protected $allowedImageType = [
25 'png',
26 'jpeg',
27 'gif',
30 /**
31 * Image format
32 * @var string
34 protected $imageType = 'png';
36 /**
37 * Resource for the image
38 * @var resource
40 protected $resource = null;
42 /**
43 * Resource for the font and bars color of the image
44 * @var int
46 protected $imageForeColor = null;
48 /**
49 * Resource for the background color of the image
50 * @var int
52 protected $imageBackgroundColor = null;
54 /**
55 * Height of the rendered image wanted by user
56 * @var int
58 protected $userHeight = 0;
60 /**
61 * Width of the rendered image wanted by user
62 * @var int
64 protected $userWidth = 0;
66 /**
67 * Constructor
69 * @param array|\Traversable $options
70 * @throws RendererCreationException
72 public function __construct($options = null)
74 if (! function_exists('gd_info')) {
75 throw new RendererCreationException(__CLASS__ . ' requires the GD extension');
78 parent::__construct($options);
81 /**
82 * Set height of the result image
84 * @param null|int $value
85 * @throws Exception\OutOfRangeException
86 * @return self Provides a fluent interface
88 public function setHeight($value)
90 if (! is_numeric($value) || intval($value) < 0) {
91 throw new Exception\OutOfRangeException(
92 'Image height must be greater than or equals 0'
95 $this->userHeight = intval($value);
96 return $this;
99 /**
100 * Get barcode height
102 * @return int
104 public function getHeight()
106 return $this->userHeight;
110 * Set barcode width
112 * @param mixed $value
113 * @throws Exception\OutOfRangeException
114 * @return self Provides a fluent interface
116 public function setWidth($value)
118 if (! is_numeric($value) || intval($value) < 0) {
119 throw new Exception\OutOfRangeException(
120 'Image width must be greater than or equals 0'
123 $this->userWidth = intval($value);
124 return $this;
128 * Get barcode width
130 * @return int
132 public function getWidth()
134 return $this->userWidth;
138 * Set an image resource to draw the barcode inside
140 * @param resource $image
141 * @return self Provides a fluent interface
142 * @throws Exception\InvalidArgumentException
144 public function setResource($image)
146 if (gettype($image) != 'resource' || get_resource_type($image) != 'gd') {
147 throw new Exception\InvalidArgumentException(
148 'Invalid image resource provided to setResource()'
151 $this->resource = $image;
152 return $this;
156 * Set the image type to produce (png, jpeg, gif)
158 * @param string $value
159 * @throws Exception\InvalidArgumentException
160 * @return self Provides a fluent interface
162 public function setImageType($value)
164 if ($value == 'jpg') {
165 $value = 'jpeg';
168 if (! in_array($value, $this->allowedImageType)) {
169 throw new Exception\InvalidArgumentException(sprintf(
170 'Invalid type "%s" provided to setImageType()',
171 $value
175 $this->imageType = $value;
176 return $this;
180 * Retrieve the image type to produce
182 * @return string
184 public function getImageType()
186 return $this->imageType;
190 * Initialize the image resource
192 * @return void
194 protected function initRenderer()
196 $barcodeWidth = $this->barcode->getWidth(true);
197 $barcodeHeight = $this->barcode->getHeight(true);
199 if (null === $this->resource) {
200 $width = $barcodeWidth;
201 $height = $barcodeHeight;
202 if ($this->userWidth && $this->barcode->getType() != 'error') {
203 $width = $this->userWidth;
205 if ($this->userHeight && $this->barcode->getType() != 'error') {
206 $height = $this->userHeight;
209 // Cast width and height to ensure they are correct type for image
210 // operations
211 $width = (int) $width;
212 $height = (int) $height;
214 $this->resource = imagecreatetruecolor($width, $height);
216 $white = imagecolorallocate($this->resource, 255, 255, 255);
217 imagefilledrectangle($this->resource, 0, 0, $width - 1, $height - 1, $white);
220 $foreColor = $this->barcode->getForeColor();
221 $this->imageForeColor = imagecolorallocate(
222 $this->resource,
223 ($foreColor & 0xFF0000) >> 16,
224 ($foreColor & 0x00FF00) >> 8,
225 $foreColor & 0x0000FF
228 $backgroundColor = $this->barcode->getBackgroundColor();
229 $this->imageBackgroundColor = imagecolorallocate(
230 $this->resource,
231 ($backgroundColor & 0xFF0000) >> 16,
232 ($backgroundColor & 0x00FF00) >> 8,
233 $backgroundColor & 0x0000FF
236 // JPEG does not support transparency, if transparentBackground is true and
237 // image type is JPEG, ignore transparency
238 if ($this->getImageType() != "jpeg" && $this->transparentBackground) {
239 imagecolortransparent($this->resource, $this->imageBackgroundColor);
242 $this->adjustPosition(imagesy($this->resource), imagesx($this->resource));
244 imagefilledrectangle(
245 $this->resource,
246 $this->leftOffset,
247 $this->topOffset,
248 (int) ($this->leftOffset + $barcodeWidth - 1),
249 (int) ($this->topOffset + $barcodeHeight - 1),
250 $this->imageBackgroundColor
255 * Check barcode parameters
257 * @return void
259 protected function checkSpecificParams()
261 $this->checkDimensions();
265 * Check barcode dimensions
267 * @throws Exception\RuntimeException
268 * @return void
270 protected function checkDimensions()
272 if ($this->resource !== null) {
273 if (imagesy($this->resource) < $this->barcode->getHeight(true)) {
274 throw new Exception\RuntimeException(
275 'Barcode is define outside the image (height)'
278 } else {
279 if ($this->userHeight) {
280 $height = $this->barcode->getHeight(true);
281 if ($this->userHeight < $height) {
282 throw new Exception\RuntimeException(sprintf(
283 "Barcode is define outside the image (calculated: '%d', provided: '%d')",
284 $height,
285 $this->userHeight
290 if ($this->resource !== null) {
291 if (imagesx($this->resource) < $this->barcode->getWidth(true)) {
292 throw new Exception\RuntimeException(
293 'Barcode is define outside the image (width)'
296 } else {
297 if ($this->userWidth) {
298 $width = $this->barcode->getWidth(true);
299 if ($this->userWidth < $width) {
300 throw new Exception\RuntimeException(sprintf(
301 "Barcode is define outside the image (calculated: '%d', provided: '%d')",
302 $width,
303 $this->userWidth
311 * Draw and render the barcode with correct headers
313 * @return mixed
315 public function render()
317 $this->draw();
318 header("Content-Type: image/" . $this->imageType);
319 $functionName = 'image' . $this->imageType;
320 $functionName($this->resource);
322 ErrorHandler::start(E_WARNING);
323 imagedestroy($this->resource);
324 ErrorHandler::stop();
328 * Draw a polygon in the image resource
330 * @param array $points
331 * @param int $color
332 * @param bool $filled
334 protected function drawPolygon($points, $color, $filled = true)
336 $newPoints = [$points[0][0] + $this->leftOffset,
337 $points[0][1] + $this->topOffset,
338 $points[1][0] + $this->leftOffset,
339 $points[1][1] + $this->topOffset,
340 $points[2][0] + $this->leftOffset,
341 $points[2][1] + $this->topOffset,
342 $points[3][0] + $this->leftOffset,
343 $points[3][1] + $this->topOffset, ];
345 $allocatedColor = imagecolorallocate(
346 $this->resource,
347 ($color & 0xFF0000) >> 16,
348 ($color & 0x00FF00) >> 8,
349 $color & 0x0000FF
352 if ($filled) {
353 imagefilledpolygon($this->resource, $newPoints, 4, $allocatedColor);
354 } else {
355 imagepolygon($this->resource, $newPoints, 4, $allocatedColor);
360 * Draw a polygon in the image resource
362 * @param string $text
363 * @param float $size
364 * @param array $position
365 * @param string $font
366 * @param int $color
367 * @param string $alignment
368 * @param float|int $orientation
369 * @throws Exception\RuntimeException
371 protected function drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0)
373 $allocatedColor = imagecolorallocate(
374 $this->resource,
375 ($color & 0xFF0000) >> 16,
376 ($color & 0x00FF00) >> 8,
377 $color & 0x0000FF
380 if ($font === null) {
381 $font = 3;
383 $position[0] += $this->leftOffset;
384 $position[1] += $this->topOffset;
386 if (is_numeric($font)) {
387 if ($orientation) {
389 * imagestring() doesn't allow orientation, if orientation
390 * needed: a TTF font is required.
391 * Throwing an exception here, allow to use automaticRenderError
392 * to inform user of the problem instead of simply not drawing
393 * the text
395 throw new Exception\RuntimeException(
396 'No orientation possible with GD internal font'
399 $fontWidth = imagefontwidth($font);
400 $positionY = $position[1] - imagefontheight($font) + 1;
401 switch ($alignment) {
402 case 'left':
403 $positionX = $position[0];
404 break;
405 case 'center':
406 $positionX = $position[0] - ceil(($fontWidth * strlen($text)) / 2);
407 break;
408 case 'right':
409 $positionX = $position[0] - ($fontWidth * strlen($text));
410 break;
412 imagestring($this->resource, $font, $positionX, $positionY, $text, $color);
413 } else {
414 if (! function_exists('imagettfbbox')) {
415 throw new Exception\RuntimeException(
416 'A font was provided, but this instance of PHP does not have TTF (FreeType) support'
420 $box = imagettfbbox($size, 0, $font, $text);
421 switch ($alignment) {
422 case 'left':
423 $width = 0;
424 break;
425 case 'center':
426 $width = ($box[2] - $box[0]) / 2;
427 break;
428 case 'right':
429 $width = ($box[2] - $box[0]);
430 break;
432 imagettftext(
433 $this->resource,
434 $size,
435 $orientation,
436 $position[0] - ($width * cos(pi() * $orientation / 180)),
437 $position[1] + ($width * sin(pi() * $orientation / 180)),
438 $allocatedColor,
439 $font,
440 $text