Projet

Général

Profil

Paste
Télécharger (17,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / libraries / fpdi-1.5.4 / fpdf_tpl.php @ a1cafe7e

1
<?php
2
//
3
//  FPDI - Version 1.5.4
4
//
5
//    Copyright 2004-2015 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
10
//
11
//      http://www.apache.org/licenses/LICENSE-2.0
12
//
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.
18
//
19

    
20
if (!class_exists('fpdi_bridge')) {
21
    require_once('fpdi_bridge.php');
22
}
23

    
24
/**
25
 * Class FPDF_TPL
26
 */
27
class FPDF_TPL extends fpdi_bridge
28
{
29
    /**
30
     * Array of template data
31
     *
32
     * @var array
33
     */
34
    protected $_tpls = array();
35

    
36
    /**
37
     * Current Template-Id
38
     *
39
     * @var int
40
     */
41
    public $tpl = 0;
42

    
43
    /**
44
     * "In Template"-Flag
45
     *
46
     * @var boolean
47
     */
48
    protected $_inTpl = false;
49

    
50
    /**
51
     * Name prefix of templates used in Resources dictionary
52
     *
53
     * @var string A String defining the Prefix used as Template-Object-Names. Have to begin with an /
54
     */
55
    public $tplPrefix = "/TPL";
56

    
57
    /**
58
     * Resources used by templates and pages
59
     *
60
     * @var array
61
     */
62
    protected  $_res = array();
63

    
64
    /**
65
     * Last used template data
66
     *
67
     * @var array
68
     */
69
    public $lastUsedTemplateData = array();
70

    
71
    /**
72
     * Start a template.
73
     *
74
     * This method starts a template. You can give own coordinates to build an own sized
75
     * template. Pay attention, that the margins are adapted to the new template size.
76
     * If you want to write outside the template, for example to build a clipped template,
77
     * you have to set the margins and "cursor"-position manual after beginTemplate()-call.
78
     *
79
     * If no parameter is given, the template uses the current page-size.
80
     * The method returns an id of the current template. This id is used later for using this template.
81
     * Warning: A created template is saved in the resulting PDF at all events. Also if you don't use it after creation!
82
     *
83
     * @param int $x The x-coordinate given in user-unit
84
     * @param int $y The y-coordinate given in user-unit
85
     * @param int $w The width given in user-unit
86
     * @param int $h The height given in user-unit
87
     * @return int The id of new created template
88
     * @throws LogicException
89
     */
90
    public function beginTemplate($x = null, $y = null, $w = null, $h = null)
91
    {
92
        if (is_subclass_of($this, 'TCPDF')) {
93
            throw new LogicException('This method is only usable with FPDF. Use TCPDF methods startTemplate() instead.');
94
        }
95

    
96
        if ($this->page <= 0) {
97
            throw new LogicException("You have to add at least a page first!");
98
        }
99

    
100
        if ($x == null)
101
            $x = 0;
102
        if ($y == null)
103
            $y = 0;
104
        if ($w == null)
105
            $w = $this->w;
106
        if ($h == null)
107
            $h = $this->h;
108

    
109
        // Save settings
110
        $this->tpl++;
111
        $tpl =& $this->_tpls[$this->tpl];
112
        $tpl = array(
113
            'o_x' => $this->x,
114
            'o_y' => $this->y,
115
            'o_AutoPageBreak' => $this->AutoPageBreak,
116
            'o_bMargin' => $this->bMargin,
117
            'o_tMargin' => $this->tMargin,
118
            'o_lMargin' => $this->lMargin,
119
            'o_rMargin' => $this->rMargin,
120
            'o_h' => $this->h,
121
            'o_w' => $this->w,
122
            'o_FontFamily' => $this->FontFamily,
123
            'o_FontStyle' => $this->FontStyle,
124
            'o_FontSizePt' => $this->FontSizePt,
125
            'o_FontSize' => $this->FontSize,
126
            'buffer' => '',
127
            'x' => $x,
128
            'y' => $y,
129
            'w' => $w,
130
            'h' => $h
131
        );
132

    
133
        $this->SetAutoPageBreak(false);
134

    
135
        // Define own high and width to calculate correct positions
136
        $this->h = $h;
137
        $this->w = $w;
138

    
139
        $this->_inTpl = true;
140
        $this->SetXY($x + $this->lMargin, $y + $this->tMargin);
141
        $this->SetRightMargin($this->w - $w + $this->rMargin);
142

    
143
        if ($this->CurrentFont) {
144
            $fontKey = $this->FontFamily . $this->FontStyle;
145
            if ($fontKey) {
146
                $this->_res['tpl'][$this->tpl]['fonts'][$fontKey] =& $this->fonts[$fontKey];
147
                $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
148
            }
149
        }
150

    
151
        return $this->tpl;
152
    }
153

    
154
    /**
155
     * End template.
156
     *
157
     * This method ends a template and reset initiated variables collected in {@link beginTemplate()}.
158
     *
159
     * @return int|boolean If a template is opened, the id is returned. If not a false is returned.
160
     */
161
    public function endTemplate()
162
    {
163
        if (is_subclass_of($this, 'TCPDF')) {
164
            $args = func_get_args();
165
            return call_user_func_array(array($this, 'TCPDF::endTemplate'), $args);
166
        }
167

    
168
        if ($this->_inTpl) {
169
            $this->_inTpl = false;
170
            $tpl = $this->_tpls[$this->tpl];
171
            $this->SetXY($tpl['o_x'], $tpl['o_y']);
172
            $this->tMargin = $tpl['o_tMargin'];
173
            $this->lMargin = $tpl['o_lMargin'];
174
            $this->rMargin = $tpl['o_rMargin'];
175
            $this->h = $tpl['o_h'];
176
            $this->w = $tpl['o_w'];
177
            $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
178

    
179
            $this->FontFamily = $tpl['o_FontFamily'];
180
            $this->FontStyle = $tpl['o_FontStyle'];
181
            $this->FontSizePt = $tpl['o_FontSizePt'];
182
            $this->FontSize = $tpl['o_FontSize'];
183

    
184
            $fontKey = $this->FontFamily . $this->FontStyle;
185
            if ($fontKey)
186
                $this->CurrentFont =& $this->fonts[$fontKey];
187

    
188
            return $this->tpl;
189
        } else {
190
            return false;
191
        }
192
    }
193

    
194
    /**
195
     * Use a template in current page or other template.
196
     *
197
     * You can use a template in a page or in another template.
198
     * You can give the used template a new size.
199
     * All parameters are optional. The width or height is calculated automatically
200
     * if one is given. If no parameter is given the origin size as defined in
201
     * {@link beginTemplate()} method is used.
202
     *
203
     * The calculated or used width and height are returned as an array.
204
     *
205
     * @param int $tplIdx A valid template-id
206
     * @param int $x The x-position
207
     * @param int $y The y-position
208
     * @param int $w The new width of the template
209
     * @param int $h The new height of the template
210
     * @return array The height and width of the template (array('w' => ..., 'h' => ...))
211
     * @throws LogicException|InvalidArgumentException
212
     */
213
    public function useTemplate($tplIdx, $x = null, $y = null, $w = 0, $h = 0)
214
    {
215
        if ($this->page <= 0) {
216
            throw new LogicException('You have to add at least a page first!');
217
        }
218

    
219
        if (!isset($this->_tpls[$tplIdx])) {
220
            throw new InvalidArgumentException('Template does not exist!');
221
        }
222

    
223
        if ($this->_inTpl) {
224
            $this->_res['tpl'][$this->tpl]['tpls'][$tplIdx] =& $this->_tpls[$tplIdx];
225
        }
226

    
227
        $tpl = $this->_tpls[$tplIdx];
228
        $_w = $tpl['w'];
229
        $_h = $tpl['h'];
230

    
231
        if ($x == null) {
232
            $x = 0;
233
        }
234

    
235
        if ($y == null) {
236
            $y = 0;
237
        }
238

    
239
        $x += $tpl['x'];
240
        $y += $tpl['y'];
241

    
242
        $wh = $this->getTemplateSize($tplIdx, $w, $h);
243
        $w = $wh['w'];
244
        $h = $wh['h'];
245

    
246
        $tplData = array(
247
            'x' => $this->x,
248
            'y' => $this->y,
249
            'w' => $w,
250
            'h' => $h,
251
            'scaleX' => ($w / $_w),
252
            'scaleY' => ($h / $_h),
253
            'tx' => $x,
254
            'ty' =>  ($this->h - $y - $h),
255
            'lty' => ($this->h - $y - $h) - ($this->h - $_h) * ($h / $_h)
256
        );
257

    
258
        $this->_out(sprintf('q %.4F 0 0 %.4F %.4F %.4F cm',
259
                $tplData['scaleX'], $tplData['scaleY'], $tplData['tx'] * $this->k, $tplData['ty'] * $this->k)
260
        ); // Translate
261
        $this->_out(sprintf('%s%d Do Q', $this->tplPrefix, $tplIdx));
262

    
263
        $this->lastUsedTemplateData = $tplData;
264

    
265
        return array('w' => $w, 'h' => $h);
266
    }
267

    
268
    /**
269
     * Get the calculated size of a template.
270
     *
271
     * If one size is given, this method calculates the other one.
272
     *
273
     * @param int $tplIdx A valid template-id
274
     * @param int $w The width of the template
275
     * @param int $h The height of the template
276
     * @return array The height and width of the template (array('w' => ..., 'h' => ...))
277
     */
278
    public function getTemplateSize($tplIdx, $w = 0, $h = 0)
279
    {
280
        if (!isset($this->_tpls[$tplIdx]))
281
            return false;
282

    
283
        $tpl = $this->_tpls[$tplIdx];
284
        $_w = $tpl['w'];
285
        $_h = $tpl['h'];
286

    
287
        if ($w == 0 && $h == 0) {
288
            $w = $_w;
289
            $h = $_h;
290
        }
291

    
292
        if ($w == 0)
293
            $w = $h * $_w / $_h;
294
        if($h == 0)
295
            $h = $w * $_h / $_w;
296

    
297
        return array("w" => $w, "h" => $h);
298
    }
299

    
300
    /**
301
     * Sets the font used to print character strings.
302
     *
303
     * See FPDF/TCPDF documentation.
304
     *
305
     * @see http://fpdf.org/en/doc/setfont.htm
306
     * @see http://www.tcpdf.org/doc/code/classTCPDF.html#afd56e360c43553830d543323e81bc045
307
     */
308
    public function SetFont($family, $style = '', $size = null, $fontfile = '', $subset = 'default', $out = true)
309
    {
310
        if (is_subclass_of($this, 'TCPDF')) {
311
            $args = func_get_args();
312
            return call_user_func_array(array($this, 'TCPDF::SetFont'), $args);
313
        }
314

    
315
        parent::SetFont($family, $style, $size);
316

    
317
        $fontkey = $this->FontFamily . $this->FontStyle;
318

    
319
        if ($this->_inTpl) {
320
            $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey];
321
        } else {
322
            $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey];
323
        }
324
    }
