File indexing completed on 2025-01-19 05:21:20
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Pdf 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id: Style.php 20096 2010-01-06 02:05:09Z bkarwin $ 0020 */ 0021 0022 // require_once 'Zend/Pdf/Canvas/Interface.php'; 0023 0024 /** Internally used classes */ 0025 // require_once 'Zend/Pdf/Element.php'; 0026 // require_once 'Zend/Pdf/Element/Array.php'; 0027 // require_once 'Zend/Pdf/Element/String/Binary.php'; 0028 // require_once 'Zend/Pdf/Element/Boolean.php'; 0029 // require_once 'Zend/Pdf/Element/Dictionary.php'; 0030 // require_once 'Zend/Pdf/Element/Name.php'; 0031 // require_once 'Zend/Pdf/Element/Null.php'; 0032 // require_once 'Zend/Pdf/Element/Numeric.php'; 0033 // require_once 'Zend/Pdf/Element/String.php'; 0034 // require_once 'Zend/Pdf/Resource/GraphicsState.php'; 0035 // require_once 'Zend/Pdf/Resource/Font.php'; 0036 // require_once 'Zend/Pdf/Resource/Image.php'; 0037 0038 0039 /** 0040 * Canvas is an abstract rectangle drawing area which can be dropped into 0041 * page object at specified place. 0042 * 0043 * @package Zend_Pdf 0044 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0045 * @license http://framework.zend.com/license/new-bsd New BSD License 0046 */ 0047 abstract class Zend_Pdf_Canvas_Abstract implements Zend_Pdf_Canvas_Interface 0048 { 0049 /** 0050 * Drawing instructions 0051 * 0052 * @var string 0053 */ 0054 protected $_contents = ''; 0055 0056 /** 0057 * Current font 0058 * 0059 * @var Zend_Pdf_Resource_Font 0060 */ 0061 protected $_font = null; 0062 0063 /** 0064 * Current font size 0065 * 0066 * @var float 0067 */ 0068 protected $_fontSize; 0069 0070 /** 0071 * Current style 0072 * 0073 * @var Zend_Pdf_Style 0074 */ 0075 protected $_style = null; 0076 0077 0078 /** 0079 * Counter for the "Save" operations 0080 * 0081 * @var integer 0082 */ 0083 protected $_saveCount = 0; 0084 0085 0086 /** 0087 * Add procedureSet to the Page description 0088 * 0089 * @param string $procSetName 0090 */ 0091 abstract protected function _addProcSet($procSetName); 0092 0093 /** 0094 * Attach resource to the canvas 0095 * 0096 * Method returns a name of the resource which can be used 0097 * as a resource reference within drawing instructions stream 0098 * Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading', 0099 * 'XObject', 'Font', 'Properties' 0100 * 0101 * @param string $type 0102 * @param Zend_Pdf_Resource $resource 0103 * @return string 0104 */ 0105 abstract protected function _attachResource($type, Zend_Pdf_Resource $resource); 0106 0107 /** 0108 * Draw a canvas at the specified location 0109 * 0110 * If upper right corner is not specified then canvas heght and width 0111 * are used. 0112 * 0113 * @param Zend_Pdf_Canvas_Interface $canvas 0114 * @param float $x1 0115 * @param float $y1 0116 * @param float $x2 0117 * @param float $y2 0118 * @return Zend_Pdf_Canvas_Interface 0119 */ 0120 public function drawCanvas(Zend_Pdf_Canvas_Interface $canvas, $x1, $y1, $x2 = null, $y2 = null) 0121 { 0122 $this->saveGS(); 0123 0124 $this->translate($x1, $y1); 0125 0126 if ($x2 === null) { 0127 $with = $canvas->getWidth(); 0128 } else { 0129 $with = $x2 - $x1; 0130 } 0131 if ($y2 === null) { 0132 $height = $canvas->getHeight(); 0133 } else { 0134 $height = $y2 - $y1; 0135 } 0136 0137 $this->clipRectangle(0, 0, $with, $height); 0138 0139 if ($x2 !== null || $y2 !== null) { 0140 // Drawn canvas has to be scaled. 0141 if ($x2 !== null) { 0142 $xScale = $with/$canvas->getWidth(); 0143 } else { 0144 $xScale = 1; 0145 } 0146 0147 if ($y2 !== null) { 0148 $yScale = $height/$canvas->getHeight(); 0149 } else { 0150 $yScale = 1; 0151 } 0152 0153 $this->scale($xScale, $yScale); 0154 } 0155 0156 $contentsToDraw = $canvas->getContents(); 0157 /** @todo implementation */ 0158 0159 $this->restoreGS(); 0160 0161 return $this; 0162 } 0163 0164 /** 0165 * Set fill color. 0166 * 0167 * @param Zend_Pdf_Color $color 0168 * @return Zend_Pdf_Canvas_Interface 0169 */ 0170 public function setFillColor(Zend_Pdf_Color $color) 0171 { 0172 $this->_addProcSet('PDF'); 0173 $this->_contents .= $color->instructions(false); 0174 0175 return $this; 0176 } 0177 0178 /** 0179 * Set line color. 0180 * 0181 * @param Zend_Pdf_Color $color 0182 * @return Zend_Pdf_Canvas_Interface 0183 */ 0184 public function setLineColor(Zend_Pdf_Color $color) 0185 { 0186 $this->_addProcSet('PDF'); 0187 $this->_contents .= $color->instructions(true); 0188 0189 return $this; 0190 } 0191 0192 /** 0193 * Set line width. 0194 * 0195 * @param float $width 0196 * @return Zend_Pdf_Canvas_Interface 0197 */ 0198 public function setLineWidth($width) 0199 { 0200 $this->_addProcSet('PDF'); 0201 $widthObj = new Zend_Pdf_Element_Numeric($width); 0202 $this->_contents .= $widthObj->toString() . " w\n"; 0203 0204 return $this; 0205 } 0206 0207 /** 0208 * Set line dashing pattern 0209 * 0210 * Pattern is an array of floats: array(on_length, off_length, on_length, off_length, ...) 0211 * or Zend_Pdf_Page::LINE_DASHING_SOLID constant 0212 * Phase is shift from the beginning of line. 0213 * 0214 * @param mixed $pattern 0215 * @param array $phase 0216 * @return Zend_Pdf_Canvas_Interface 0217 */ 0218 public function setLineDashingPattern($pattern, $phase = 0) 0219 { 0220 $this->_addProcSet('PDF'); 0221 0222 // require_once 'Zend/Pdf/Page.php'; 0223 if ($pattern === Zend_Pdf_Page::LINE_DASHING_SOLID) { 0224 $pattern = array(); 0225 $phase = 0; 0226 } 0227 0228 $dashPattern = new Zend_Pdf_Element_Array(); 0229 $phaseEleemnt = new Zend_Pdf_Element_Numeric($phase); 0230 0231 foreach ($pattern as $dashItem) { 0232 $dashElement = new Zend_Pdf_Element_Numeric($dashItem); 0233 $dashPattern->items[] = $dashElement; 0234 } 0235 0236 $this->_contents .= $dashPattern->toString() . ' ' 0237 . $phaseEleemnt->toString() . " d\n"; 0238 0239 return $this; 0240 } 0241 0242 /** 0243 * Set current font. 0244 * 0245 * @param Zend_Pdf_Resource_Font $font 0246 * @param float $fontSize 0247 * @return Zend_Pdf_Canvas_Interface 0248 */ 0249 public function setFont(Zend_Pdf_Resource_Font $font, $fontSize) 0250 { 0251 $this->_addProcSet('Text'); 0252 $fontName = $this->_attachResource('Font', $font); 0253 0254 $this->_font = $font; 0255 $this->_fontSize = $fontSize; 0256 0257 $fontNameObj = new Zend_Pdf_Element_Name($fontName); 0258 $fontSizeObj = new Zend_Pdf_Element_Numeric($fontSize); 0259 $this->_contents .= $fontNameObj->toString() . ' ' . $fontSizeObj->toString() . " Tf\n"; 0260 0261 return $this; 0262 } 0263 0264 /** 0265 * Set the style to use for future drawing operations on this page 0266 * 0267 * @param Zend_Pdf_Style $style 0268 * @return Zend_Pdf_Canvas_Interface 0269 */ 0270 public function setStyle(Zend_Pdf_Style $style) 0271 { 0272 $this->_addProcSet('Text'); 0273 $this->_addProcSet('PDF'); 0274 if ($style->getFont() !== null) { 0275 $this->setFont($style->getFont(), $style->getFontSize()); 0276 } 0277 $this->_contents .= $style->instructions($this->_dictionary->Resources); 0278 0279 $this->_style = $style; 0280 0281 return $this; 0282 } 0283 0284 /** 0285 * Get current font. 0286 * 0287 * @return Zend_Pdf_Resource_Font $font 0288 */ 0289 public function getFont() 0290 { 0291 return $this->_font; 0292 } 0293 0294 /** 0295 * Get current font size 0296 * 0297 * @return float $fontSize 0298 */ 0299 public function getFontSize() 0300 { 0301 return $this->_fontSize; 0302 } 0303 0304 /** 0305 * Return the style, applied to the page. 0306 * 0307 * @return Zend_Pdf_Style 0308 */ 0309 public function getStyle() 0310 { 0311 return $this->_style; 0312 } 0313 0314 /** 0315 * Save the graphics state of this page. 0316 * This takes a snapshot of the currently applied style, position, clipping area and 0317 * any rotation/translation/scaling that has been applied. 0318 * 0319 * @todo check for the open paths 0320 * @throws Zend_Pdf_Exception - if a save is performed with an open path 0321 * @return Zend_Pdf_Canvas_Interface 0322 */ 0323 public function saveGS() 0324 { 0325 $this->_saveCount++; 0326 0327 $this->_addProcSet('PDF'); 0328 $this->_contents .= " q\n"; 0329 0330 return $this; 0331 } 0332 0333 /** 0334 * Restore the graphics state that was saved with the last call to saveGS(). 0335 * 0336 * @throws Zend_Pdf_Exception - if there is no previously saved state 0337 * @return Zend_Pdf_Canvas_Interface 0338 */ 0339 public function restoreGS() 0340 { 0341 if ($this->_saveCount-- <= 0) { 0342 // require_once 'Zend/Pdf/Exception.php'; 0343 throw new Zend_Pdf_Exception('Restoring graphics state which is not saved'); 0344 } 0345 $this->_contents .= " Q\n"; 0346 0347 return $this; 0348 } 0349 0350 /** 0351 * Set the transparancy 0352 * 0353 * $alpha == 0 - transparent 0354 * $alpha == 1 - opaque 0355 * 0356 * Transparency modes, supported by PDF: 0357 * Normal (default), Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, 0358 * SoftLight, Difference, Exclusion 0359 * 0360 * @param float $alpha 0361 * @param string $mode 0362 * @return Zend_Pdf_Canvas_Interface 0363 */ 0364 public function setAlpha($alpha, $mode = 'Normal') 0365 { 0366 $this->_addProcSet('Text'); 0367 $this->_addProcSet('PDF'); 0368 0369 $graphicsState = new Zend_Pdf_Resource_GraphicsState(); 0370 0371 $graphicsState->setAlpha($alpha, $mode); 0372 $gStateName = $this->_attachResource('ExtGState', $graphicsState); 0373 0374 $gStateNameObject = new Zend_Pdf_Element_Name($gStateName); 0375 $this->_contents .= $gStateNameObject->toString() . " gs\n"; 0376 0377 return $this; 0378 } 0379 0380 /** 0381 * Intersect current clipping area with a circle. 0382 * 0383 * @param float $x 0384 * @param float $y 0385 * @param float $radius 0386 * @param float $startAngle 0387 * @param float $endAngle 0388 * @return Zend_Pdf_Canvas_Interface 0389 */ 0390 public function clipCircle($x, $y, $radius, $startAngle = null, $endAngle = null) 0391 { 0392 $this->clipEllipse($x - $radius, $y - $radius, 0393 $x + $radius, $y + $radius, 0394 $startAngle, $endAngle); 0395 0396 return $this; 0397 } 0398 0399 /** 0400 * Intersect current clipping area with a polygon. 0401 * 0402 * Method signatures: 0403 * drawEllipse($x1, $y1, $x2, $y2); 0404 * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle); 0405 * 0406 * @todo process special cases with $x2-$x1 == 0 or $y2-$y1 == 0 0407 * 0408 * @param float $x1 0409 * @param float $y1 0410 * @param float $x2 0411 * @param float $y2 0412 * @param float $startAngle 0413 * @param float $endAngle 0414 * @return Zend_Pdf_Canvas_Interface 0415 */ 0416 public function clipEllipse($x1, $y1, $x2, $y2, $startAngle = null, $endAngle = null) 0417 { 0418 $this->_addProcSet('PDF'); 0419 0420 if ($x2 < $x1) { 0421 $temp = $x1; 0422 $x1 = $x2; 0423 $x2 = $temp; 0424 } 0425 if ($y2 < $y1) { 0426 $temp = $y1; 0427 $y1 = $y2; 0428 $y2 = $temp; 0429 } 0430 0431 $x = ($x1 + $x2)/2.; 0432 $y = ($y1 + $y2)/2.; 0433 0434 $xC = new Zend_Pdf_Element_Numeric($x); 0435 $yC = new Zend_Pdf_Element_Numeric($y); 0436 0437 if ($startAngle !== null) { 0438 if ($startAngle != 0) { $startAngle = fmod($startAngle, M_PI*2); } 0439 if ($endAngle != 0) { $endAngle = fmod($endAngle, M_PI*2); } 0440 0441 if ($startAngle > $endAngle) { 0442 $endAngle += M_PI*2; 0443 } 0444 0445 $clipPath = $xC->toString() . ' ' . $yC->toString() . " m\n"; 0446 $clipSectors = (int)ceil(($endAngle - $startAngle)/M_PI_4); 0447 $clipRadius = max($x2 - $x1, $y2 - $y1); 0448 0449 for($count = 0; $count <= $clipSectors; $count++) { 0450 $pAngle = $startAngle + ($endAngle - $startAngle)*$count/(float)$clipSectors; 0451 0452 $pX = new Zend_Pdf_Element_Numeric($x + cos($pAngle)*$clipRadius); 0453 $pY = new Zend_Pdf_Element_Numeric($y + sin($pAngle)*$clipRadius); 0454 $clipPath .= $pX->toString() . ' ' . $pY->toString() . " l\n"; 0455 } 0456 0457 $this->_contents .= $clipPath . "h\nW\nn\n"; 0458 } 0459 0460 $xLeft = new Zend_Pdf_Element_Numeric($x1); 0461 $xRight = new Zend_Pdf_Element_Numeric($x2); 0462 $yUp = new Zend_Pdf_Element_Numeric($y2); 0463 $yDown = new Zend_Pdf_Element_Numeric($y1); 0464 0465 $xDelta = 2*(M_SQRT2 - 1)*($x2 - $x1)/3.; 0466 $yDelta = 2*(M_SQRT2 - 1)*($y2 - $y1)/3.; 0467 $xr = new Zend_Pdf_Element_Numeric($x + $xDelta); 0468 $xl = new Zend_Pdf_Element_Numeric($x - $xDelta); 0469 $yu = new Zend_Pdf_Element_Numeric($y + $yDelta); 0470 $yd = new Zend_Pdf_Element_Numeric($y - $yDelta); 0471 0472 $this->_contents .= $xC->toString() . ' ' . $yUp->toString() . " m\n" 0473 . $xr->toString() . ' ' . $yUp->toString() . ' ' 0474 . $xRight->toString() . ' ' . $yu->toString() . ' ' 0475 . $xRight->toString() . ' ' . $yC->toString() . " c\n" 0476 . $xRight->toString() . ' ' . $yd->toString() . ' ' 0477 . $xr->toString() . ' ' . $yDown->toString() . ' ' 0478 . $xC->toString() . ' ' . $yDown->toString() . " c\n" 0479 . $xl->toString() . ' ' . $yDown->toString() . ' ' 0480 . $xLeft->toString() . ' ' . $yd->toString() . ' ' 0481 . $xLeft->toString() . ' ' . $yC->toString() . " c\n" 0482 . $xLeft->toString() . ' ' . $yu->toString() . ' ' 0483 . $xl->toString() . ' ' . $yUp->toString() . ' ' 0484 . $xC->toString() . ' ' . $yUp->toString() . " c\n" 0485 . "h\nW\nn\n"; 0486 0487 return $this; 0488 } 0489 0490 /** 0491 * Intersect current clipping area with a polygon. 0492 * 0493 * @param array $x - array of float (the X co-ordinates of the vertices) 0494 * @param array $y - array of float (the Y co-ordinates of the vertices) 0495 * @param integer $fillMethod 0496 * @return Zend_Pdf_Canvas_Interface 0497 */ 0498 public function clipPolygon($x, $y, $fillMethod = Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) 0499 { 0500 $this->_addProcSet('PDF'); 0501 0502 $firstPoint = true; 0503 foreach ($x as $id => $xVal) { 0504 $xObj = new Zend_Pdf_Element_Numeric($xVal); 0505 $yObj = new Zend_Pdf_Element_Numeric($y[$id]); 0506 0507 if ($firstPoint) { 0508 $path = $xObj->toString() . ' ' . $yObj->toString() . " m\n"; 0509 $firstPoint = false; 0510 } else { 0511 $path .= $xObj->toString() . ' ' . $yObj->toString() . " l\n"; 0512 } 0513 } 0514 0515 $this->_contents .= $path; 0516 0517 if ($fillMethod == Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) { 0518 $this->_contents .= " h\n W\nn\n"; 0519 } else { 0520 // Even-Odd fill method. 0521 $this->_contents .= " h\n W*\nn\n"; 0522 } 0523 0524 return $this; 0525 } 0526 0527 /** 0528 * Intersect current clipping area with a rectangle. 0529 * 0530 * @param float $x1 0531 * @param float $y1 0532 * @param float $x2 0533 * @param float $y2 0534 * @return Zend_Pdf_Canvas_Interface 0535 */ 0536 public function clipRectangle($x1, $y1, $x2, $y2) 0537 { 0538 $this->_addProcSet('PDF'); 0539 0540 $x1Obj = new Zend_Pdf_Element_Numeric($x1); 0541 $y1Obj = new Zend_Pdf_Element_Numeric($y1); 0542 $widthObj = new Zend_Pdf_Element_Numeric($x2 - $x1); 0543 $height2Obj = new Zend_Pdf_Element_Numeric($y2 - $y1); 0544 0545 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' ' 0546 . $widthObj->toString() . ' ' . $height2Obj->toString() . " re\n" 0547 . " W\nn\n"; 0548 0549 return $this; 0550 } 0551 0552 // ------------------------------------------------------------------------------------------ 0553 /** 0554 * Draw a circle centered on x, y with a radius of radius. 0555 * 0556 * Method signatures: 0557 * drawCircle($x, $y, $radius); 0558 * drawCircle($x, $y, $radius, $fillType); 0559 * drawCircle($x, $y, $radius, $startAngle, $endAngle); 0560 * drawCircle($x, $y, $radius, $startAngle, $endAngle, $fillType); 0561 * 0562 * 0563 * It's not a really circle, because PDF supports only cubic Bezier curves. 0564 * But _very_ good approximation. 0565 * It differs from a real circle on a maximum 0.00026 radiuses 0566 * (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). 0567 * 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. 0568 * 0569 * @param float $x 0570 * @param float $y 0571 * @param float $radius 0572 * @param mixed $param4 0573 * @param mixed $param5 0574 * @param mixed $param6 0575 * @return Zend_Pdf_Canvas_Interface 0576 */ 0577 public function drawCircle($x, $y, $radius, $param4 = null, $param5 = null, $param6 = null) 0578 { 0579 $this->drawEllipse($x - $radius, $y - $radius, 0580 $x + $radius, $y + $radius, 0581 $param4, $param5, $param6); 0582 0583 return $this; 0584 } 0585 0586 /** 0587 * Draw an ellipse inside the specified rectangle. 0588 * 0589 * Method signatures: 0590 * drawEllipse($x1, $y1, $x2, $y2); 0591 * drawEllipse($x1, $y1, $x2, $y2, $fillType); 0592 * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle); 0593 * drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle, $fillType); 0594 * 0595 * @todo process special cases with $x2-$x1 == 0 or $y2-$y1 == 0 0596 * 0597 * @param float $x1 0598 * @param float $y1 0599 * @param float $x2 0600 * @param float $y2 0601 * @param mixed $param5 0602 * @param mixed $param6 0603 * @param mixed $param7 0604 * @return Zend_Pdf_Canvas_Interface 0605 */ 0606 public function drawEllipse($x1, $y1, $x2, $y2, $param5 = null, $param6 = null, $param7 = null) 0607 { 0608 if ($param5 === null) { 0609 // drawEllipse($x1, $y1, $x2, $y2); 0610 $startAngle = null; 0611 $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE; 0612 } else if ($param6 === null) { 0613 // drawEllipse($x1, $y1, $x2, $y2, $fillType); 0614 $startAngle = null; 0615 $fillType = $param5; 0616 } else { 0617 // drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle); 0618 // drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle, $fillType); 0619 $startAngle = $param5; 0620 $endAngle = $param6; 0621 0622 if ($param7 === null) { 0623 $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE; 0624 } else { 0625 $fillType = $param7; 0626 } 0627 } 0628 0629 $this->_addProcSet('PDF'); 0630 0631 if ($x2 < $x1) { 0632 $temp = $x1; 0633 $x1 = $x2; 0634 $x2 = $temp; 0635 } 0636 if ($y2 < $y1) { 0637 $temp = $y1; 0638 $y1 = $y2; 0639 $y2 = $temp; 0640 } 0641 0642 $x = ($x1 + $x2)/2.; 0643 $y = ($y1 + $y2)/2.; 0644 0645 $xC = new Zend_Pdf_Element_Numeric($x); 0646 $yC = new Zend_Pdf_Element_Numeric($y); 0647 0648 if ($startAngle !== null) { 0649 if ($startAngle != 0) { $startAngle = fmod($startAngle, M_PI*2); } 0650 if ($endAngle != 0) { $endAngle = fmod($endAngle, M_PI*2); } 0651 0652 if ($startAngle > $endAngle) { 0653 $endAngle += M_PI*2; 0654 } 0655 0656 $clipPath = $xC->toString() . ' ' . $yC->toString() . " m\n"; 0657 $clipSectors = (int)ceil(($endAngle - $startAngle)/M_PI_4); 0658 $clipRadius = max($x2 - $x1, $y2 - $y1); 0659 0660 for($count = 0; $count <= $clipSectors; $count++) { 0661 $pAngle = $startAngle + ($endAngle - $startAngle)*$count/(float)$clipSectors; 0662 0663 $pX = new Zend_Pdf_Element_Numeric($x + cos($pAngle)*$clipRadius); 0664 $pY = new Zend_Pdf_Element_Numeric($y + sin($pAngle)*$clipRadius); 0665 $clipPath .= $pX->toString() . ' ' . $pY->toString() . " l\n"; 0666 } 0667 0668 $this->_contents .= "q\n" . $clipPath . "h\nW\nn\n"; 0669 } 0670 0671 $xLeft = new Zend_Pdf_Element_Numeric($x1); 0672 $xRight = new Zend_Pdf_Element_Numeric($x2); 0673 $yUp = new Zend_Pdf_Element_Numeric($y2); 0674 $yDown = new Zend_Pdf_Element_Numeric($y1); 0675 0676 $xDelta = 2*(M_SQRT2 - 1)*($x2 - $x1)/3.; 0677 $yDelta = 2*(M_SQRT2 - 1)*($y2 - $y1)/3.; 0678 $xr = new Zend_Pdf_Element_Numeric($x + $xDelta); 0679 $xl = new Zend_Pdf_Element_Numeric($x - $xDelta); 0680 $yu = new Zend_Pdf_Element_Numeric($y + $yDelta); 0681 $yd = new Zend_Pdf_Element_Numeric($y - $yDelta); 0682 0683 $this->_contents .= $xC->toString() . ' ' . $yUp->toString() . " m\n" 0684 . $xr->toString() . ' ' . $yUp->toString() . ' ' 0685 . $xRight->toString() . ' ' . $yu->toString() . ' ' 0686 . $xRight->toString() . ' ' . $yC->toString() . " c\n" 0687 . $xRight->toString() . ' ' . $yd->toString() . ' ' 0688 . $xr->toString() . ' ' . $yDown->toString() . ' ' 0689 . $xC->toString() . ' ' . $yDown->toString() . " c\n" 0690 . $xl->toString() . ' ' . $yDown->toString() . ' ' 0691 . $xLeft->toString() . ' ' . $yd->toString() . ' ' 0692 . $xLeft->toString() . ' ' . $yC->toString() . " c\n" 0693 . $xLeft->toString() . ' ' . $yu->toString() . ' ' 0694 . $xl->toString() . ' ' . $yUp->toString() . ' ' 0695 . $xC->toString() . ' ' . $yUp->toString() . " c\n"; 0696 0697 switch ($fillType) { 0698 case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE: 0699 $this->_contents .= " B*\n"; 0700 break; 0701 case Zend_Pdf_Page::SHAPE_DRAW_FILL: 0702 $this->_contents .= " f*\n"; 0703 break; 0704 case Zend_Pdf_Page::SHAPE_DRAW_STROKE: 0705 $this->_contents .= " S\n"; 0706 break; 0707 } 0708 0709 if ($startAngle !== null) { 0710 $this->_contents .= "Q\n"; 0711 } 0712 0713 return $this; 0714 } 0715 0716 /** 0717 * Draw an image at the specified position on the page. 0718 * 0719 * @param Zend_Pdf_Image $image 0720 * @param float $x1 0721 * @param float $y1 0722 * @param float $x2 0723 * @param float $y2 0724 * @return Zend_Pdf_Canvas_Interface 0725 */ 0726 public function drawImage(Zend_Pdf_Resource_Image $image, $x1, $y1, $x2, $y2) 0727 { 0728 $this->_addProcSet('PDF'); 0729 0730 $imageName = $this->_attachResource('XObject', $image); 0731 $imageNameObj = new Zend_Pdf_Element_Name($imageName); 0732 0733 $x1Obj = new Zend_Pdf_Element_Numeric($x1); 0734 $y1Obj = new Zend_Pdf_Element_Numeric($y1); 0735 $widthObj = new Zend_Pdf_Element_Numeric($x2 - $x1); 0736 $heightObj = new Zend_Pdf_Element_Numeric($y2 - $y1); 0737 0738 $this->_contents .= "q\n" 0739 . '1 0 0 1 ' . $x1Obj->toString() . ' ' . $y1Obj->toString() . " cm\n" 0740 . $widthObj->toString() . ' 0 0 ' . $heightObj->toString() . " 0 0 cm\n" 0741 . $imageNameObj->toString() . " Do\n" 0742 . "Q\n"; 0743 0744 return $this; 0745 } 0746 0747 /** 0748 * Draw a LayoutBox at the specified position on the page. 0749 * 0750 * @internal (not implemented now) 0751 * 0752 * @param Zend_Pdf_Element_LayoutBox $box 0753 * @param float $x 0754 * @param float $y 0755 * @return Zend_Pdf_Canvas_Interface 0756 */ 0757 public function drawLayoutBox($box, $x, $y) 0758 { 0759 /** @todo implementation */ 0760 return $this; 0761 } 0762 0763 /** 0764 * Draw a line from x1,y1 to x2,y2. 0765 * 0766 * @param float $x1 0767 * @param float $y1 0768 * @param float $x2 0769 * @param float $y2 0770 * @return Zend_Pdf_Canvas_Interface 0771 */ 0772 public function drawLine($x1, $y1, $x2, $y2) 0773 { 0774 $this->_addProcSet('PDF'); 0775 0776 $x1Obj = new Zend_Pdf_Element_Numeric($x1); 0777 $y1Obj = new Zend_Pdf_Element_Numeric($y1); 0778 $x2Obj = new Zend_Pdf_Element_Numeric($x2); 0779 $y2Obj = new Zend_Pdf_Element_Numeric($y2); 0780 0781 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " m\n" 0782 . $x2Obj->toString() . ' ' . $y2Obj->toString() . " l\n S\n"; 0783 0784 return $this; 0785 } 0786 0787 /** 0788 * Draw a polygon. 0789 * 0790 * If $fillType is Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE or 0791 * Zend_Pdf_Page::SHAPE_DRAW_FILL, then polygon is automatically closed. 0792 * See detailed description of these methods in a PDF documentation 0793 * (section 4.4.2 Path painting Operators, Filling) 0794 * 0795 * @param array $x - array of float (the X co-ordinates of the vertices) 0796 * @param array $y - array of float (the Y co-ordinates of the vertices) 0797 * @param integer $fillType 0798 * @param integer $fillMethod 0799 * @return Zend_Pdf_Canvas_Interface 0800 */ 0801 public function drawPolygon($x, $y, 0802 $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE, 0803 $fillMethod = Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) 0804 { 0805 $this->_addProcSet('PDF'); 0806 0807 $firstPoint = true; 0808 foreach ($x as $id => $xVal) { 0809 $xObj = new Zend_Pdf_Element_Numeric($xVal); 0810 $yObj = new Zend_Pdf_Element_Numeric($y[$id]); 0811 0812 if ($firstPoint) { 0813 $path = $xObj->toString() . ' ' . $yObj->toString() . " m\n"; 0814 $firstPoint = false; 0815 } else { 0816 $path .= $xObj->toString() . ' ' . $yObj->toString() . " l\n"; 0817 } 0818 } 0819 0820 $this->_contents .= $path; 0821 0822 switch ($fillType) { 0823 case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE: 0824 if ($fillMethod == Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) { 0825 $this->_contents .= " b\n"; 0826 } else { 0827 // Even-Odd fill method. 0828 $this->_contents .= " b*\n"; 0829 } 0830 break; 0831 case Zend_Pdf_Page::SHAPE_DRAW_FILL: 0832 if ($fillMethod == Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING) { 0833 $this->_contents .= " h\n f\n"; 0834 } else { 0835 // Even-Odd fill method. 0836 $this->_contents .= " h\n f*\n"; 0837 } 0838 break; 0839 case Zend_Pdf_Page::SHAPE_DRAW_STROKE: 0840 $this->_contents .= " S\n"; 0841 break; 0842 } 0843 0844 return $this; 0845 } 0846 0847 /** 0848 * Draw a rectangle. 0849 * 0850 * Fill types: 0851 * Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - fill rectangle and stroke (default) 0852 * Zend_Pdf_Page::SHAPE_DRAW_STROKE - stroke rectangle 0853 * Zend_Pdf_Page::SHAPE_DRAW_FILL - fill rectangle 0854 * 0855 * @param float $x1 0856 * @param float $y1 0857 * @param float $x2 0858 * @param float $y2 0859 * @param integer $fillType 0860 * @return Zend_Pdf_Canvas_Interface 0861 */ 0862 public function drawRectangle($x1, $y1, $x2, $y2, $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE) 0863 { 0864 $this->_addProcSet('PDF'); 0865 0866 $x1Obj = new Zend_Pdf_Element_Numeric($x1); 0867 $y1Obj = new Zend_Pdf_Element_Numeric($y1); 0868 $widthObj = new Zend_Pdf_Element_Numeric($x2 - $x1); 0869 $height2Obj = new Zend_Pdf_Element_Numeric($y2 - $y1); 0870 0871 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' ' 0872 . $widthObj->toString() . ' ' . $height2Obj->toString() . " re\n"; 0873 0874 switch ($fillType) { 0875 case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE: 0876 $this->_contents .= " B*\n"; 0877 break; 0878 case Zend_Pdf_Page::SHAPE_DRAW_FILL: 0879 $this->_contents .= " f*\n"; 0880 break; 0881 case Zend_Pdf_Page::SHAPE_DRAW_STROKE: 0882 $this->_contents .= " S\n"; 0883 break; 0884 } 0885 0886 return $this; 0887 } 0888 0889 /** 0890 * Draw a rounded rectangle. 0891 * 0892 * Fill types: 0893 * Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - fill rectangle and stroke (default) 0894 * Zend_Pdf_Page::SHAPE_DRAW_STROKE - stroke rectangle 0895 * Zend_Pdf_Page::SHAPE_DRAW_FILL - fill rectangle 0896 * 0897 * radius is an integer representing radius of the four corners, or an array 0898 * of four integers representing the radius starting at top left, going 0899 * clockwise 0900 * 0901 * @param float $x1 0902 * @param float $y1 0903 * @param float $x2 0904 * @param float $y2 0905 * @param integer|array $radius 0906 * @param integer $fillType 0907 * @return Zend_Pdf_Canvas_Interface 0908 */ 0909 public function drawRoundedRectangle($x1, $y1, $x2, $y2, $radius, 0910 $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE) 0911 { 0912 0913 $this->_addProcSet('PDF'); 0914 0915 if(!is_array($radius)) { 0916 $radius = array($radius, $radius, $radius, $radius); 0917 } else { 0918 for ($i = 0; $i < 4; $i++) { 0919 if(!isset($radius[$i])) { 0920 $radius[$i] = 0; 0921 } 0922 } 0923 } 0924 0925 $topLeftX = $x1; 0926 $topLeftY = $y2; 0927 $topRightX = $x2; 0928 $topRightY = $y2; 0929 $bottomRightX = $x2; 0930 $bottomRightY = $y1; 0931 $bottomLeftX = $x1; 0932 $bottomLeftY = $y1; 0933 0934 //draw top side 0935 $x1Obj = new Zend_Pdf_Element_Numeric($topLeftX + $radius[0]); 0936 $y1Obj = new Zend_Pdf_Element_Numeric($topLeftY); 0937 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " m\n"; 0938 $x1Obj = new Zend_Pdf_Element_Numeric($topRightX - $radius[1]); 0939 $y1Obj = new Zend_Pdf_Element_Numeric($topRightY); 0940 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n"; 0941 0942 //draw top right corner if needed 0943 if ($radius[1] != 0) { 0944 $x1Obj = new Zend_Pdf_Element_Numeric($topRightX); 0945 $y1Obj = new Zend_Pdf_Element_Numeric($topRightY); 0946 $x2Obj = new Zend_Pdf_Element_Numeric($topRightX); 0947 $y2Obj = new Zend_Pdf_Element_Numeric($topRightY); 0948 $x3Obj = new Zend_Pdf_Element_Numeric($topRightX); 0949 $y3Obj = new Zend_Pdf_Element_Numeric($topRightY - $radius[1]); 0950 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' ' 0951 . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' ' 0952 . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' ' 0953 . " c\n"; 0954 } 0955 0956 //draw right side 0957 $x1Obj = new Zend_Pdf_Element_Numeric($bottomRightX); 0958 $y1Obj = new Zend_Pdf_Element_Numeric($bottomRightY + $radius[2]); 0959 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n"; 0960 0961 //draw bottom right corner if needed 0962 if ($radius[2] != 0) { 0963 $x1Obj = new Zend_Pdf_Element_Numeric($bottomRightX); 0964 $y1Obj = new Zend_Pdf_Element_Numeric($bottomRightY); 0965 $x2Obj = new Zend_Pdf_Element_Numeric($bottomRightX); 0966 $y2Obj = new Zend_Pdf_Element_Numeric($bottomRightY); 0967 $x3Obj = new Zend_Pdf_Element_Numeric($bottomRightX - $radius[2]); 0968 $y3Obj = new Zend_Pdf_Element_Numeric($bottomRightY); 0969 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' ' 0970 . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' ' 0971 . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' ' 0972 . " c\n"; 0973 } 0974 0975 //draw bottom side 0976 $x1Obj = new Zend_Pdf_Element_Numeric($bottomLeftX + $radius[3]); 0977 $y1Obj = new Zend_Pdf_Element_Numeric($bottomLeftY); 0978 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n"; 0979 0980 //draw bottom left corner if needed 0981 if ($radius[3] != 0) { 0982 $x1Obj = new Zend_Pdf_Element_Numeric($bottomLeftX); 0983 $y1Obj = new Zend_Pdf_Element_Numeric($bottomLeftY); 0984 $x2Obj = new Zend_Pdf_Element_Numeric($bottomLeftX); 0985 $y2Obj = new Zend_Pdf_Element_Numeric($bottomLeftY); 0986 $x3Obj = new Zend_Pdf_Element_Numeric($bottomLeftX); 0987 $y3Obj = new Zend_Pdf_Element_Numeric($bottomLeftY + $radius[3]); 0988 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' ' 0989 . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' ' 0990 . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' ' 0991 . " c\n"; 0992 } 0993 0994 //draw left side 0995 $x1Obj = new Zend_Pdf_Element_Numeric($topLeftX); 0996 $y1Obj = new Zend_Pdf_Element_Numeric($topLeftY - $radius[0]); 0997 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . " l\n"; 0998 0999 //draw top left corner if needed 1000 if ($radius[0] != 0) { 1001 $x1Obj = new Zend_Pdf_Element_Numeric($topLeftX); 1002 $y1Obj = new Zend_Pdf_Element_Numeric($topLeftY); 1003 $x2Obj = new Zend_Pdf_Element_Numeric($topLeftX); 1004 $y2Obj = new Zend_Pdf_Element_Numeric($topLeftY); 1005 $x3Obj = new Zend_Pdf_Element_Numeric($topLeftX + $radius[0]); 1006 $y3Obj = new Zend_Pdf_Element_Numeric($topLeftY); 1007 $this->_contents .= $x1Obj->toString() . ' ' . $y1Obj->toString() . ' ' 1008 . $x2Obj->toString() . ' ' . $y2Obj->toString() . ' ' 1009 . $x3Obj->toString() . ' ' . $y3Obj->toString() . ' ' 1010 . " c\n"; 1011 } 1012 1013 switch ($fillType) { 1014 case Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE: 1015 $this->_contents .= " B*\n"; 1016 break; 1017 case Zend_Pdf_Page::SHAPE_DRAW_FILL: 1018 $this->_contents .= " f*\n"; 1019 break; 1020 case Zend_Pdf_Page::SHAPE_DRAW_STROKE: 1021 $this->_contents .= " S\n"; 1022 break; 1023 } 1024 1025 return $this; 1026 } 1027 1028 /** 1029 * Draw a line of text at the specified position. 1030 * 1031 * @param string $text 1032 * @param float $x 1033 * @param float $y 1034 * @param string $charEncoding (optional) Character encoding of source text. 1035 * Defaults to current locale. 1036 * @throws Zend_Pdf_Exception 1037 * @return Zend_Pdf_Canvas_Interface 1038 */ 1039 public function drawText($text, $x, $y, $charEncoding = '') 1040 { 1041 if ($this->_font === null) { 1042 // require_once 'Zend/Pdf/Exception.php'; 1043 throw new Zend_Pdf_Exception('Font has not been set'); 1044 } 1045 1046 $this->_addProcSet('Text'); 1047 1048 $textObj = new Zend_Pdf_Element_String($this->_font->encodeString($text, $charEncoding)); 1049 $xObj = new Zend_Pdf_Element_Numeric($x); 1050 $yObj = new Zend_Pdf_Element_Numeric($y); 1051 1052 $this->_contents .= "BT\n" 1053 . $xObj->toString() . ' ' . $yObj->toString() . " Td\n" 1054 . $textObj->toString() . " Tj\n" 1055 . "ET\n"; 1056 1057 return $this; 1058 } 1059 1060 /** 1061 * Close the path by drawing a straight line back to it's beginning. 1062 * 1063 * @internal (needs implementation) 1064 * 1065 * @throws Zend_Pdf_Exception - if a path hasn't been started with pathMove() 1066 * @return Zend_Pdf_Canvas_Interface 1067 */ 1068 public function pathClose() 1069 { 1070 /** @todo implementation */ 1071 return $this; 1072 } 1073 1074 /** 1075 * Continue the open path in a straight line to the specified position. 1076 * 1077 * @internal (needs implementation) 1078 * 1079 * @param float $x - the X co-ordinate to move to 1080 * @param float $y - the Y co-ordinate to move to 1081 * @return Zend_Pdf_Canvas_Interface 1082 */ 1083 public function pathLine($x, $y) 1084 { 1085 /** @todo implementation */ 1086 return $this; 1087 } 1088 1089 /** 1090 * Start a new path at the specified position. If a path has already been started, 1091 * move the cursor without drawing a line. 1092 * 1093 * @internal (needs implementation) 1094 * 1095 * @param float $x - the X co-ordinate to move to 1096 * @param float $y - the Y co-ordinate to move to 1097 * @return Zend_Pdf_Canvas_Interface 1098 */ 1099 public function pathMove($x, $y) 1100 { 1101 /** @todo implementation */ 1102 return $this; 1103 } 1104 1105 /** 1106 * Rotate the page. 1107 * 1108 * @param float $x - the X co-ordinate of rotation point 1109 * @param float $y - the Y co-ordinate of rotation point 1110 * @param float $angle - rotation angle 1111 * @return Zend_Pdf_Canvas_Interface 1112 */ 1113 public function rotate($x, $y, $angle) 1114 { 1115 $cos = new Zend_Pdf_Element_Numeric(cos($angle)); 1116 $sin = new Zend_Pdf_Element_Numeric(sin($angle)); 1117 $mSin = new Zend_Pdf_Element_Numeric(-$sin->value); 1118 1119 $xObj = new Zend_Pdf_Element_Numeric($x); 1120 $yObj = new Zend_Pdf_Element_Numeric($y); 1121 1122 $mXObj = new Zend_Pdf_Element_Numeric(-$x); 1123 $mYObj = new Zend_Pdf_Element_Numeric(-$y); 1124 1125 1126 $this->_addProcSet('PDF'); 1127 $this->_contents .= '1 0 0 1 ' . $xObj->toString() . ' ' . $yObj->toString() . " cm\n" 1128 . $cos->toString() . ' ' . $sin->toString() . ' ' . $mSin->toString() . ' ' . $cos->toString() . " 0 0 cm\n" 1129 . '1 0 0 1 ' . $mXObj->toString() . ' ' . $mYObj->toString() . " cm\n"; 1130 1131 return $this; 1132 } 1133 1134 /** 1135 * Scale coordination system. 1136 * 1137 * @param float $xScale - X dimention scale factor 1138 * @param float $yScale - Y dimention scale factor 1139 * @return Zend_Pdf_Canvas_Interface 1140 */ 1141 public function scale($xScale, $yScale) 1142 { 1143 $xScaleObj = new Zend_Pdf_Element_Numeric($xScale); 1144 $yScaleObj = new Zend_Pdf_Element_Numeric($yScale); 1145 1146 $this->_addProcSet('PDF'); 1147 $this->_contents .= $xScaleObj->toString() . ' 0 0 ' . $yScaleObj->toString() . " 0 0 cm\n"; 1148 1149 return $this; 1150 } 1151 1152 /** 1153 * Translate coordination system. 1154 * 1155 * @param float $xShift - X coordinate shift 1156 * @param float $yShift - Y coordinate shift 1157 * @return Zend_Pdf_Canvas_Interface 1158 */ 1159 public function translate($xShift, $yShift) 1160 { 1161 $xShiftObj = new Zend_Pdf_Element_Numeric($xShift); 1162 $yShiftObj = new Zend_Pdf_Element_Numeric($yShift); 1163 1164 $this->_addProcSet('PDF'); 1165 $this->_contents .= '1 0 0 1 ' . $xShiftObj->toString() . ' ' . $yShiftObj->toString() . " cm\n"; 1166 1167 return $this; 1168 } 1169 1170 /** 1171 * Translate coordination system. 1172 * 1173 * @param float $x - the X co-ordinate of axis skew point 1174 * @param float $y - the Y co-ordinate of axis skew point 1175 * @param float $xAngle - X axis skew angle 1176 * @param float $yAngle - Y axis skew angle 1177 * @return Zend_Pdf_Canvas_Interface 1178 */ 1179 public function skew($x, $y, $xAngle, $yAngle) 1180 { 1181 $tanXObj = new Zend_Pdf_Element_Numeric(tan($xAngle)); 1182 $tanYObj = new Zend_Pdf_Element_Numeric(-tan($yAngle)); 1183 1184 $xObj = new Zend_Pdf_Element_Numeric($x); 1185 $yObj = new Zend_Pdf_Element_Numeric($y); 1186 1187 $mXObj = new Zend_Pdf_Element_Numeric(-$x); 1188 $mYObj = new Zend_Pdf_Element_Numeric(-$y); 1189 1190 $this->_addProcSet('PDF'); 1191 $this->_contents .= '1 0 0 1 ' . $xObj->toString() . ' ' . $yObj->toString() . " cm\n" 1192 . '1 ' . $tanXObj->toString() . ' ' . $tanYObj->toString() . " 1 0 0 cm\n" 1193 . '1 0 0 1 ' . $mXObj->toString() . ' ' . $mYObj->toString() . " cm\n"; 1194 1195 return $this; 1196 } 1197 1198 /** 1199 * Writes the raw data to the page's content stream. 1200 * 1201 * Be sure to consult the PDF reference to ensure your syntax is correct. No 1202 * attempt is made to ensure the validity of the stream data. 1203 * 1204 * @param string $data 1205 * @param string $procSet (optional) Name of ProcSet to add. 1206 * @return Zend_Pdf_Canvas_Interface 1207 */ 1208 public function rawWrite($data, $procSet = null) 1209 { 1210 if (! empty($procSet)) { 1211 $this->_addProcSet($procSet); 1212 } 1213 $this->_contents .= $data; 1214 1215 return $this; 1216 } 1217 }