Added HTML2PDF and FPDI to the project.
[openemr.git] / library / html2pdf / fpdi / fpdf_tpl.php
blobd21743e63742c7f834ec722378d0edb2afb09508
1 <?php
2 //
3 // FPDF_TPL - Version 1.2
4 //
5 // Copyright 2004-2010 Setasign - Jan Slabon
6 //
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 {
21 /**
22 * Array of Tpl-Data
23 * @var array
25 var $tpls = array();
27 /**
28 * Current Template-ID
29 * @var int
31 var $tpl = 0;
33 /**
34 * "In Template"-Flag
35 * @var boolean
37 var $_intpl = false;
39 /**
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";
45 /**
46 * Resources used By Templates and Pages
47 * @var array
49 var $_res = array();
51 /**
52 * Last used Template data
54 * @var array
56 var $lastUsedTemplateData = array();
58 /**
59 * Start a Template
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.');
79 return;
82 if ($this->page <= 0)
83 $this->error("You have to add a page to fpdf first!");
85 if ($x == null)
86 $x = 0;
87 if ($y == null)
88 $y = 0;
89 if ($w == null)
90 $w = $this->w;
91 if ($h == null)
92 $h = $this->h;
94 // Save settings
95 $this->tpl++;
96 $tpl =& $this->tpls[$this->tpl];
97 $tpl = array(
98 'o_x' => $this->x,
99 'o_y' => $this->y,
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,
105 'o_h' => $this->h,
106 'o_w' => $this->w,
107 'buffer' => '',
108 'x' => $x,
109 'y' => $y,
110 'w' => $w,
111 'h' => $h
114 $this->SetAutoPageBreak(false);
116 // Define own high and width to calculate possitions correct
117 $this->h = $h;
118 $this->w = $w;
120 $this->_intpl = true;
121 $this->SetXY($x + $this->lMargin, $y + $this->tMargin);
122 $this->SetRightMargin($this->w - $w + $this->rMargin);
124 return $this->tpl;
128 * End Template
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);
140 if ($this->_intpl) {
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']);
151 return $this->tpl;
152 } else {
153 return false;
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!');
181 if ($this->_intpl) {
182 $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx];
185 $tpl =& $this->tpls[$tplidx];
186 $w = $tpl['w'];
187 $h = $tpl['h'];
189 if ($_x == null)
190 $_x = 0;
191 if ($_y == null)
192 $_y = 0;
194 $_x += $tpl['x'];
195 $_y += $tpl['y'];
197 $wh = $this->getTemplateSize($tplidx, $_w, $_h);
198 $_w = $wh['w'];
199 $_h = $wh['h'];
201 $tData = array(
202 'x' => $this->x,
203 'y' => $this->y,
204 'w' => $_w,
205 'h' => $_h,
206 'scaleX' => ($_w / $w),
207 'scaleY' => ($_h / $h),
208 'tx' => $_x,
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])
240 return false;
242 $tpl =& $this->tpls[$tplidx];
243 $w = $tpl['w'];
244 $h = $tpl['h'];
246 if ($_w == 0 and $_h == 0) {
247 $_w = $w;
248 $_h = $h;
251 if($_w == 0)
252 $_w = $_h * $w / $h;
253 if($_h == 0)
254 $_h = $_w * $h / $w;
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
271 if ($this->_intpl)
272 $this->FontFamily = '';
274 parent::SetFont($family, $style, $size);
276 $fontkey = $this->FontFamily . $this->FontStyle;
278 if ($this->_intpl) {
279 $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey];
280 } else {
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);
295 if ($this->_intpl) {
296 $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
297 } else {
298 $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file];
301 return $ret;
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);
315 if ($this->_intpl)
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);
330 if ($this->_intpl)
331 $this->Error('Using links in templates aren\'t possible!');
333 parent::Link($x, $y, $w, $h, $link);
336 function AddLink() {
337 if (is_subclass_of($this, 'TCPDF')) {
338 $args = func_get_args();
339 return call_user_func_array(array($this, 'TCPDF::AddLink'), $args);
342 if ($this->_intpl)
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);
353 if ($this->_intpl)
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 ' : '';
363 reset($this->tpls);
364 foreach($this->tpls AS $tplidx => $tpl) {
366 $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
367 $this->_newobj();
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]',
373 // llx
374 $tpl['x'] * $this->k,
375 // lly
376 -$tpl['y'] * $this->k,
377 // urx
378 ($tpl['w'] + $tpl['x']) * $this->k,
379 // ury
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');
396 $this->_out('>>');
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');
410 $this->_out('>>');
412 $this->_out('>>');
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']));
440 * Private Method
442 function _out($s) {
443 if ($this->state == 2 && $this->_intpl) {
444 $this->tpls[$this->tpl]['buffer'] .= $s . "\n";
445 } else {
446 parent::_out($s);