325

    
326
    /**
327
     * Puts an image.
328
     *
329
     * See FPDF/TCPDF documentation.
330
     *
331
     * @see http://fpdf.org/en/doc/image.htm
332
     * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a714c2bee7d6b39d4d6d304540c761352
333
     */
334
    public function Image(
335
        $file, $x = '', $y = '', $w = 0, $h = 0, $type = '', $link = '', $align = '', $resize = false,
336
        $dpi = 300, $palign = '', $ismask = false, $imgmask = false, $border = 0, $fitbox = false,
337
        $hidden = false, $fitonpage = false, $alt = false, $altimgs = array()
338
    )
339
    {
340
        if (is_subclass_of($this, 'TCPDF')) {
341
            $args = func_get_args();
342
            return call_user_func_array(array($this, 'TCPDF::Image'), $args);
343
        }
344

    
345
        $ret = parent::Image($file, $x, $y, $w, $h, $type, $link);
346
        if ($this->_inTpl) {
347
            $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
348
        } else {
349
            $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file];
350
        }
351

    
352
        return $ret;
353
    }
354

    
355
    /**
356
     * Adds a new page to the document.
357
     *
358
     * See FPDF/TCPDF documentation.
359
     *
360
     * This method cannot be used if you'd started a template.
361
     *
362
     * @see http://fpdf.org/en/doc/addpage.htm
363
     * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a5171e20b366b74523709d84c349c1ced
364
     */
