5 // Copyright 2004-2014 Setasign - Jan Slabon
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
20 require_once('fpdi_bridge.php');
25 class FPDF_TPL
extends fpdi_bridge
28 * Array of template data
32 protected $_tpls = array();
46 protected $_inTpl = false;
49 * Name prefix of templates used in Resources dictionary
51 * @var string A String defining the Prefix used as Template-Object-Names. Have to begin with an /
53 public $tplPrefix = "/TPL";
56 * Resources used by templates and pages
60 protected $_res = array();
63 * Last used template data
67 public $lastUsedTemplateData = array();
72 * This method starts a template. You can give own coordinates to build an own sized
73 * template. Pay attention, that the margins are adapted to the new template size.
74 * If you want to write outside the template, for example to build a clipped template,
75 * you have to set the margins and "cursor"-position manual after beginTemplate()-call.
77 * If no parameter is given, the template uses the current page-size.
78 * The method returns an id of the current template. This id is used later for using this template.
79 * Warning: A created template is saved in the resulting PDF at all events. Also if you don't use it after creation!
81 * @param int $x The x-coordinate given in user-unit
82 * @param int $y The y-coordinate given in user-unit
83 * @param int $w The width given in user-unit
84 * @param int $h The height given in user-unit
85 * @return int The id of new created template
86 * @throws LogicException
88 public function beginTemplate($x = null, $y = null, $w = null, $h = null)
90 if (is_subclass_of($this, 'TCPDF')) {
91 throw new LogicException('This method is only usable with FPDF. Use TCPDF methods startTemplate() instead.');
94 if ($this->page
<= 0) {
95 throw new LogicException("You have to add at least a page first!");
109 $tpl =& $this->_tpls
[$this->tpl
];
113 'o_AutoPageBreak' => $this->AutoPageBreak
,
114 'o_bMargin' => $this->bMargin
,
115 'o_tMargin' => $this->tMargin
,
116 'o_lMargin' => $this->lMargin
,
117 'o_rMargin' => $this->rMargin
,
120 'o_FontFamily' => $this->FontFamily
,
121 'o_FontStyle' => $this->FontStyle
,
122 'o_FontSizePt' => $this->FontSizePt
,
123 'o_FontSize' => $this->FontSize
,
131 $this->SetAutoPageBreak(false);
133 // Define own high and width to calculate correct positions
137 $this->_inTpl
= true;
138 $this->SetXY($x +
$this->lMargin
, $y +
$this->tMargin
);
139 $this->SetRightMargin($this->w
- $w +
$this->rMargin
);
141 if ($this->CurrentFont
) {
142 $fontKey = $this->FontFamily
. $this->FontStyle
;
144 $this->_res
['tpl'][$this->tpl
]['fonts'][$fontKey] =& $this->fonts
[$fontKey];
145 $this->_out(sprintf('BT /F%d %.2f Tf ET', $this->CurrentFont
['i'], $this->FontSizePt
));
155 * This method ends a template and reset initiated variables collected in {@link beginTemplate()}.
157 * @return int|boolean If a template is opened, the id is returned. If not a false is returned.
159 public function endTemplate()
161 if (is_subclass_of($this, 'TCPDF')) {
162 $args = func_get_args();
163 return call_user_func_array(array($this, 'TCPDF::endTemplate'), $args);
167 $this->_inTpl
= false;
168 $tpl = $this->_tpls
[$this->tpl
];
169 $this->SetXY($tpl['o_x'], $tpl['o_y']);
170 $this->tMargin
= $tpl['o_tMargin'];
171 $this->lMargin
= $tpl['o_lMargin'];
172 $this->rMargin
= $tpl['o_rMargin'];
173 $this->h
= $tpl['o_h'];
174 $this->w
= $tpl['o_w'];
175 $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
177 $this->FontFamily
= $tpl['o_FontFamily'];
178 $this->FontStyle
= $tpl['o_FontStyle'];
179 $this->FontSizePt
= $tpl['o_FontSizePt'];
180 $this->FontSize
= $tpl['o_FontSize'];
182 $fontKey = $this->FontFamily
. $this->FontStyle
;
184 $this->CurrentFont
=& $this->fonts
[$fontKey];
193 * Use a template in current page or other template.
195 * You can use a template in a page or in another template.
196 * You can give the used template a new size.
197 * All parameters are optional. The width or height is calculated automatically
198 * if one is given. If no parameter is given the origin size as defined in
199 * {@link beginTemplate()} method is used.
201 * The calculated or used width and height are returned as an array.
203 * @param int $tplIdx A valid template-id
204 * @param int $x The x-position
205 * @param int $y The y-position
206 * @param int $w The new width of the template
207 * @param int $h The new height of the template
208 * @return array The height and width of the template (array('w' => ..., 'h' => ...))
209 * @throws LogicException|InvalidArgumentException
211 public function useTemplate($tplIdx, $x = null, $y = null, $w = 0, $h = 0)
213 if ($this->page
<= 0) {
214 throw new LogicException('You have to add at least a page first!');
217 if (!isset($this->_tpls
[$tplIdx])) {
218 throw new InvalidArgumentException('Template does not exist!');
222 $this->_res
['tpl'][$this->tpl
]['tpls'][$tplIdx] =& $this->_tpls
[$tplIdx];
225 $tpl = $this->_tpls
[$tplIdx];
240 $wh = $this->getTemplateSize($tplIdx, $w, $h);
249 'scaleX' => ($w / $_w),
250 'scaleY' => ($h / $_h),
252 'ty' => ($this->h
- $y - $h),
253 'lty' => ($this->h
- $y - $h) - ($this->h
- $_h) * ($h / $_h)
256 $this->_out(sprintf('q %.4F 0 0 %.4F %.4F %.4F cm',
257 $tplData['scaleX'], $tplData['scaleY'], $tplData['tx'] * $this->k
, $tplData['ty'] * $this->k
)
259 $this->_out(sprintf('%s%d Do Q', $this->tplPrefix
, $tplIdx));
261 $this->lastUsedTemplateData
= $tplData;
263 return array('w' => $w, 'h' => $h);
267 * Get the calculated size of a template.
269 * If one size is given, this method calculates the other one.
271 * @param int $tplIdx A valid template-id
272 * @param int $w The width of the template
273 * @param int $h The height of the template
274 * @return array The height and width of the template (array('w' => ..., 'h' => ...))
276 public function getTemplateSize($tplIdx, $w = 0, $h = 0)
278 if (!isset($this->_tpls
[$tplIdx]))
281 $tpl = $this->_tpls
[$tplIdx];
285 if ($w == 0 && $h == 0) {
295 return array("w" => $w, "h" => $h);
299 * Sets the font used to print character strings.
301 * See FPDF/TCPDF documentation.
303 * @see http://fpdf.org/en/doc/setfont.htm
304 * @see http://www.tcpdf.org/doc/code/classTCPDF.html#afd56e360c43553830d543323e81bc045
306 public function SetFont($family, $style = '', $size = null, $fontfile = '', $subset = 'default', $out = true)
308 if (is_subclass_of($this, 'TCPDF')) {
309 $args = func_get_args();
310 return call_user_func_array(array($this, 'TCPDF::SetFont'), $args);
313 parent
::SetFont($family, $style, $size);
315 $fontkey = $this->FontFamily
. $this->FontStyle
;
318 $this->_res
['tpl'][$this->tpl
]['fonts'][$fontkey] =& $this->fonts
[$fontkey];
320 $this->_res
['page'][$this->page
]['fonts'][$fontkey] =& $this->fonts
[$fontkey];
327 * See FPDF/TCPDF documentation.
329 * @see http://fpdf.org/en/doc/image.htm
330 * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a714c2bee7d6b39d4d6d304540c761352
332 public function Image(
333 $file, $x = '', $y = '', $w = 0, $h = 0, $type = '', $link = '', $align = '', $resize = false,
334 $dpi = 300, $palign = '', $ismask = false, $imgmask = false, $border = 0, $fitbox = false,
335 $hidden = false, $fitonpage = false, $alt = false, $altimgs = array()
338 if (is_subclass_of($this, 'TCPDF')) {
339 $args = func_get_args();
340 return call_user_func_array(array($this, 'TCPDF::Image'), $args);
343 $ret = parent
::Image($file, $x, $y, $w, $h, $type, $link);
345 $this->_res
['tpl'][$this->tpl
]['images'][$file] =& $this->images
[$file];
347 $this->_res
['page'][$this->page
]['images'][$file] =& $this->images
[$file];
354 * Adds a new page to the document.
356 * See FPDF/TCPDF documentation.
358 * This method cannot be used if you'd started a template.
360 * @see http://fpdf.org/en/doc/addpage.htm
361 * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a5171e20b366b74523709d84c349c1ced
363 public function AddPage($orientation = '', $format = '', $keepmargins = false, $tocpage = false)
365 if (is_subclass_of($this, 'TCPDF')) {
366 $args = func_get_args();
367 return call_user_func_array(array($this, 'TCPDF::AddPage'), $args);
371 throw new LogicException('Adding pages in templates is not possible!');
374 parent
::AddPage($orientation, $format);
378 * Puts a link on a rectangular area of the page.
380 * Overwritten because adding links in a template will not work.
382 * @see http://fpdf.org/en/doc/link.htm
383 * @see http://www.tcpdf.org/doc/code/classTCPDF.html#ab87bf1826384fbfe30eb499d42f1d994
385 public function Link($x, $y, $w, $h, $link, $spaces = 0)
387 if (is_subclass_of($this, 'TCPDF')) {
388 $args = func_get_args();
389 return call_user_func_array(array($this, 'TCPDF::Link'), $args);
393 throw new LogicException('Using links in templates is not posible!');
396 parent
::Link($x, $y, $w, $h, $link);
400 * Creates a new internal link and returns its identifier.
402 * Overwritten because adding links in a template will not work.
404 * @see http://fpdf.org/en/doc/addlink.htm
405 * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a749522038ed7786c3e1701435dcb891e
407 public function AddLink()
409 if (is_subclass_of($this, 'TCPDF')) {
410 $args = func_get_args();
411 return call_user_func_array(array($this, 'TCPDF::AddLink'), $args);
415 throw new LogicException('Adding links in templates is not possible!');
418 return parent
::AddLink();
422 * Defines the page and position a link points to.
424 * Overwritten because adding links in a template will not work.
426 * @see http://fpdf.org/en/doc/setlink.htm
427 * @see http://www.tcpdf.org/doc/code/classTCPDF.html#ace5be60e7857953ea5e2b89cb90df0ae
429 public function SetLink($link, $y = 0, $page = -1)
431 if (is_subclass_of($this, 'TCPDF')) {
432 $args = func_get_args();
433 return call_user_func_array(array($this, 'TCPDF::SetLink'), $args);
437 throw new LogicException('Setting links in templates is not possible!');
440 parent
::SetLink($link, $y, $page);
444 * Writes the form XObjects to the PDF document.
446 protected function _putformxobjects()
448 $filter=($this->compress
) ?
'/Filter /FlateDecode ' : '';
451 foreach($this->_tpls
AS $tplIdx => $tpl) {
453 $this->_tpls
[$tplIdx]['n'] = $this->n
;
454 $this->_out('<<'.$filter.'/Type /XObject');
455 $this->_out('/Subtype /Form');
456 $this->_out('/FormType 1');
457 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
459 $tpl['x'] * $this->k
,
461 -$tpl['y'] * $this->k
,
463 ($tpl['w'] +
$tpl['x']) * $this->k
,
465 ($tpl['h'] - $tpl['y']) * $this->k
468 if ($tpl['x'] != 0 ||
$tpl['y'] != 0) {
469 $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',
470 -$tpl['x'] * $this->k
* 2, $tpl['y'] * $this->k
* 2
474 $this->_out('/Resources ');
475 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
477 if (isset($this->_res
['tpl'][$tplIdx])) {
478 $res = $this->_res
['tpl'][$tplIdx];
479 if (isset($res['fonts']) && count($res['fonts'])) {
480 $this->_out('/Font <<');
482 foreach($res['fonts'] as $font) {
483 $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R');
489 if(isset($res['images']) ||
isset($res['tpls'])) {
490 $this->_out('/XObject <<');
492 if (isset($res['images'])) {
493 foreach($res['images'] as $image)
494 $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R');
497 if (isset($res['tpls'])) {
498 foreach($res['tpls'] as $i => $_tpl)
499 $this->_out($this->tplPrefix
. $i . ' ' . $_tpl['n'] . ' 0 R');
508 $buffer = ($this->compress
) ?
gzcompress($tpl['buffer']) : $tpl['buffer'];
509 $this->_out('/Length ' . strlen($buffer) . ' >>');
510 $this->_putstream($buffer);
511 $this->_out('endobj');
518 * Overwritten to add {@link _putformxobjects()} after _putimages().
520 public function _putimages()
522 parent
::_putimages();
523 $this->_putformxobjects();
527 * Writes the references of XObject resources to the document.
529 * Overwritten to add the the templates to the XObject resource dictionary.
531 public function _putxobjectdict()
533 parent
::_putxobjectdict();
535 foreach($this->_tpls
as $tplIdx => $tpl) {
536 $this->_out(sprintf('%s%d %d 0 R', $this->tplPrefix
, $tplIdx, $tpl['n']));
541 * Writes bytes to the resulting document.
543 * Overwritten to delegate the data to the template buffer.
547 public function _out($s)
549 if ($this->state
== 2 && $this->_inTpl
) {
550 $this->_tpls
[$this->tpl
]['buffer'] .= $s . "\n";