Abstract.php 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  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_Pdf
  17. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: Style.php 20096 2010-01-06 02:05:09Z bkarwin $
  20. */
  21. require_once 'Zend/Pdf/Canvas/Interface.php';
  22. /** Internally used classes */
  23. require_once 'Zend/Pdf/Element.php';
  24. require_once 'Zend/Pdf/Element/Array.php';
  25. require_once 'Zend/Pdf/Element/String/Binary.php';
  26. require_once 'Zend/Pdf/Element/Boolean.php';
  27. require_once 'Zend/Pdf/Element/Dictionary.php';
  28. require_once 'Zend/Pdf/Element/Name.php';
  29. require_once 'Zend/Pdf/Element/Null.php';
  30. require_once 'Zend/Pdf/Element/Numeric.php';
  31. require_once 'Zend/Pdf/Element/String.php';
  32. /**
  33. * Canvas is an abstract rectangle drawing area which can be dropped into
  34. * page object at specified place.
  35. *
  36. * @package Zend_Pdf
  37. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  38. * @license http://framework.zend.com/license/new-bsd New BSD License
  39. */
  40. abstract class Zend_Pdf_Canvas_Abstract implements Zend_Pdf_Canvas_Interface
  41. {
  42. /**
  43. * Drawing instructions
  44. *
  45. * @var string
  46. */
  47. protected $_contents = '';
  48. /**
  49. * Current font
  50. *
  51. * @var Zend_Pdf_Resource_Font
  52. */
  53. protected $_font = null;
  54. /**
  55. * Current font size
  56. *
  57. * @var float
  58. */
  59. protected $_fontSize;
  60. /**
  61. * Current style
  62. *
  63. * @var Zend_Pdf_Style
  64. */
  65. protected $_style = null;
  66. /**
  67. * Counter for the "Save" operations
  68. *
  69. * @var integer
  70. */
  71. protected $_saveCount = 0;
  72. /**
  73. * Add procedureSet to the Page description
  74. *
  75. * @param string $procSetName
  76. */
  77. abstract protected function _addProcSet($procSetName);
  78. /**
  79. * Attach resource to the canvas
  80. *
  81. * Method returns a name of the resource which can be used
  82. * as a resource reference within drawing instructions stream
  83. * Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading',
  84. * 'XObject', 'Font', 'Properties'
  85. *
  86. * @param string $type
  87. * @param Zend_Pdf_Resource $resource
  88. * @return string
  89. */
  90. abstract protected function _attachResource($type, Zend_Pdf_Resource $resource);
  91. /**
  92. * Draw a canvas at the specified location
  93. *
  94. * If upper right corner is not specified then canvas heght and width
  95. * are used.
  96. *
  97. * @param Zend_Pdf_Canvas_Interface $canvas
  98. * @param float $x1
  99. * @param float $y1
  100. * @param float $x2
  101. * @param float $y2
  102. * @return Zend_Pdf_Canvas_Interface
  103. */
  104. public function drawCanvas(Zend_Pdf_Canvas_Interface $canvas, $x1, $y1, $x2 = null, $y2 = null)
  105. {
  106. $this->saveGS();
  107. $this->translate($x1, $y1);
  108. if ($x2 === null) {
  109. $with = $canvas->getWidth();
  110. } else {
  111. $with = $x2 - $x1;
  112. }
  113. if ($y2 === null) {
  114. $height = $canvas->getHeight();
  115. } else {
  116. $height = $y2 - $y1;
  117. }
  118. $this->clipRectangle(0, 0, $with, $height);
  119. if ($x2 !== null || $y2 !== null) {
  120. // Drawn canvas has to be scaled.
  121. if ($x2 !== null) {
  122. $xScale = $with/$canvas->getWidth();
  123. } else {
  124. $xScale = 1;
  125. }
  126. if ($y2 !== null) {
  127. $yScale = $height/$canvas->getHeight();
  128. } else {
  129. $yScale = 1;
  130. }
  131. $this->scale($xScale, $yScale);
  132. }
  133. $contentsToDraw = $canvas->_getContents();
  134. $this->restoreGS();
  135. return $this;
  136. }
  137. /**
  138. * Set fill color.
  139. *
  140. * @param Zend_Pdf_Color $color
  141. * @return Zend_Pdf_Canvas_Interface
  142. */
  143. public function setFillColor(Zend_Pdf_Color $color)
  144. {
  145. $this->_addProcSet('PDF');
  146. $this->_contents .= $color->instructions(false);
  147. return $this;
  148. }
  149. /**
  150. * Set line color.
  151. *
  152. * @param Zend_Pdf_Color $color
  153. * @return Zend_Pdf_Canvas_Interface
  154. */
  155. public function setLineColor(Zend_Pdf_Color $color)
  156. {
  157. $this->_addProcSet('PDF');
  158. $this->_contents .= $color->instructions(true);
  159. return $this;
  160. }
  161. /**
  162. * Set line width.
  163. *
  164. * @param float $width
  165. * @return Zend_Pdf_Canvas_Interface
  166. */
  167. public function setLineWidth($width)
  168. {
  169. $this->_addProcSet('PDF');
  170. $widthObj = new Zend_Pdf_Element_Numeric($width);
  171. $this->_contents .= $widthObj->toString() . " w\n";
  172. return $this;
  173. }
  174. /**
  175. * Set line dashing pattern
  176. *
  177. * Pattern is an array of floats: array(on_length, off_length, on_length, off_length, ...)
  178. * or Zend_Pdf_Page::LINE_DASHING_SOLID constant
  179. * Phase is shift from the beginning of line.
  180. *
  181. * @param mixed $pattern
  182. * @param array $phase
  183. * @return Zend_Pdf_Canvas_Interface
  184. */
  185. public function setLineDashingPattern($pattern, $phase = 0)
  186. {
  187. $this->_addProcSet('PDF');
  188. require_once 'Zend/Pdf/Page.php';
  189. if ($pattern === Zend_Pdf_Page::LINE_DASHING_SOLID) {
  190. $pattern = array();
  191. $phase = 0;
  192. }
  193. $dashPattern = new Zend_Pdf_Element_Array();
  194. $phaseEleemnt = new Zend_Pdf_Element_Numeric($phase);
  195. foreach ($pattern as $dashItem) {
  196. $dashElement = new Zend_Pdf_Element_Numeric($dashItem);
  197. $dashPattern->items[] = $dashElement;
  198. }
  199. $this->_contents .= $dashPattern->toString() . ' '
  200. . $phaseEleemnt->toString() . " d\n";
  201. return $this;
  202. }
  203. /**
  204. * Set current font.
  205. *
  206. * @param Zend_Pdf_Resource_Font $font
  207. * @param float $fontSize
  208. * @return Zend_Pdf_Canvas_Interface
  209. */
  210. public function setFont(Zend_Pdf_Resource_Font $font, $fontSize)
  211. {
  212. $this->_addProcSet('Text');
  213. $fontName = $this->_attachResource('Font', $font);
  214. $this->_font = $font;
  215. $this->_fontSize = $fontSize;
  216. $fontNameObj = new Zend_Pdf_Element_Name($fontName);
  217. $fontSizeObj = new Zend_Pdf_Element_Numeric($fontSize);
  218. $this->_contents .= $fontNameObj->toString() . ' ' . $fontSizeObj->toString() . " Tf\n";
  219. return $this;
  220. }
  221. /**
  222. * Set the style to use for future drawing operations on this page
  223. *
  224. * @param Zend_Pdf_Style $style
  225. * @return Zend_Pdf_Canvas_Interface
  226. */
  227. public function setStyle(Zend_Pdf_Style $style)
  228. {
  229. $this->_addProcSet('Text');
  230. $this->_addProcSet('PDF');
  231. if ($style->getFont() !== null) {
  232. $this->setFont($style->getFont(), $style->getFontSize());
  233. }
  234. $this->_contents .= $style->instructions($this->_dictionary->Resources);
  235. $this->_style = $style;
  236. return $this;
  237. }
  238. /**
  239. * Get current font.
  240. *
  241. * @return Zend_Pdf_Resource_Font $font
  242. */
  243. public function getFont()
  244. {
  245. return $this->_font;
  246. }
  247. /**
  248. * Get current font size
  249. *
  250. * @return float $fontSize
  251. */
  252. public function getFontSize()
  253. {
  254. return $this->_fontSize;
  255. }
  256. /**
  257. * Return the style, applied to the page.
  258. *
  259. * @return Zend_Pdf_Style
  260. */
  261. public function getStyle()
  262. {
  263. return $this->_style;
  264. }
  265. /**
  266. * Save the graphics state of this page.
  267. * This takes a snapshot of the currently applied style, position, clipping area and
  268. * any rotation/translation/scaling that has been applied.
  269. *
  270. * @todo check for the open paths
  271. * @throws Zend_Pdf_Exception - if a save is performed with an open path
  272. * @return Zend_Pdf_Canvas_Interface
  273. */
  274. public function saveGS()
  275. {
  276. $this->_saveCount++;
  277. $this->_addProcSet('PDF');
  278. $this->_contents .= " q\n";
  279. return $this;
  280. }
  281. /**
  282. * Restore the graphics state that was saved with the last call to saveGS().
  283. *
  284. * @throws Zend_Pdf_Exception - if there is no previously saved state
  285. * @return Zend_Pdf_Canvas_Interface
  286. */
  287. public function restoreGS()
  288. {
  289. if ($this->_saveCount-- <= 0) {
  290. require_once 'Zend/Pdf/Exception.php';
  291. throw new Zend_Pdf_Exception('Restoring graphics state which is not saved');
  292. }
  293. $this->_contents .= " Q\n";
  294. return $this;
  295. }
  296. /**
  297. * Set the transparancy
  298. *
  299. * $alpha == 0 - transparent
  300. * $alpha == 1 - opaque
  301. *
  302. * Transparency modes, supported by PDF:
  303. * Normal (default), Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight,
  304. * SoftLight, Difference, Exclusion
  305. *
  306. * @param float $alpha
  307. * @param string $mode
  308. * @return Zend_Pdf_Canvas_Interface
  309. */
  310. public function setAlpha($alpha, $mode = 'Normal')
  311. {
  312. $this->_addProcSet('Text');
  313. $this->_addProcSet('PDF');
  314. $graphicsState = new Zend_Pdf_Resource_GraphicsState();
  315. $graphicsState->setAlpha($alpha, $mode);
  316. $gStateName = $this->_attachResource('ExtGState', $graphicsState);
  317. $gStateNameObject = new Zend_Pdf_Element_Name($gStateName);
  318. $this->_contents .= $gStateNameObject->toString() . " gs\n";
  319. return $this;
  320. }
  321. /**
  322. * Intersect current clipping area with a circle.
  323. *
  324. * @param float $x
  325. * @param float $y
  326. * @param float $radius
  327. * @param float $startAngle
  328. * @param float $endAngle
  329. * @return Zend_Pdf_Canvas_Interface
  330. */
  331. public function clipCircle($x, $y, $radius, $startAngle = null, $endAngle = null)
  332. {
  333. $this->clipEllipse($x - $radius, $y - $radius,
  334. $x + $radius, $y + $radius,
  335. $startAngle, $endAngle);
  336. return $this;
  337. }
  338. /**
  339. * Intersect current clipping area with a polygon.
  340. *
  341. * Method signatures:
  342. * drawEllipse($x1, $y1, $x2, $y2);
  343. * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle);
  344. *
  345. * @todo process special cases with $x2-$x1 == 0 or $y2-$y1 == 0
  346. *
  347. * @param float $x1
  348. * @param float $y1
  349. * @param float $x2
  350. * @param float $y2
  351. * @param float $startAngle
  352. * @param float $endAngle
  353. * @return Zend_Pdf_Canvas_Interface
  354. */
  355. public function clipEllipse($x1, $y1, $x2, $y2, $startAngle = null, $endAngle = null)
  356. {
  357. $this->_addProcSet('PDF');
  358. if ($x2 < $x1) {
  359. $temp = $x1;
  360. $x1 = $x2;
  361. $x2 = $temp;
  362. }
  363. if ($y2 < $y1) {
  364. $temp = $y1;
  365. $y1 = $y2;
  366. $y2 = $temp;
  367. }
  368. $x = ($x1 + $x2)/2.;
  369. $y = ($y1 + $y2)/2.;
  370. $xC = new Zend_Pdf_Element_Numeric($x);
  371. $yC = new Zend_Pdf_Element_Numeric($y);
  372. if ($startAngle !== null) {
  373. if ($startAngle != 0) { $startAngle = fmod($startAngle, M_PI*2); }
  374. if ($endAngle != 0) { $endAngle = fmod($endAngle, M_PI*2); }
  375. if ($startAngle > $endAngle) {
  376. $endAngle += M_PI*2;
  377. }
  378. $clipPath = $xC->toString() . ' ' . $yC->toString() . " m\n";
  379. $clipSectors = (int)ceil(($endAngle - $startAngle)/M_PI_4);
  380. $clipRadius = max($x2 - $x1, $y2 - $y1);
  381. for($count = 0; $count <= $clipSectors; $count++) {
  382. $pAngle = $startAngle + ($endAngle - $startAngle)*$count/(float)$clipSectors;
  383. $pX = new Zend_Pdf_Element_Numeric($x + cos($pAngle)*$clipRadius);
  384. $pY = new Zend_Pdf_Element_Numeric($y + sin($pAngle)*$clipRadius);
  385. $clipPath .= $pX->toString() . ' ' . $pY->toString() . " l\n";
  386. }
  387. $this->_contents .= $clipPath . "h\nW\nn\n";
  388. }
  389. $xLeft = new Zend_Pdf_Element_Numeric($x1);
  390. $xRight = new Zend_Pdf_Element_Numeric($x2);
  391. $yUp = new Zend_Pdf_Element_Numeric($y2);
  392. $yDown = new Zend_Pdf_Element_Numeric($y1);
  393. $xDelta = 2*(M_SQRT2 - 1)*($x2 - $x1)/3.;
  394. $yDelta = 2*(M_SQRT2 - 1)*($y2 - $y1)/3.;
  395. $xr = new Zend_Pdf_Element_Numeric($x + $xDelta);
  396. $xl = new Zend_Pdf_Element_Numeric($x - $xDelta);
  397. $yu = new Zend_Pdf_Element_Numeric($y + $yDelta);
  398. $yd = new Zend_Pdf_Element_Numeric($y - $yDelta);
  399. $this->_contents .= $xC->toString() . ' ' . $yUp->toString() . " m\n"
  400. . $xr->toString() . ' ' . $yUp->toString() . ' '
  401. . $xRight->toString() . ' ' . $yu->toString() . ' '
  402. . $xRight->toString() . ' ' . $yC->toString() . " c\n"
  403. . $xRight->toString() . ' ' . $yd->toString() . ' '
  404. . $xr->toString() . ' ' . $yDown->toString() . ' '
  405. . $xC->toString() . ' ' . $yDown->toString() . " c\n"
  406. . $xl->toString() . ' ' . $yDown->toString() . ' '
  407. . $xLeft->toString() . ' ' . $yd->toString() . ' '
  408. . $xLeft->toString() . ' ' . $yC->toString() . " c\n"
  409. . $xLeft->toString() . ' ' . $yu->toString() . ' '
  410. . $xl->toString() . ' ' . $yUp->toString() . ' '
  411. . $xC->toString() . ' ' . $yUp->toString() . " c\n"
  412. . "h\nW\nn\n";
  413. return $this;
  414. }
  415. /**
  416. * Intersect current clipping area with a polygon.
  417. *
  418. * @param array $x - array of float (the X co-ordinates of the vertices)
  419. * @param array $y - array of float (the Y co-ordinates of the vertices)
  420. * @param integer $fillMethod
  421. * @return Zend_Pdf_Canvas_Interface
  422. */
  423. public function clipPolygon($x, $y, $fillMethod = Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING)
  424. {
  425. $this->_addProcSet('PDF');
  426. $firstPoint = true;
  427. foreach ($x as $id => $xVal) {
  428. $xObj = new Zend_Pdf_Element_Numeric($xVal);
  429. $yObj = new Zend_Pdf_Element_Numeric($y[$id]);
  430. if ($firstPoint) {
  431. $path = $xObj->toString() . ' ' . $yObj->toString() . " m\n";
  432. $firstPoint = false;
  433. } else {
  434. $path .= $xObj->toString() . ' ' . $yObj->toString() . " l\n";
  435. }
  436. }
  437. $this->_contents .= $path;
  438. if ($fillMethod == Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) {
  439. $this->_contents .= " h\n W\nn\n";
  440. } else {
  441. // Even-Odd fill method.
  442. $this->_contents .= " h\n W*\nn\n";
  443. }
  444. return $this;
  445. }
  446. /**
  447. * Intersect current clipping area with a rectangle.
  448. *
  449. * @param float $x1
  450. * @param float $y1
  451. * @param float $x2
  452. * @param float $y2
  453. * @return Zend_Pdf_Canvas_Interface
  454. */
  455. public function clipRectangle($x1, $y1, $x2, $y2)
  456. {
  457. $this->_addProcSet('PDF');
  458. $x1Obj = new Zend_Pdf_Element_Numeric($x1);
  459. $y1Obj = new Zend_Pdf_Element_Numeric($y1);
  460. $widthObj = new Zend_Pdf_Element_Numeric($x2 - $x1);
  461. $height2Obj = new Zend_Pdf_Element_Numeric($y2 - $y1);
  462. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' '
  463. . $widthObj->toString() . ' ' . $height2Obj->toString() . " re\n"
  464. . " W\nn\n";
  465. return $this;
  466. }
  467. // ------------------------------------------------------------------------------------------
  468. /**
  469. * Draw a circle centered on x, y with a radius of radius.
  470. *
  471. * Method signatures:
  472. * drawCircle($x, $y, $radius);
  473. * drawCircle($x, $y, $radius, $fillType);
  474. * drawCircle($x, $y, $radius, $startAngle, $endAngle);
  475. * drawCircle($x, $y, $radius, $startAngle, $endAngle, $fillType);
  476. *
  477. *
  478. * It's not a really circle, because PDF supports only cubic Bezier curves.
  479. * But _very_ good approximation.
  480. * It differs from a real circle on a maximum 0.00026 radiuses
  481. * (at PI/8, 3*PI/8, 5*PI/8, 7*PI/8, 9*PI/8, 11*PI/8, 13*PI/8 and 15*PI/8 angles).
  482. * At 0, PI/4, PI/2, 3*PI/4, PI, 5*PI/4, 3*PI/2 and 7*PI/4 it's exactly a tangent to a circle.
  483. *
  484. * @param float $x
  485. * @param float $y
  486. * @param float $radius
  487. * @param mixed $param4
  488. * @param mixed $param5
  489. * @param mixed $param6
  490. * @return Zend_Pdf_Canvas_Interface
  491. */
  492. public function drawCircle($x, $y, $radius, $param4 = null, $param5 = null, $param6 = null)
  493. {
  494. $this->drawEllipse($x - $radius, $y - $radius,
  495. $x + $radius, $y + $radius,
  496. $param4, $param5, $param6);
  497. return $this;
  498. }
  499. /**
  500. * Draw an ellipse inside the specified rectangle.
  501. *
  502. * Method signatures:
  503. * drawEllipse($x1, $y1, $x2, $y2);
  504. * drawEllipse($x1, $y1, $x2, $y2, $fillType);
  505. * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle);
  506. * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle, $fillType);
  507. *
  508. * @todo process special cases with $x2-$x1 == 0 or $y2-$y1 == 0
  509. *
  510. * @param float $x1
  511. * @param float $y1
  512. * @param float $x2
  513. * @param float $y2
  514. * @param mixed $param5
  515. * @param mixed $param6
  516. * @param mixed $param7
  517. * @return Zend_Pdf_Canvas_Interface
  518. */
  519. public function drawEllipse($x1, $y1, $x2, $y2, $param5 = null, $param6 = null, $param7 = null)
  520. {
  521. if ($param5 === null) {
  522. // drawEllipse($x1, $y1, $x2, $y2);
  523. $startAngle = null;
  524. $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE;
  525. } else if ($param6 === null) {
  526. // drawEllipse($x1, $y1, $x2, $y2, $fillType);
  527. $startAngle = null;
  528. $fillType = $param5;
  529. } else {
  530. // drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle);
  531. // drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle, $fillType);
  532. $startAngle = $param5;
  533. $endAngle = $param6;
  534. if ($param7 === null) {
  535. $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE;
  536. } else {
  537. $fillType = $param7;
  538. }
  539. }
  540. $this->_addProcSet('PDF');
  541. if ($x2 < $x1) {
  542. $temp = $x1;
  543. $x1 = $x2;
  544. $x2 = $temp;
  545. }
  546. if ($y2 < $y1) {
  547. $temp = $y1;
  548. $y1 = $y2;
  549. $y2 = $temp;
  550. }
  551. $x = ($x1 + $x2)/2.;
  552. $y = ($y1 + $y2)/2.;
  553. $xC = new Zend_Pdf_Element_Numeric($x);
  554. $yC = new Zend_Pdf_Element_Numeric($y);
  555. if ($startAngle !== null) {
  556. if ($startAngle != 0) { $startAngle = fmod($startAngle, M_PI*2); }
  557. if ($endAngle != 0) { $endAngle = fmod($endAngle, M_PI*2); }
  558. if ($startAngle > $endAngle) {
  559. $endAngle += M_PI*2;
  560. }
  561. $clipPath = $xC->toString() . ' ' . $yC->toString() . " m\n";
  562. $clipSectors = (int)ceil(($endAngle - $startAngle)/M_PI_4);
  563. $clipRadius = max($x2 - $x1, $y2 - $y1);
  564. for($count = 0; $count <= $clipSectors; $count++) {
  565. $pAngle = $startAngle + ($endAngle - $startAngle)*$count/(float)$clipSectors;
  566. $pX = new Zend_Pdf_Element_Numeric($x + cos($pAngle)*$clipRadius);
  567. $pY = new Zend_Pdf_Element_Numeric($y + sin($pAngle)*$clipRadius);
  568. $clipPath .= $pX->toString() . ' ' . $pY->toString() . " l\n";
  569. }
  570. $this->_contents .= "q\n" . $clipPath . "h\nW\nn\n";
  571. }
  572. $xLeft = new Zend_Pdf_Element_Numeric($x1);
  573. $xRight = new Zend_Pdf_Element_Numeric($x2);
  574. $yUp = new Zend_Pdf_Element_Numeric($y2);
  575. $yDown = new Zend_Pdf_Element_Numeric($y1);
  576. $xDelta = 2*(M_SQRT2 - 1)*($x2 - $x1)/3.;
  577. $yDelta = 2*(M_SQRT2 - 1)*($y2 - $y1)/3.;
  578. $xr = new Zend_Pdf_Element_Numeric($x + $xDelta);
  579. $xl = new Zend_Pdf_Element_Numeric($x - $xDelta);
  580. $yu = new Zend_Pdf_Element_Numeric($y + $yDelta);
  581. $yd = new Zend_Pdf_Element_Numeric($y - $yDelta);
  582. $this->_contents .= $xC->toString() . ' ' . $yUp->toString() . " m\n"
  583. . $xr->toString() . ' ' . $yUp->toString() . ' '
  584. . $xRight->toString() . ' ' . $yu->toString() . ' '
  585. . $xRight->toString() . ' ' . $yC->toString() . " c\n"
  586. . $xRight->toString() . ' ' . $yd->toString() . ' '
  587. . $xr->toString() . ' ' . $yDown->toString() . ' '
  588. . $xC->toString() . ' ' . $yDown->toString() . " c\n"
  589. . $xl->toString() . ' ' . $yDown->toString() . ' '
  590. . $xLeft->toString() . ' ' . $yd->toString() . ' '
  591. . $xLeft->toString() . ' ' . $yC->toString() . " c\n"
  592. . $xLeft->toString() . ' ' . $yu->toString() . ' '
  593. . $xl->toString() . ' ' . $yUp->toString() . ' '
  594. . $xC->toString() . ' ' . $yUp->toString() . " c\n";
  595. switch ($fillType) {
  596. case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE:
  597. $this->_contents .= " B*\n";
  598. break;
  599. case Zend_Pdf_Page::SHAPE_DRAW_FILL:
  600. $this->_contents .= " f*\n";
  601. break;
  602. case Zend_Pdf_Page::SHAPE_DRAW_STROKE:
  603. $this->_contents .= " S\n";
  604. break;
  605. }
  606. if ($startAngle !== null) {
  607. $this->_contents .= "Q\n";
  608. }
  609. return $this;
  610. }
  611. /**
  612. * Draw an image at the specified position on the page.
  613. *
  614. * @param Zend_Pdf_Image $image
  615. * @param float $x1
  616. * @param float $y1
  617. * @param float $x2
  618. * @param float $y2
  619. * @return Zend_Pdf_Canvas_Interface
  620. */
  621. public function drawImage(Zend_Pdf_Resource_Image $image, $x1, $y1, $x2, $y2)
  622. {
  623. $this->_addProcSet('PDF');
  624. $imageName = $this->_attachResource('XObject', $image);
  625. $imageNameObj = new Zend_Pdf_Element_Name($imageName);
  626. $x1Obj = new Zend_Pdf_Element_Numeric($x1);
  627. $y1Obj = new Zend_Pdf_Element_Numeric($y1);
  628. $widthObj = new Zend_Pdf_Element_Numeric($x2 - $x1);
  629. $heightObj = new Zend_Pdf_Element_Numeric($y2 - $y1);
  630. $this->_contents .= "q\n"
  631. . '1 0 0 1 ' . $x1Obj->toString() . ' ' . $y1Obj->toString() . " cm\n"
  632. . $widthObj->toString() . ' 0 0 ' . $heightObj->toString() . " 0 0 cm\n"
  633. . $imageNameObj->toString() . " Do\n"
  634. . "Q\n";
  635. return $this;
  636. }
  637. /**
  638. * Draw a LayoutBox at the specified position on the page.
  639. *
  640. * @internal (not implemented now)
  641. *
  642. * @param Zend_Pdf_Element_LayoutBox $box
  643. * @param float $x
  644. * @param float $y
  645. * @return Zend_Pdf_Canvas_Interface
  646. */
  647. public function drawLayoutBox($box, $x, $y)
  648. {
  649. /** @todo implementation */
  650. return $this;
  651. }
  652. /**
  653. * Draw a line from x1,y1 to x2,y2.
  654. *
  655. * @param float $x1
  656. * @param float $y1
  657. * @param float $x2
  658. * @param float $y2
  659. * @return Zend_Pdf_Canvas_Interface
  660. */
  661. public function drawLine($x1, $y1, $x2, $y2)
  662. {
  663. $this->_addProcSet('PDF');
  664. $x1Obj = new Zend_Pdf_Element_Numeric($x1);
  665. $y1Obj = new Zend_Pdf_Element_Numeric($y1);
  666. $x2Obj = new Zend_Pdf_Element_Numeric($x2);
  667. $y2Obj = new Zend_Pdf_Element_Numeric($y2);
  668. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " m\n"
  669. . $x2Obj->toString() . ' ' . $y2Obj->toString() . " l\n S\n";
  670. return $this;
  671. }
  672. /**
  673. * Draw a polygon.
  674. *
  675. * If $fillType is Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE or
  676. * Zend_Pdf_Page::SHAPE_DRAW_FILL, then polygon is automatically closed.
  677. * See detailed description of these methods in a PDF documentation
  678. * (section 4.4.2 Path painting Operators, Filling)
  679. *
  680. * @param array $x - array of float (the X co-ordinates of the vertices)
  681. * @param array $y - array of float (the Y co-ordinates of the vertices)
  682. * @param integer $fillType
  683. * @param integer $fillMethod
  684. * @return Zend_Pdf_Canvas_Interface
  685. */
  686. public function drawPolygon($x, $y,
  687. $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE,
  688. $fillMethod = Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING)
  689. {
  690. $this->_addProcSet('PDF');
  691. $firstPoint = true;
  692. foreach ($x as $id => $xVal) {
  693. $xObj = new Zend_Pdf_Element_Numeric($xVal);
  694. $yObj = new Zend_Pdf_Element_Numeric($y[$id]);
  695. if ($firstPoint) {
  696. $path = $xObj->toString() . ' ' . $yObj->toString() . " m\n";
  697. $firstPoint = false;
  698. } else {
  699. $path .= $xObj->toString() . ' ' . $yObj->toString() . " l\n";
  700. }
  701. }
  702. $this->_contents .= $path;
  703. switch ($fillType) {
  704. case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE:
  705. if ($fillMethod == Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) {
  706. $this->_contents .= " b\n";
  707. } else {
  708. // Even-Odd fill method.
  709. $this->_contents .= " b*\n";
  710. }
  711. break;
  712. case Zend_Pdf_Page::SHAPE_DRAW_FILL:
  713. if ($fillMethod == Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) {
  714. $this->_contents .= " h\n f\n";
  715. } else {
  716. // Even-Odd fill method.
  717. $this->_contents .= " h\n f*\n";
  718. }
  719. break;
  720. case Zend_Pdf_Page::SHAPE_DRAW_STROKE:
  721. $this->_contents .= " S\n";
  722. break;
  723. }
  724. return $this;
  725. }
  726. /**
  727. * Draw a rectangle.
  728. *
  729. * Fill types:
  730. * Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - fill rectangle and stroke (default)
  731. * Zend_Pdf_Page::SHAPE_DRAW_STROKE - stroke rectangle
  732. * Zend_Pdf_Page::SHAPE_DRAW_FILL - fill rectangle
  733. *
  734. * @param float $x1
  735. * @param float $y1
  736. * @param float $x2
  737. * @param float $y2
  738. * @param integer $fillType
  739. * @return Zend_Pdf_Canvas_Interface
  740. */
  741. public function drawRectangle($x1, $y1, $x2, $y2, $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE)
  742. {
  743. $this->_addProcSet('PDF');
  744. $x1Obj = new Zend_Pdf_Element_Numeric($x1);
  745. $y1Obj = new Zend_Pdf_Element_Numeric($y1);
  746. $widthObj = new Zend_Pdf_Element_Numeric($x2 - $x1);
  747. $height2Obj = new Zend_Pdf_Element_Numeric($y2 - $y1);
  748. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' '
  749. . $widthObj->toString() . ' ' . $height2Obj->toString() . " re\n";
  750. switch ($fillType) {
  751. case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE:
  752. $this->_contents .= " B*\n";
  753. break;
  754. case Zend_Pdf_Page::SHAPE_DRAW_FILL:
  755. $this->_contents .= " f*\n";
  756. break;
  757. case Zend_Pdf_Page::SHAPE_DRAW_STROKE:
  758. $this->_contents .= " S\n";
  759. break;
  760. }
  761. return $this;
  762. }
  763. /**
  764. * Draw a rounded rectangle.
  765. *
  766. * Fill types:
  767. * Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - fill rectangle and stroke (default)
  768. * Zend_Pdf_Page::SHAPE_DRAW_STROKE - stroke rectangle
  769. * Zend_Pdf_Page::SHAPE_DRAW_FILL - fill rectangle
  770. *
  771. * radius is an integer representing radius of the four corners, or an array
  772. * of four integers representing the radius starting at top left, going
  773. * clockwise
  774. *
  775. * @param float $x1
  776. * @param float $y1
  777. * @param float $x2
  778. * @param float $y2
  779. * @param integer|array $radius
  780. * @param integer $fillType
  781. * @return Zend_Pdf_Canvas_Interface
  782. */
  783. public function drawRoundedRectangle($x1, $y1, $x2, $y2, $radius,
  784. $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE)
  785. {
  786. $this->_addProcSet('PDF');
  787. if(!is_array($radius)) {
  788. $radius = array($radius, $radius, $radius, $radius);
  789. } else {
  790. for ($i = 0; $i < 4; $i++) {
  791. if(!isset($radius[$i])) {
  792. $radius[$i] = 0;
  793. }
  794. }
  795. }
  796. $topLeftX = $x1;
  797. $topLeftY = $y2;
  798. $topRightX = $x2;
  799. $topRightY = $y2;
  800. $bottomRightX = $x2;
  801. $bottomRightY = $y1;
  802. $bottomLeftX = $x1;
  803. $bottomLeftY = $y1;
  804. //draw top side
  805. $x1Obj = new Zend_Pdf_Element_Numeric($topLeftX + $radius[0]);
  806. $y1Obj = new Zend_Pdf_Element_Numeric($topLeftY);
  807. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " m\n";
  808. $x1Obj = new Zend_Pdf_Element_Numeric($topRightX - $radius[1]);
  809. $y1Obj = new Zend_Pdf_Element_Numeric($topRightY);
  810. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n";
  811. //draw top right corner if needed
  812. if ($radius[1] != 0) {
  813. $x1Obj = new Zend_Pdf_Element_Numeric($topRightX);
  814. $y1Obj = new Zend_Pdf_Element_Numeric($topRightY);
  815. $x2Obj = new Zend_Pdf_Element_Numeric($topRightX);
  816. $y2Obj = new Zend_Pdf_Element_Numeric($topRightY);
  817. $x3Obj = new Zend_Pdf_Element_Numeric($topRightX);
  818. $y3Obj = new Zend_Pdf_Element_Numeric($topRightY - $radius[1]);
  819. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' '
  820. . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' '
  821. . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' '
  822. . " c\n";
  823. }
  824. //draw right side
  825. $x1Obj = new Zend_Pdf_Element_Numeric($bottomRightX);
  826. $y1Obj = new Zend_Pdf_Element_Numeric($bottomRightY + $radius[2]);
  827. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n";
  828. //draw bottom right corner if needed
  829. if ($radius[2] != 0) {
  830. $x1Obj = new Zend_Pdf_Element_Numeric($bottomRightX);
  831. $y1Obj = new Zend_Pdf_Element_Numeric($bottomRightY);
  832. $x2Obj = new Zend_Pdf_Element_Numeric($bottomRightX);
  833. $y2Obj = new Zend_Pdf_Element_Numeric($bottomRightY);
  834. $x3Obj = new Zend_Pdf_Element_Numeric($bottomRightX - $radius[2]);
  835. $y3Obj = new Zend_Pdf_Element_Numeric($bottomRightY);
  836. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' '
  837. . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' '
  838. . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' '
  839. . " c\n";
  840. }
  841. //draw bottom side
  842. $x1Obj = new Zend_Pdf_Element_Numeric($bottomLeftX + $radius[3]);
  843. $y1Obj = new Zend_Pdf_Element_Numeric($bottomLeftY);
  844. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n";
  845. //draw bottom left corner if needed
  846. if ($radius[3] != 0) {
  847. $x1Obj = new Zend_Pdf_Element_Numeric($bottomLeftX);
  848. $y1Obj = new Zend_Pdf_Element_Numeric($bottomLeftY);
  849. $x2Obj = new Zend_Pdf_Element_Numeric($bottomLeftX);
  850. $y2Obj = new Zend_Pdf_Element_Numeric($bottomLeftY);
  851. $x3Obj = new Zend_Pdf_Element_Numeric($bottomLeftX);
  852. $y3Obj = new Zend_Pdf_Element_Numeric($bottomLeftY + $radius[3]);
  853. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' '
  854. . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' '
  855. . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' '
  856. . " c\n";
  857. }
  858. //draw left side
  859. $x1Obj = new Zend_Pdf_Element_Numeric($topLeftX);
  860. $y1Obj = new Zend_Pdf_Element_Numeric($topLeftY - $radius[0]);
  861. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n";
  862. //draw top left corner if needed
  863. if ($radius[0] != 0) {
  864. $x1Obj = new Zend_Pdf_Element_Numeric($topLeftX);
  865. $y1Obj = new Zend_Pdf_Element_Numeric($topLeftY);
  866. $x2Obj = new Zend_Pdf_Element_Numeric($topLeftX);
  867. $y2Obj = new Zend_Pdf_Element_Numeric($topLeftY);
  868. $x3Obj = new Zend_Pdf_Element_Numeric($topLeftX + $radius[0]);
  869. $y3Obj = new Zend_Pdf_Element_Numeric($topLeftY);
  870. $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' '
  871. . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' '
  872. . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' '
  873. . " c\n";
  874. }
  875. switch ($fillType) {
  876. case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE:
  877. $this->_contents .= " B*\n";
  878. break;
  879. case Zend_Pdf_Page::SHAPE_DRAW_FILL:
  880. $this->_contents .= " f*\n";
  881. break;
  882. case Zend_Pdf_Page::SHAPE_DRAW_STROKE:
  883. $this->_contents .= " S\n";
  884. break;
  885. }
  886. return $this;
  887. }
  888. /**
  889. * Draw a line of text at the specified position.
  890. *
  891. * @param string $text
  892. * @param float $x
  893. * @param float $y
  894. * @param string $charEncoding (optional) Character encoding of source text.
  895. * Defaults to current locale.
  896. * @throws Zend_Pdf_Exception
  897. * @return Zend_Pdf_Canvas_Interface
  898. */
  899. public function drawText($text, $x, $y, $charEncoding = '')
  900. {
  901. if ($this->_font === null) {
  902. require_once 'Zend/Pdf/Exception.php';
  903. throw new Zend_Pdf_Exception('Font has not been set');
  904. }
  905. $this->_addProcSet('Text');
  906. $textObj = new Zend_Pdf_Element_String($this->_font->encodeString($text, $charEncoding));
  907. $xObj = new Zend_Pdf_Element_Numeric($x);
  908. $yObj = new Zend_Pdf_Element_Numeric($y);
  909. $this->_contents .= "BT\n"
  910. . $xObj->toString() . ' ' . $yObj->toString() . " Td\n"
  911. . $textObj->toString() . " Tj\n"
  912. . "ET\n";
  913. return $this;
  914. }
  915. /**
  916. * Close the path by drawing a straight line back to it's beginning.
  917. *
  918. * @internal (needs implementation)
  919. *
  920. * @throws Zend_Pdf_Exception - if a path hasn't been started with pathMove()
  921. * @return Zend_Pdf_Canvas_Interface
  922. */
  923. public function pathClose()
  924. {
  925. /** @todo implementation */
  926. return $this;
  927. }
  928. /**
  929. * Continue the open path in a straight line to the specified position.
  930. *
  931. * @internal (needs implementation)
  932. *
  933. * @param float $x - the X co-ordinate to move to
  934. * @param float $y - the Y co-ordinate to move to
  935. * @return Zend_Pdf_Canvas_Interface
  936. */
  937. public function pathLine($x, $y)
  938. {
  939. /** @todo implementation */
  940. return $this;
  941. }
  942. /**
  943. * Start a new path at the specified position. If a path has already been started,
  944. * move the cursor without drawing a line.
  945. *
  946. * @internal (needs implementation)
  947. *
  948. * @param float $x - the X co-ordinate to move to
  949. * @param float $y - the Y co-ordinate to move to
  950. * @return Zend_Pdf_Canvas_Interface
  951. */
  952. public function pathMove($x, $y)
  953. {
  954. /** @todo implementation */
  955. return $this;
  956. }
  957. /**
  958. * Rotate the page.
  959. *
  960. * @param float $x - the X co-ordinate of rotation point
  961. * @param float $y - the Y co-ordinate of rotation point
  962. * @param float $angle - rotation angle
  963. * @return Zend_Pdf_Canvas_Interface
  964. */
  965. public function rotate($x, $y, $angle)
  966. {
  967. $cos = new Zend_Pdf_Element_Numeric(cos($angle));
  968. $sin = new Zend_Pdf_Element_Numeric(sin($angle));
  969. $mSin = new Zend_Pdf_Element_Numeric(-$sin->value);
  970. $xObj = new Zend_Pdf_Element_Numeric($x);
  971. $yObj = new Zend_Pdf_Element_Numeric($y);
  972. $mXObj = new Zend_Pdf_Element_Numeric(-$x);
  973. $mYObj = new Zend_Pdf_Element_Numeric(-$y);
  974. $this->_addProcSet('PDF');
  975. $this->_contents .= '1 0 0 1 ' . $xObj->toString() . ' ' . $yObj->toString() . " cm\n"
  976. . $cos->toString() . ' ' . $sin->toString() . ' ' . $mSin->toString() . ' ' . $cos->toString() . " 0 0 cm\n"
  977. . '1 0 0 1 ' . $mXObj->toString() . ' ' . $mYObj->toString() . " cm\n";
  978. return $this;
  979. }
  980. /**
  981. * Scale coordination system.
  982. *
  983. * @param float $xScale - X dimention scale factor
  984. * @param float $yScale - Y dimention scale factor
  985. * @return Zend_Pdf_Canvas_Interface
  986. */
  987. public function scale($xScale, $yScale)
  988. {
  989. $xScaleObj = new Zend_Pdf_Element_Numeric($xScale);
  990. $yScaleObj = new Zend_Pdf_Element_Numeric($yScale);
  991. $this->_addProcSet('PDF');
  992. $this->_contents .= $xScaleObj->toString() . ' 0 0 ' . $yScaleObj->toString() . " 0 0 cm\n";
  993. return $this;
  994. }
  995. /**
  996. * Translate coordination system.
  997. *
  998. * @param float $xShift - X coordinate shift
  999. * @param float $yShift - Y coordinate shift
  1000. * @return Zend_Pdf_Canvas_Interface
  1001. */
  1002. public function translate($xShift, $yShift)
  1003. {
  1004. $xShiftObj = new Zend_Pdf_Element_Numeric($xShift);
  1005. $yShiftObj = new Zend_Pdf_Element_Numeric($yShift);
  1006. $this->_addProcSet('PDF');
  1007. $this->_contents .= '1 0 0 1 ' . $xShiftObj->toString() . ' ' . $yShiftObj->toString() . " cm\n";
  1008. return $this;
  1009. }
  1010. /**
  1011. * Translate coordination system.
  1012. *
  1013. * @param float $x - the X co-ordinate of axis skew point
  1014. * @param float $y - the Y co-ordinate of axis skew point
  1015. * @param float $xAngle - X axis skew angle
  1016. * @param float $yAngle - Y axis skew angle
  1017. * @return Zend_Pdf_Canvas_Interface
  1018. */
  1019. public function skew($x, $y, $xAngle, $yAngle)
  1020. {
  1021. $tanXObj = new Zend_Pdf_Element_Numeric(tan($xAngle));
  1022. $tanYObj = new Zend_Pdf_Element_Numeric(-tan($yAngle));
  1023. $xObj = new Zend_Pdf_Element_Numeric($x);
  1024. $yObj = new Zend_Pdf_Element_Numeric($y);
  1025. $mXObj = new Zend_Pdf_Element_Numeric(-$x);
  1026. $mYObj = new Zend_Pdf_Element_Numeric(-$y);
  1027. $this->_addProcSet('PDF');
  1028. $this->_contents .= '1 0 0 1 ' . $xObj->toString() . ' ' . $yObj->toString() . " cm\n"
  1029. . '1 ' . $tanXObj->toString() . ' ' . $tanYObj->toString() . " 1 0 0 cm\n"
  1030. . '1 0 0 1 ' . $mXObj->toString() . ' ' . $mYObj->toString() . " cm\n";
  1031. return $this;
  1032. }
  1033. /**
  1034. * Writes the raw data to the page's content stream.
  1035. *
  1036. * Be sure to consult the PDF reference to ensure your syntax is correct. No
  1037. * attempt is made to ensure the validity of the stream data.
  1038. *
  1039. * @param string $data
  1040. * @param string $procSet (optional) Name of ProcSet to add.
  1041. * @return Zend_Pdf_Canvas_Interface
  1042. */
  1043. public function rawWrite($data, $procSet = null)
  1044. {
  1045. if (! empty($procSet)) {
  1046. $this->_addProcSet($procSet);
  1047. }
  1048. $this->_contents .= $data;
  1049. return $this;
  1050. }
  1051. }