365
    public function AddPage($orientation = '', $format = '', $keepmargins = false, $tocpage = false)
366
    {
367
        if (is_subclass_of($this, 'TCPDF')) {
368
            $args = func_get_args();
369
            return call_user_func_array(array($this, 'TCPDF::AddPage'), $args);
370
        }
371

    
372
        if ($this->_inTpl) {
373
            throw new LogicException('Adding pages in templates is not possible!');
374
        }
375

    
376
        parent::AddPage($orientation, $format);
377
    }
378

    
379
    /**
380
     * Puts a link on a rectangular area of the page.
381
     *
382
     * Overwritten because adding links in a template will not work.
383
     *
384
     * @see http://fpdf.org/en/doc/link.htm
385
     * @see http://www.tcpdf.org/doc/code/classTCPDF.html#ab87bf1826384fbfe30eb499d42f1d994
386
     */
387
    public function Link($x, $y, $w, $h, $link, $spaces = 0)
388
    {
389
        if (is_subclass_of($this, 'TCPDF')) {
390
            $args = func_get_args();
391
            return call_user_func_array(array($this, 'TCPDF::Link'), $args);
392
        }
393

    
394
        if ($this->_inTpl) {
395
            throw new LogicException('Using links in templates is not posible!');
396
        }
397

    
398
        parent::Link($x, $y, $w, $h, $link);
399
    }
400

    
401
    /**
402
     * Creates a new internal link and returns its identifier.
403
     *
404
     * Overwritten because adding links in a template will not work.
405
     *
406
     * @see http://fpdf.org/en/doc/addlink.htm
407
     * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a749522038ed7786c3e1701435dcb891e
408
     */
409
    public function AddLink()
