PageRenderTime 33ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Zend/Barcode/Renderer/Svg.php

https://bitbucket.org/chung/buyforher
PHP | 382 lines | 217 code | 25 blank | 140 comment | 26 complexity | f343fcfe2ae96bc3805913bbe09addf6 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Barcode
  17. * @subpackage Renderer
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Image.php 20366 2010-01-18 03:56:52Z ralph $
  21. */
  22. /** @see Zend_Barcode_Renderer_RendererAbstract*/
  23. #require_once 'Zend/Barcode/Renderer/RendererAbstract.php';
  24. /**
  25. * Class for rendering the barcode as svg
  26. *
  27. * @category Zend
  28. * @package Zend_Barcode
  29. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. */
  32. class Zend_Barcode_Renderer_Svg extends Zend_Barcode_Renderer_RendererAbstract
  33. {
  34. /**
  35. * Resource for the image
  36. * @var DOMDocument
  37. */
  38. protected $_resource = null;
  39. /**
  40. * Root element of the XML structure
  41. * @var DOMElement
  42. */
  43. protected $_rootElement = null;
  44. /**
  45. * Height of the rendered image wanted by user
  46. * @var integer
  47. */
  48. protected $_userHeight = 0;
  49. /**
  50. * Width of the rendered image wanted by user
  51. * @var integer
  52. */
  53. protected $_userWidth = 0;
  54. /**
  55. * Set height of the result image
  56. * @param null|integer $value
  57. * @return Zend_Image_Barcode_Abstract
  58. * @throw Zend_Image_Barcode_Exception
  59. */
  60. public function setHeight($value)
  61. {
  62. if (!is_numeric($value) || intval($value) < 0) {
  63. #require_once 'Zend/Barcode/Renderer/Exception.php';
  64. throw new Zend_Barcode_Renderer_Exception(
  65. 'Svg height must be greater than or equals 0'
  66. );
  67. }
  68. $this->_userHeight = intval($value);
  69. return $this;
  70. }
  71. /**
  72. * Get barcode height
  73. *
  74. * @return int
  75. */
  76. public function getHeight()
  77. {
  78. return $this->_userHeight;
  79. }
  80. /**
  81. * Set barcode width
  82. *
  83. * @param mixed $value
  84. * @return void
  85. */
  86. public function setWidth($value)
  87. {
  88. if (!is_numeric($value) || intval($value) < 0) {
  89. #require_once 'Zend/Barcode/Renderer/Exception.php';
  90. throw new Zend_Barcode_Renderer_Exception(
  91. 'Svg width must be greater than or equals 0'
  92. );
  93. }
  94. $this->_userWidth = intval($value);
  95. return $this;
  96. }
  97. /**
  98. * Get barcode width
  99. *
  100. * @return int
  101. */
  102. public function getWidth()
  103. {
  104. return $this->_userWidth;
  105. }
  106. /**
  107. * Set an image resource to draw the barcode inside
  108. *
  109. * @param DOMDocument $value
  110. * @return Zend_Barcode_Renderer
  111. * @throw Zend_Barcode_Renderer_Exception
  112. */
  113. public function setResource($svg)
  114. {
  115. if (!$svg instanceof DOMDocument) {
  116. #require_once 'Zend/Barcode/Renderer/Exception.php';
  117. throw new Zend_Barcode_Renderer_Exception(
  118. 'Invalid DOMDocument resource provided to setResource()'
  119. );
  120. }
  121. $this->_resource = $svg;
  122. return $this;
  123. }
  124. /**
  125. * Initialize the image resource
  126. *
  127. * @return void
  128. */
  129. protected function _initRenderer()
  130. {
  131. $barcodeWidth = $this->_barcode->getWidth(true);
  132. $barcodeHeight = $this->_barcode->getHeight(true);
  133. $backgroundColor = $this->_barcode->getBackgroundColor();
  134. $imageBackgroundColor = 'rgb(' . implode(', ', array(($backgroundColor & 0xFF0000) >> 16,
  135. ($backgroundColor & 0x00FF00) >> 8,
  136. ($backgroundColor & 0x0000FF))) . ')';
  137. $width = $barcodeWidth;
  138. $height = $barcodeHeight;
  139. if ($this->_userWidth && $this->_barcode->getType() != 'error') {
  140. $width = $this->_userWidth;
  141. }
  142. if ($this->_userHeight && $this->_barcode->getType() != 'error') {
  143. $height = $this->_userHeight;
  144. }
  145. if ($this->_resource === null) {
  146. $this->_resource = new DOMDocument('1.0', 'utf-8');
  147. $this->_resource->formatOutput = true;
  148. $this->_rootElement = $this->_resource->createElement('svg');
  149. $this->_rootElement->setAttribute('xmlns', "http://www.w3.org/2000/svg");
  150. $this->_rootElement->setAttribute('version', '1.1');
  151. $this->_rootElement->setAttribute('width', $width);
  152. $this->_rootElement->setAttribute('height', $height);
  153. $this->_appendRootElement('title',
  154. array(),
  155. "Barcode " . strtoupper($this->_barcode->getType()) . " " . $this->_barcode->getText());
  156. } else {
  157. $this->_readRootElement();
  158. $width = $this->_rootElement->getAttribute('width');
  159. $height = $this->_rootElement->getAttribute('height');
  160. }
  161. $this->_adjustPosition($height, $width);
  162. $this->_appendRootElement('rect',
  163. array('x' => $this->_leftOffset,
  164. 'y' => $this->_topOffset,
  165. 'width' => ($this->_leftOffset + $barcodeWidth - 1),
  166. 'height' => ($this->_topOffset + $barcodeHeight - 1),
  167. 'fill' => $imageBackgroundColor));
  168. }
  169. protected function _readRootElement()
  170. {
  171. if ($this->_resource !== null) {
  172. $this->_rootElement = $this->_resource->documentElement;
  173. }
  174. }
  175. /**
  176. * Append a new DOMElement to the root element
  177. *
  178. * @param string $tagName
  179. * @param array $attributes
  180. * @param string $textContent
  181. */
  182. protected function _appendRootElement($tagName, $attributes = array(), $textContent = null)
  183. {
  184. $newElement = $this->_createElement($tagName, $attributes, $textContent);
  185. $this->_rootElement->appendChild($newElement);
  186. }
  187. /**
  188. * Create DOMElement
  189. *
  190. * @param string $tagName
  191. * @param array $attributes
  192. * @param string $textContent
  193. * @return DOMElement
  194. */
  195. protected function _createElement($tagName, $attributes = array(), $textContent = null)
  196. {
  197. $element = $this->_resource->createElement($tagName);
  198. foreach ($attributes as $k =>$v) {
  199. $element->setAttribute($k, $v);
  200. }
  201. if ($textContent !== null) {
  202. $element->appendChild(new DOMText((string) $textContent));
  203. }
  204. return $element;
  205. }
  206. /**
  207. * Check barcode parameters
  208. *
  209. * @return void
  210. */
  211. protected function _checkParams()
  212. {
  213. $this->_checkDimensions();
  214. }
  215. /**
  216. * Check barcode dimensions
  217. *
  218. * @return void
  219. */
  220. protected function _checkDimensions()
  221. {
  222. if ($this->_resource !== null) {
  223. $this->_readRootElement();
  224. $height = (float) $this->_rootElement->getAttribute('height');
  225. if ($height < $this->_barcode->getHeight(true)) {
  226. #require_once 'Zend/Barcode/Renderer/Exception.php';
  227. throw new Zend_Barcode_Renderer_Exception(
  228. 'Barcode is define outside the image (height)'
  229. );
  230. }
  231. } else {
  232. if ($this->_userHeight) {
  233. $height = $this->_barcode->getHeight(true);
  234. if ($this->_userHeight < $height) {
  235. #require_once 'Zend/Barcode/Renderer/Exception.php';
  236. throw new Zend_Barcode_Renderer_Exception(sprintf(
  237. "Barcode is define outside the image (calculated: '%d', provided: '%d')",
  238. $height,
  239. $this->_userHeight
  240. ));
  241. }
  242. }
  243. }
  244. if ($this->_resource !== null) {
  245. $this->_readRootElement();
  246. $width = $this->_rootElement->getAttribute('width');
  247. if ($width < $this->_barcode->getWidth(true)) {
  248. #require_once 'Zend/Barcode/Renderer/Exception.php';
  249. throw new Zend_Barcode_Renderer_Exception(
  250. 'Barcode is define outside the image (width)'
  251. );
  252. }
  253. } else {
  254. if ($this->_userWidth) {
  255. $width = (float) $this->_barcode->getWidth(true);
  256. if ($this->_userWidth < $width) {
  257. #require_once 'Zend/Barcode/Renderer/Exception.php';
  258. throw new Zend_Barcode_Renderer_Exception(sprintf(
  259. "Barcode is define outside the image (calculated: '%d', provided: '%d')",
  260. $width,
  261. $this->_userWidth
  262. ));
  263. }
  264. }
  265. }
  266. }
  267. /**
  268. * Draw the barcode in the rendering resource
  269. * @return mixed
  270. */
  271. public function draw()
  272. {
  273. parent::draw();
  274. $this->_resource->appendChild($this->_rootElement);
  275. return $this->_resource;
  276. }
  277. /**
  278. * Draw and render the barcode with correct headers
  279. *
  280. * @return mixed
  281. */
  282. public function render()
  283. {
  284. $this->draw();
  285. header("Content-Type: image/svg+xml");
  286. echo $this->_resource->saveXML();
  287. }
  288. /**
  289. * Draw a polygon in the svg resource
  290. *
  291. * @param array $points
  292. * @param integer $color
  293. * @param boolean $filled
  294. */
  295. protected function _drawPolygon($points, $color, $filled = true)
  296. {
  297. $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
  298. ($color & 0x00FF00) >> 8,
  299. ($color & 0x0000FF))) . ')';
  300. $orientation = $this->getBarcode()->getOrientation();
  301. $newPoints = array(
  302. $points[0][0] + $this->_leftOffset,
  303. $points[0][1] + $this->_topOffset,
  304. $points[1][0] + $this->_leftOffset,
  305. $points[1][1] + $this->_topOffset,
  306. $points[2][0] + $this->_leftOffset + cos(-$orientation),
  307. $points[2][1] + $this->_topOffset - sin($orientation),
  308. $points[3][0] + $this->_leftOffset + cos(-$orientation),
  309. $points[3][1] + $this->_topOffset - sin($orientation),
  310. );
  311. $newPoints = implode(' ', $newPoints);
  312. $attributes['points'] = $newPoints;
  313. $attributes['fill'] = $color;
  314. $this->_appendRootElement('polygon', $attributes);
  315. }
  316. /**
  317. * Draw a polygon in the svg resource
  318. *
  319. * @param string $text
  320. * @param float $size
  321. * @param array $position
  322. * @param string $font
  323. * @param integer $color
  324. * @param string $alignment
  325. * @param float $orientation
  326. */
  327. protected function _drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0)
  328. {
  329. $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
  330. ($color & 0x00FF00) >> 8,
  331. ($color & 0x0000FF))) . ')';
  332. $attributes['x'] = $position[0] + $this->_leftOffset;
  333. $attributes['y'] = $position[1] + $this->_topOffset;
  334. //$attributes['font-family'] = $font;
  335. $attributes['color'] = $color;
  336. $attributes['font-size'] = $size * 1.2;
  337. switch ($alignment) {
  338. case 'left':
  339. $textAnchor = 'start';
  340. break;
  341. case 'right':
  342. $textAnchor = 'end';
  343. break;
  344. case 'center':
  345. default:
  346. $textAnchor = 'middle';
  347. }
  348. $attributes['style'] = 'text-anchor: ' . $textAnchor;
  349. $attributes['transform'] = 'rotate('
  350. . (- $orientation)
  351. . ', '
  352. . ($position[0] + $this->_leftOffset)
  353. . ', ' . ($position[1] + $this->_topOffset)
  354. . ')';
  355. $this->_appendRootElement('text', $attributes, $text);
  356. }
  357. }