3 // FPDF_TPL - Version 1.2
5 // Copyright 2004-2010 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 class FPDF_TPL
extends FPDF
{
40 * Nameprefix of Templates used in Resources-Dictonary
41 * @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an /
43 var $tplprefix = "/TPL";
46 * Resources used By Templates and Pages
52 * Last used Template data
56 var $lastUsedTemplateData = array();
61 * This method starts a template. You can give own coordinates to build an own sized
62 * Template. Pay attention, that the margins are adapted to the new templatesize.
63 * If you want to write outside the template, for example to build a clipped Template,
64 * you have to set the Margins and "Cursor"-Position manual after beginTemplate-Call.
66 * If no parameter is given, the template uses the current page-size.
67 * The Method returns an ID of the current Template. This ID is used later for using this template.
68 * Warning: A created Template is used in PDF at all events. Still if you don't use it after creation!
70 * @param int $x The x-coordinate given in user-unit
71 * @param int $y The y-coordinate given in user-unit
72 * @param int $w The width given in user-unit
73 * @param int $h The height given in user-unit
74 * @return int The ID of new created Template
76 function beginTemplate($x = null, $y = null, $w = null, $h = null) {
77 if (is_subclass_of($this, 'TCPDF')) {
78 $this->Error('This method is only usable with FPDF. Use TCPDF methods startTemplate() instead.');
83 $this->error("You have to add a page to fpdf first!");
96 $tpl =& $this->tpls
[$this->tpl
];
100 'o_AutoPageBreak' => $this->AutoPageBreak
,
101 'o_bMargin' => $this->bMargin
,
102 'o_tMargin' => $this->tMargin
,
103 'o_lMargin' => $this->lMargin
,
104 'o_rMargin' => $this->rMargin
,
114 $this->SetAutoPageBreak(false);
116 // Define own high and width to calculate possitions correct
120 $this->_intpl
= true;
121 $this->SetXY($x +
$this->lMargin
, $y +
$this->tMargin
);
122 $this->SetRightMargin($this->w
- $w +
$this->rMargin
);
130 * This method ends a template and reset initiated variables on beginTemplate.
132 * @return mixed If a template is opened, the ID is returned. If not a false is returned.
134 function endTemplate() {
135 if (is_subclass_of($this, 'TCPDF')) {
136 $args = func_get_args();
137 return call_user_func_array(array($this, 'TCPDF::endTemplate'), $args);
141 $this->_intpl
= false;
142 $tpl =& $this->tpls
[$this->tpl
];
143 $this->SetXY($tpl['o_x'], $tpl['o_y']);
144 $this->tMargin
= $tpl['o_tMargin'];
145 $this->lMargin
= $tpl['o_lMargin'];
146 $this->rMargin
= $tpl['o_rMargin'];
147 $this->h
= $tpl['o_h'];
148 $this->w
= $tpl['o_w'];
149 $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
158 * Use a Template in current Page or other Template
160 * You can use a template in a page or in another template.
161 * You can give the used template a new size like you use the Image()-method.
162 * All parameters are optional. The width or height is calculated automaticaly
163 * if one is given. If no parameter is given the origin size as defined in
164 * beginTemplate() is used.
165 * The calculated or used width and height are returned as an array.
167 * @param int $tplidx A valid template-Id
168 * @param int $_x The x-position
169 * @param int $_y The y-position
170 * @param int $_w The new width of the template
171 * @param int $_h The new height of the template
172 * @retrun array The height and width of the template
174 function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0) {
175 if ($this->page
<= 0)
176 $this->error('You have to add a page first!');
178 if (!isset($this->tpls
[$tplidx]))
179 $this->error('Template does not exist!');
182 $this->_res
['tpl'][$this->tpl
]['tpls'][$tplidx] =& $this->tpls
[$tplidx];
185 $tpl =& $this->tpls
[$tplidx];
197 $wh = $this->getTemplateSize($tplidx, $_w, $_h);
206 'scaleX' => ($_w / $w),
207 'scaleY' => ($_h / $h),
209 'ty' => ($this->h
- $_y - $_h),
210 'lty' => ($this->h
- $_y - $_h) - ($this->h
- $h) * ($_h / $h)
213 $this->_out(sprintf('q %.4F 0 0 %.4F %.4F %.4F cm', $tData['scaleX'], $tData['scaleY'], $tData['tx'] * $this->k
, $tData['ty'] * $this->k
)); // Translate
214 $this->_out(sprintf('%s%d Do Q', $this->tplprefix
, $tplidx));
216 // reset font in the outer graphic state
217 if ($this->FontFamily
) {
218 $family = $this->FontFamily
;
219 $this->FontFamily
= '';
220 $this->SetFont($family);
223 $this->lastUsedTemplateData
= $tData;
225 return array('w' => $_w, 'h' => $_h);
229 * Get The calculated Size of a Template
231 * If one size is given, this method calculates the other one.
233 * @param int $tplidx A valid template-Id
234 * @param int $_w The width of the template
235 * @param int $_h The height of the template
236 * @return array The height and width of the template
238 function getTemplateSize($tplidx, $_w = 0, $_h = 0) {
239 if (!$this->tpls
[$tplidx])
242 $tpl =& $this->tpls
[$tplidx];
246 if ($_w == 0 and $_h == 0) {
256 return array("w" => $_w, "h" => $_h);
260 * See FPDF/TCPDF-Documentation ;-)
262 public function SetFont($family, $style = '', $size = 0) {
263 if (is_subclass_of($this, 'TCPDF')) {
264 $args = func_get_args();
265 return call_user_func_array(array($this, 'TCPDF::SetFont'), $args);
269 * force the resetting of font changes in a template
272 $this->FontFamily
= '';
274 parent
::SetFont($family, $style, $size);
276 $fontkey = $this->FontFamily
. $this->FontStyle
;
279 $this->_res
['tpl'][$this->tpl
]['fonts'][$fontkey] =& $this->fonts
[$fontkey];
281 $this->_res
['page'][$this->page
]['fonts'][$fontkey] =& $this->fonts
[$fontkey];
286 * See FPDF/TCPDF-Documentation ;-)
288 function Image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '') {
289 if (is_subclass_of($this, 'TCPDF')) {
290 $args = func_get_args();
291 return call_user_func_array(array($this, 'TCPDF::Image'), $args);
294 $ret = parent
::Image($file, $x, $y, $w, $h, $type, $link);
296 $this->_res
['tpl'][$this->tpl
]['images'][$file] =& $this->images
[$file];
298 $this->_res
['page'][$this->page
]['images'][$file] =& $this->images
[$file];
305 * See FPDF-Documentation ;-)
307 * AddPage is not available when you're "in" a template.
309 function AddPage($orientation = '', $format = '') {
310 if (is_subclass_of($this, 'TCPDF')) {
311 $args = func_get_args();
312 return call_user_func_array(array($this, 'TCPDF::AddPage'), $args);
316 $this->Error('Adding pages in templates isn\'t possible!');
318 parent
::AddPage($orientation, $format);
322 * Preserve adding Links in Templates ...won't work
324 function Link($x, $y, $w, $h, $link) {
325 if (is_subclass_of($this, 'TCPDF')) {
326 $args = func_get_args();
327 return call_user_func_array(array($this, 'TCPDF::Link'), $args);
331 $this->Error('Using links in templates aren\'t possible!');
333 parent
::Link($x, $y, $w, $h, $link);
337 if (is_subclass_of($this, 'TCPDF')) {
338 $args = func_get_args();
339 return call_user_func_array(array($this, 'TCPDF::AddLink'), $args);
343 $this->Error('Adding links in templates aren\'t possible!');
344 return parent
::AddLink();
347 function SetLink($link, $y = 0, $page = -1) {
348 if (is_subclass_of($this, 'TCPDF')) {
349 $args = func_get_args();
350 return call_user_func_array(array($this, 'TCPDF::SetLink'), $args);
354 $this->Error('Setting links in templates aren\'t possible!');
355 parent
::SetLink($link, $y, $page);
359 * Private Method that writes the form xobjects
361 function _putformxobjects() {
362 $filter=($this->compress
) ?
'/Filter /FlateDecode ' : '';
364 foreach($this->tpls
AS $tplidx => $tpl) {
366 $p=($this->compress
) ?
gzcompress($tpl['buffer']) : $tpl['buffer'];
368 $this->tpls
[$tplidx]['n'] = $this->n
;
369 $this->_out('<<'.$filter.'/Type /XObject');
370 $this->_out('/Subtype /Form');
371 $this->_out('/FormType 1');
372 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
374 $tpl['x'] * $this->k
,
376 -$tpl['y'] * $this->k
,
378 ($tpl['w'] +
$tpl['x']) * $this->k
,
380 ($tpl['h'] - $tpl['y']) * $this->k
383 if ($tpl['x'] != 0 ||
$tpl['y'] != 0) {
384 $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',
385 -$tpl['x'] * $this->k
* 2, $tpl['y'] * $this->k
* 2
389 $this->_out('/Resources ');
391 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
392 if (isset($this->_res
['tpl'][$tplidx]['fonts']) && count($this->_res
['tpl'][$tplidx]['fonts'])) {
393 $this->_out('/Font <<');
394 foreach($this->_res
['tpl'][$tplidx]['fonts'] as $font)
395 $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R');
398 if(isset($this->_res
['tpl'][$tplidx]['images']) && count($this->_res
['tpl'][$tplidx]['images']) ||
399 isset($this->_res
['tpl'][$tplidx]['tpls']) && count($this->_res
['tpl'][$tplidx]['tpls']))
401 $this->_out('/XObject <<');
402 if (isset($this->_res
['tpl'][$tplidx]['images']) && count($this->_res
['tpl'][$tplidx]['images'])) {
403 foreach($this->_res
['tpl'][$tplidx]['images'] as $image)
404 $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R');
406 if (isset($this->_res
['tpl'][$tplidx]['tpls']) && count($this->_res
['tpl'][$tplidx]['tpls'])) {
407 foreach($this->_res
['tpl'][$tplidx]['tpls'] as $i => $tpl)
408 $this->_out($this->tplprefix
. $i . ' ' . $tpl['n'] . ' 0 R');
414 $this->_out('/Length ' . strlen($p) . ' >>');
415 $this->_putstream($p);
416 $this->_out('endobj');
421 * Overwritten to add _putformxobjects() after _putimages()
424 function _putimages() {
425 parent
::_putimages();
426 $this->_putformxobjects();
429 function _putxobjectdict() {
430 parent
::_putxobjectdict();
432 if (count($this->tpls
)) {
433 foreach($this->tpls
as $tplidx => $tpl) {
434 $this->_out(sprintf('%s%d %d 0 R', $this->tplprefix
, $tplidx, $tpl['n']));
443 if ($this->state
== 2 && $this->_intpl
) {
444 $this->tpls
[$this->tpl
]['buffer'] .= $s . "\n";