410
    {
411
        if (is_subclass_of($this, 'TCPDF')) {
412
            $args = func_get_args();
413
            return call_user_func_array(array($this, 'TCPDF::AddLink'), $args);
414
        }
415

    
416
        if ($this->_inTpl) {
417
            throw new LogicException('Adding links in templates is not possible!');
418
        }
419

    
420
        return parent::AddLink();
421
    }
422

    
423
    /**
424
     * Defines the page and position a link points to.
425
     *
426
     * Overwritten because adding links in a template will not work.
427
     *
428
     * @see http://fpdf.org/en/doc/setlink.htm
429
     * @see http://www.tcpdf.org/doc/code/classTCPDF.html#ace5be60e7857953ea5e2b89cb90df0ae
430
     */
431
    public function SetLink($link, $y = 0, $page = -1)
432
    {
433
        if (is_subclass_of($this, 'TCPDF')) {
434
            $args = func_get_args();
435
            return call_user_func_array(array($this, 'TCPDF::SetLink'), $args);
436
        }
437

    
438
        if ($this->_inTpl) {
439
            throw new LogicException('Setting links in templates is not possible!');
440
        }
441

    
442
        parent::SetLink($link, $y, $page);
443
    }
444

    
445
    /**
446
     * Writes the form XObjects to the PDF document.
447
     */
448
    protected function _putformxobjects()
449
    {
450
        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
451
        reset($this->_tpls);
452

    
453
        foreach($this->_tpls AS $tplIdx => $tpl) {
454
            $this->_newobj();
455
            $this->_tpls[$tplIdx]['n'] = $this->n;
456
            $this->_out('<<'.$filter.'/Type /XObject');
457
            $this->_out('/Subtype /Form');
458
            $this->_out('/FormType 1');
459
            $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
460
                // llx
461
                $tpl['x'] * $this->k,
462
                // lly
463
                -$tpl['y'] * $this->k,
464
                // urx
465
                ($tpl['w'] + $tpl['x']) * $this->k,
466
                // ury
467
                ($tpl['h'] - $tpl['y']) * $this->k
468
            ));
469

    
470
            if ($tpl['x'] != 0 || $tpl['y'] != 0) {
471
                $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',
472
                    -$tpl['x'] * $this->k * 2, $tpl['y'] * $this->k * 2
473
                ));
474
            }
475

    
476
            $this->_out('/Resources ');
477
            $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
478

    
479
            if (isset($this->_res['tpl'][$tplIdx])) {
480
                $res = $this->_res['tpl'][$tplIdx];
481
                if (isset($res['fonts']) && count($res['fonts'])) {
482
                    $this->_out('/Font <<');
483

    
484
                    foreach($res['fonts'] as $font) {
485
                        $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R');
486
                    }
487

    
488
                    $this->_out('>>');
489
                }
490

    
491
                if(isset($res['images']) || isset($res['tpls'])) {
492
                    $this->_out('/XObject <<');
493

    
494
                    if (isset($res['images'])) {
495
                        foreach($res['images'] as $image)
496
                            $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R');
497
                    }
498

    
499
                    if (isset($res['tpls'])) {
500
                        foreach($res['tpls'] as $i => $_tpl)
501
                            $this->_out($this->tplPrefix . $i . ' ' . $_tpl['n'] . ' 0 R');
502
                    }
503

    
504
                    $this->_out('>>');
505
                }
506
            }
507

    
508
            $this->_out('>>');
509

    
510
            $buffer = ($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
511
            $this->_out('/Length ' . strlen($buffer) . ' >>');
512
            $this->_putstream($buffer);
513
            $this->_out('endobj');
514
        }
515
    }
516

    
517
    /**
518
     * Output images.
519
     *
520
     * Overwritten to add {@link _putformxobjects()} after _putimages().
521
     */
522
    public function _putimages()
523
    {
524
        parent::_putimages();
525
        $this->_putformxobjects();
526
    }
527

    
528
    /**
529
     * Writes the references of XObject resources to the document.
530
     *
531
     * Overwritten to add the the templates to the XObject resource dictionary.
532
     */
533
    public function _putxobjectdict()
534
    {
535
        parent::_putxobjectdict();
536

    
537
        foreach($this->_tpls as $tplIdx => $tpl) {
538
            $this->_out(sprintf('%s%d %d 0 R', $this->tplPrefix, $tplIdx, $tpl['n']));
539
        }
540
    }
541

    
542
    /**
543
     * Writes bytes to the resulting document.
544
     *
545
     * Overwritten to delegate the data to the template buffer.
546
     *
547
     * @param string $s
548
     */
549
    public function _out($s)
550
    {
551
        if ($this->state == 2 && $this->_inTpl) {
552
            $this->_tpls[$this->tpl]['buffer'] .= $s . "\n";
553
        } else {
554
            parent::_out($s);
555
        }
556
    }
557
}