Passed
Pull Request — master (#114)
by Roberto
06:37
created

Fpdf::footer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace NFePHP\DA\Legacy\FPDF;
4
5
use Exception;
6
7
class Fpdf
8
{
9
    const FPDF_VERSION = '1.6';
10
    
11
    public $page;               //current page number
12
    public $n;                  //current object number
13
    public $offsets;            //array of object offsets
14
    public $buffer;             //buffer holding in-memory PDF
15
    public $pages;              //array containing pages
16
    public $state;              //current document state
17
    public $compress;           //compression flag
18
    public $k;                  //scale factor (number of points in user unit)
19
    public $defOrientation;     //default orientation
20
    public $curOrientation;     //current orientation
21
    public $pageFormats;        //available page formats
22
    public $defPageFormat;      //default page format
23
    public $curPageFormat;      //current page format
24
    public $pageSizes;          //array storing non-default page sizes
25
    public $wPt;
26
    public $hPt;           //dimensions of current page in points
27
    public $w;
28
    public $h;               //dimensions of current page in user unit
29
    public $lMargin;            //left margin
30
    public $tMargin;            //top margin
31
    public $rMargin;            //right margin
32
    public $bMargin;            //page break margin
33
    public $cMargin;            //cell margin
34
    public $x;
35
    public $y;               //current position in user unit
36
    public $lasth;              //height of last printed cell
37
    public $lineWidth;          //line width in user unit
38
    public $coreFonts;          //array of standard font names
39
    public $fonts;              //array of used fonts
40
    public $fontFiles;          //array of font files
41
    public $diffs;              //array of encoding differences
42
    public $fontFamily;         //current font family
43
    public $fontStyle;          //current font style
44
    public $underline;          //underlining flag
45
    public $currentFont;        //current font info
46
    public $fontSizePt;         //current font size in points
47
    public $fontSize;           //current font size in user unit
48
    public $drawColor;          //commands for drawing color
49
    public $fillColor;          //commands for filling color
50
    public $textColor;          //commands for text color
51
    public $colorFlag;          //indicates whether fill and text colors are different
52
    public $ws;                 //word spacing
53
    public $images;             //array of used images
54
    public $PageLinks;          //array of links in pages
55
    public $links;              //array of internal links
56
    public $autoPageBreak;      //automatic page breaking
57
    public $pageBreakTrigger;   //threshold used to trigger page breaks
58
    public $inHeader;           //flag set when processing header
59
    public $inFooter;           //flag set when processing footer
60
    public $zoomMode;           //zoom display mode
61
    public $layoutMode;         //layout display mode
62
    public $title;              //title
63
    public $subject;            //subject
64
    public $author;             //author
65
    public $keywords;           //keywords
66
    public $creator;            //creator
67
    public $aliasNbPages;       //alias for total number of pages
68
    public $pdfVersion;         //PDF version number
69
    
70 1
    public function __construct($orientation = 'P', $unit = 'mm', $format = 'A4')
71
    {
72
        //Some checks
73 1
        $this->dochecks();
74
        //Initialization of properties
75 1
        $this->page = 0;
76 1
        $this->n = 2;
77 1
        $this->buffer = '';
78 1
        $this->pages = array();
79 1
        $this->pageSizes = array();
80 1
        $this->state = 0;
81 1
        $this->fonts = array();
82 1
        $this->fontFiles = array();
83 1
        $this->diffs = array();
84 1
        $this->images = array();
85 1
        $this->links = array();
86 1
        $this->inHeader = false;
87 1
        $this->inFooter = false;
88 1
        $this->lasth = 0;
89 1
        $this->fontFamily = '';
90 1
        $this->fontStyle = '';
91 1
        $this->fontSizePt = 12;
92 1
        $this->underline = false;
93 1
        $this->drawColor = '0 G';
94 1
        $this->fillColor = '0 g';
95 1
        $this->textColor = '0 g';
96 1
        $this->colorFlag = false;
97 1
        $this->ws = 0;
98
        //Standard fonts
99 1
        $this->coreFonts = [
100
            'courier'=>'Courier',
101
            'courierB'=>'Courier-Bold',
102
            'courierI'=>'Courier-Oblique',
103
            'courierBI'=>'Courier-BoldOblique',
104
            'helvetica'=>'Helvetica',
105
            'helveticaB'=>'Helvetica-Bold',
106
            'helveticaI'=>'Helvetica-Oblique',
107
            'helveticaBI'=>'Helvetica-BoldOblique',
108
            'times'=>'Times-Roman',
109
            'timesB'=>'Times-Bold',
110
            'timesI'=>'Times-Italic',
111
            'timesBI'=>'Times-BoldItalic',
112
            'symbol'=>'Symbol',
113
            'zapfdingbats'=>'ZapfDingbats'
114
        ];
115
        //Scale factor
116 1
        if ($unit == 'pt') {
117
            $this->k = 1;
118 1
        } elseif ($unit == 'mm') {
119 1
            $this->k = 72/25.4;
120
        } elseif ($unit == 'cm') {
121
            $this->k = 72/2.54;
122
        } elseif ($unit == 'in') {
123
            $this->k = 72;
124
        } else {
125
            $this->error('Incorrect unit: '.$unit);
126
        }
127
        //Page format
128 1
        $this->pageFormats = array(
129
            'a3' => array(841.89,1190.55),
130
            'a4' => array(595.28,841.89),
131
            'a5' => array(420.94,595.28),
132
            'letter' => array(612,792),
133
            'legal' => array(612,1008)
134
        );
135 1
        if (is_string($format)) {
136 1
            $format = $this->getpageformat($format);
137
        }
138 1
        $this->defPageFormat = $format;
139 1
        $this->curPageFormat = $format;
140
        //Page orientation
141 1
        $orientation = strtolower($orientation);
142 1
        if ($orientation == 'p' || $orientation == 'portrait') {
143 1
            $this->defOrientation='P';
144 1
            $this->w = $this->defPageFormat[0];
145 1
            $this->h = $this->defPageFormat[1];
146
        } elseif ($orientation == 'l' || $orientation == 'landscape') {
147
            $this->defOrientation = 'L';
148
            $this->w = $this->defPageFormat[1];
149
            $this->h = $this->defPageFormat[0];
150
        } else {
151
            $this->error('Incorrect orientation: '.$orientation);
152
        }
153 1
        $this->curOrientation = $this->defOrientation;
154 1
        $this->wPt = $this->w*$this->k;
155 1
        $this->hPt = $this->h*$this->k;
156
        //Page margins (1 cm)
157 1
        $margin = 28.35/$this->k;
158 1
        $this->setMargins($margin, $margin);
159
        //Interior cell margin (1 mm)
160 1
        $this->cMargin = $margin/10;
161
        //Line width (0.2 mm)
162 1
        $this->lineWidth = .567/$this->k;
163
        //Automatic page break
164 1
        $this->setAutoPageBreak(true, 2*$margin);
165
        //Full width display mode
166 1
        $this->setDisplayMode('fullwidth');
167
        //Enable compression
168 1
        $this->setCompression(true);
169
        //Set default PDF version number
170 1
        $this->pdfVersion='1.3';
171 1
    }
172 1
    public function setMargins($left, $top, $right = null)
173
    {
174
        //Set left, top and right margins
175 1
        $this->lMargin = $left;
176 1
        $this->tMargin = $top;
177 1
        if ($right === null) {
178 1
            $right = $left;
179
        }
180 1
        $this->rMargin=$right;
181 1
    }
182
    public function setLeftMargin($margin)
183
    {
184
        //Set left margin
185
        $this->lMargin = $margin;
186
        if ($this->page>0 && $this->x<$margin) {
187
            $this->x = $margin;
188
        }
189
    }
190
    public function setTopMargin($margin)
191
    {
192
        //Set top margin
193
        $this->tMargin = $margin;
194
    }
195
    public function setRightMargin($margin)
196
    {
197
        //Set right margin
198
        $this->rMargin = $margin;
199
    }
200 1
    public function setAutoPageBreak($auto, $margin = 0)
201
    {
202
        //Set auto page break mode and triggering margin
203 1
        $this->autoPageBreak = $auto;
204 1
        $this->bMargin = $margin;
205 1
        $this->pageBreakTrigger = $this->h-$margin;
206 1
    }
207 1
    public function setDisplayMode($zoom, $layout = 'continuous')
208
    {
209
        //Set display mode in viewer
210 1
        if ($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom)) {
211 1
            $this->zoomMode = $zoom;
212
        } else {
213
            $this->error('Incorrect zoom display mode: '.$zoom);
214
        }
215 1
        if ($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default') {
216 1
            $this->layoutMode = $layout;
217
        } else {
218
            $this->error('Incorrect layout display mode: '.$layout);
219
        }
220 1
    }
221 1
    public function setCompression($compress)
222
    {
223
        //Set page compression
224 1
        if (function_exists('gzcompress')) {
225 1
            $this->compress = $compress;
226
        } else {
227
            $this->compress = false;
228
        }
229 1
    }
230
    public function setTitle($title, $isUTF8 = false)
231
    {
232
        //Title of document
233
        if ($isUTF8) {
234
            $title = $this->utf8Toutf16($title);
235
        }
236
        $this->title = $title;
237
    }
238
    public function setSubject($subject, $isUTF8 = false)
239
    {
240
        //Subject of document
241
        if ($isUTF8) {
242
            $subject = $this->utf8Toutf16($subject);
243
        }
244
        $this->subject = $subject;
245
    }
246
    public function setAuthor($author, $isUTF8 = false)
247
    {
248
        //Author of document
249
        if ($isUTF8) {
250
            $author = $this->utf8Toutf16($author);
251
        }
252
        $this->author=$author;
253
    }
254
    public function setKeywords($keywords, $isUTF8 = false)
255
    {
256
        //Keywords of document
257
        if ($isUTF8) {
258
            $keywords = $this->utf8Toutf16($keywords);
259
        }
260
        $this->keywords = $keywords;
261
    }
262
    public function setCreator($creator, $isUTF8 = false)
263
    {
264
        //Creator of document
265
        if ($isUTF8) {
266
            $creator = $this->utf8Toutf16($creator);
267
        }
268
        $this->creator = $creator;
269
    }
270 1
    public function aliasNbPages($alias = '{nb}')
271
    {
272
        //Define an alias for total number of pages
273 1
        $this->aliasNbPages=$alias;
274 1
    }
275
    public function error($msg)
276
    {
277
        throw Exception($msg);
278
    }
279 1
    public function open()
280
    {
281 1
        $this->state = 1;
282 1
    }
283 1
    public function close()
284
    {
285
        //Terminate document
286 1
        if ($this->state == 3) {
287
            return;
288
        }
289 1
        if ($this->page == 0) {
290
            $this->addPage();
291
        }
292
        //Page footer
293 1
        $this->inFooter = true;
294 1
        $this->footer();
295 1
        $this->inFooter = false;
296
        //Close page
297 1
        $this->endPage();
298
        //Close document
299 1
        $this->endDoc();
300 1
    }
301
    
302 1
    public function addPage($orientation = '', $format = '')
303
    {
304
        //Start a new page
305 1
        if ($this->state == 0) {
306
            $this->open();
307
        }
308 1
        $family = $this->fontFamily;
309 1
        $style = $this->fontStyle.($this->underline ? 'U' : '');
310 1
        $size = $this->fontSizePt;
311 1
        $lw = $this->lineWidth;
312 1
        $dc = $this->drawColor;
313 1
        $fc = $this->fillColor;
314 1
        $tc = $this->textColor;
315 1
        $cf = $this->colorFlag;
316 1
        if ($this->page > 0) {
317
            //Page footer
318
            $this->inFooter = true;
319
            $this->footer();
320
            $this->inFooter = false;
321
            //Close page
322
            $this->endPage();
323
        }
324
        //Start new page
325 1
        $this->beginPage($orientation, $format);
326
        //Set line cap style to square
327 1
        $this->out('2 J');
328
        //Set line width
329 1
        $this->lineWidth = $lw;
330 1
        $this->out(sprintf('%.2F w', $lw*$this->k));
331
        //Set font
332 1
        if ($family) {
333
            $this->setFont($family, $style, $size);
334
        }
335
        //Set colors
336 1
        $this->drawColor = $dc;
337 1
        if ($dc!='0 G') {
338 1
            $this->out($dc);
339
        }
340 1
        $this->fillColor = $fc;
341 1
        if ($fc != '0 g') {
342 1
            $this->out($fc);
343
        }
344 1
        $this->textColor = $tc;
345 1
        $this->colorFlag = $cf;
346
        //Page header
347 1
        $this->inHeader = true;
348 1
        $this->Header();
349 1
        $this->inHeader = false;
350
        //Restore line width
351 1
        if ($this->lineWidth != $lw) {
352
            $this->lineWidth = $lw;
353
            $this->out(sprintf('%.2F w', $lw*$this->k));
354
        }
355
        //Restore font
356 1
        if ($family) {
357
            $this->setFont($family, $style, $size);
358
        }
359
        //Restore colors
360 1
        if ($this->drawColor != $dc) {
361
            $this->drawColor = $dc;
362
            $this->out($dc);
363
        }
364 1
        if ($this->fillColor != $fc) {
365
            $this->fillColor = $fc;
366
            $this->out($fc);
367
        }
368 1
        $this->textColor = $tc;
369 1
        $this->colorFlag = $cf;
370 1
    }
371 1
    public function header()
372
    {
373
        //To be implemented in your own inherited class
374 1
    }
375 1
    public function footer()
376
    {
377
        //To be implemented in your own inherited class
378 1
    }
379
    public function pageNo()
380
    {
381
        //Get current page number
382
        return $this->page;
383
    }
384 1
    public function setDrawColor($r, $g = null, $b = null)
385
    {
386
        //Set color for all stroking operations
387 1
        if (($r==0 && $g==0 && $b==0) || $g===null) {
388 1
            $this->drawColor = sprintf('%.3F G', $r/255);
389
        } else {
390
            $this->drawColor = sprintf('%.3F %.3F %.3F RG', $r/255, $g/255, $b/255);
391
        }
392 1
        if ($this->page > 0) {
393
            $this->out($this->drawColor);
394
        }
395 1
    }
396 1
    public function setFillColor($r, $g = null, $b = null)
397
    {
398
        //Set color for all filling operations
399 1
        if (($r==0 && $g==0 && $b==0) || $g===null) {
400 1
            $this->fillColor = sprintf('%.3F g', $r/255);
401
        } else {
402 1
            $this->fillColor = sprintf('%.3F %.3F %.3F rg', $r/255, $g/255, $b/255);
403
        }
404 1
        $this->colorFlag = ($this->fillColor != $this->textColor);
405 1
        if ($this->page > 0) {
406 1
            $this->out($this->fillColor);
407
        }
408 1
    }
409 1
    public function settextColor($r, $g = null, $b = null)
410
    {
411
        //Set color for text
412 1
        if (($r==0 && $g==0 && $b==0) || $g===null) {
413 1
            $this->textColor = sprintf('%.3F g', $r/255);
414
        } else {
415 1
            $this->textColor = sprintf('%.3F %.3F %.3F rg', $r/255, $g/255, $b/255);
416
        }
417 1
        $this->colorFlag = ($this->fillColor != $this->textColor);
418 1
    }
419 1
    public function getStringWidth($s)
420
    {
421
        //Get width of a string in the current font
422 1
        $s = (string)$s;
423 1
        $cw =& $this->currentFont['cw'];
424 1
        $w = 0;
425 1
        $l = strlen($s);
426 1
        for ($i=0; $i<$l; $i++) {
427 1
            $w += $cw[$s[$i]];
428
        }
429 1
        return $w*$this->fontSize/1000;
430
    }
431 1
    public function setLineWidth($width)
432
    {
433
        //Set line width
434 1
        $this->lineWidth = $width;
435 1
        if ($this->page > 0) {
436 1
            $this->out(sprintf('%.2F w', $width*$this->k));
437
        }
438 1
    }
439
    public function line($x1, $y1, $x2, $y2)
440
    {
441
        //Draw a line
442
        $this->out(
443
            sprintf(
444
                '%.2F %.2F m %.2F %.2F l S',
445
                $x1*$this->k,
446
                ($this->h-$y1)*$this->k,
447
                $x2*$this->k,
448
                ($this->h-$y2)*$this->k
449
            )
450
        );
451
    }
452 1
    public function rect($x, $y, $w, $h, $style = '')
453
    {
454
        //Draw a rectangle
455 1
        if ($style == 'F') {
456 1
            $op = 'f';
457
        } elseif ($style == 'FD' || $style == 'DF') {
458
            $op = 'B';
459
        } else {
460
            $op = 'S';
461
        }
462 1
        $this->out(
463
            sprintf(
464 1
                '%.2F %.2F %.2F %.2F re %s',
465 1
                $x*$this->k,
466 1
                ($this->h-$y)*$this->k,
467 1
                $w*$this->k,
468 1
                -$h*$this->k,
469
                $op
470
            )
471
        );
472 1
    }
473
    public function addFont($family, $style = '', $file = '')
474
    {
475
        //Add a TrueType or Type1 font
476
        $family = strtolower($family);
477
        if ($file == '') {
478
            $file = str_replace(' ', '', $family).strtolower($style).'.php';
479
        }
480
        if ($family=='arial') {
481
            $family='helvetica';
482
        }
483
        $style = strtoupper($style);
484
        if ($style == 'IB') {
485
            $style = 'BI';
486
        }
487
        $fontkey = $family.$style;
488
        if (isset($this->fonts[$fontkey])) {
489
            return;
490
        }
491
        include $this->getFontPath().$file;
492
        if (!isset($name)) {
0 ignored issues
show
Bug introduced by
The variable $name seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
493
            $this->error('Could not include font definition file');
494
        }
495
        $i = count($this->fonts)+1;
496
        $this->fonts[$fontkey] = [
497
            'i'=>$i,
498
            'type'=>$type,
0 ignored issues
show
Bug introduced by
The variable $type does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
499
            'name'=>$name,
0 ignored issues
show
Bug introduced by
The variable $name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
500
            'desc'=>$desc,
0 ignored issues
show
Bug introduced by
The variable $desc does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
501
            'up'=>$up,
0 ignored issues
show
Bug introduced by
The variable $up does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
502
            'ut'=>$ut,
0 ignored issues
show
Bug introduced by
The variable $ut does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
503
            'cw'=>$cw,
0 ignored issues
show
Bug introduced by
The variable $cw does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
504
            'enc'=>$enc,
0 ignored issues
show
Bug introduced by
The variable $enc does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
505
            'file'=>$file
506
        ];
507
        if ($diff) {
508
            //Search existing encodings
509
            $d = 0;
510
            $nb = count($this->diffs);
511
            for ($i=1; $i<=$nb; $i++) {
512
                if ($this->diffs[$i] == $diff) {
0 ignored issues
show
Bug introduced by
The variable $diff does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
513
                    $d = $i;
514
                    break;
515
                }
516
            }
517
            if ($d == 0) {
518
                $d = $nb+1;
519
                $this->diffs[$d] = $diff;
520
            }
521
            $this->fonts[$fontkey]['diff'] = $d;
522
        }
523
        if ($file) {
524
            if ($type=='TrueType') {
525
                $this->fontFiles[$file] = array('length1'=>$originalsize);
0 ignored issues
show
Bug introduced by
The variable $originalsize does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
526
            } else {
527
                $this->fontFiles[$file] = array('length1'=>$size1, 'length2'=>$size2);
0 ignored issues
show
Bug introduced by
The variable $size1 does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $size2 does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
528
            }
529
        }
530
    }
531 1
    public function setFont($family, $style = '', $size = 0)
532
    {
533
        //Select a font; size given in points
534 1
        global $fpdf_charwidths;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
535 1
        $family = strtolower($family);
536 1
        if ($family == '') {
537
            $family = $this->fontFamily;
538
        }
539 1
        if ($family == 'arial') {
540
            $family = 'helvetica';
541 1
        } elseif ($family == 'symbol' || $family == 'zapfdingbats') {
542
            $style = '';
543
        }
544 1
        $style = strtoupper($style);
545 1
        if (strpos($style, 'U') !== false) {
546
            $this->underline = true;
547
            $style = str_replace('U', '', $style);
548
        } else {
549 1
            $this->underline = false;
550
        }
551 1
        if ($style == 'IB') {
552
            $style = 'BI';
553
        }
554 1
        if ($size == 0) {
555
            $size = $this->fontSizePt;
556
        }
557
        //Test if font is already selected
558 1
        if ($this->fontFamily==$family && $this->fontStyle==$style && $this->fontSizePt==$size) {
559 1
            return;
560
        }
561
        //Test if used for the first time
562 1
        $fontkey = $family.$style;
563 1
        if (!isset($this->fonts[$fontkey])) {
564
            //Check if one of the standard fonts
565 1
            if (isset($this->coreFonts[$fontkey])) {
566 1
                if (!isset($fpdf_charwidths[$fontkey])) {
567
                    //Load metric file
568 1
                    $file=$family;
569 1
                    if ($family=='times' || $family=='helvetica') {
570 1
                        $file .= strtolower($style);
571
                    }
572 1
                    include $this->getFontPath().$file.'.php';
573 1
                    if (!isset($fpdf_charwidths[$fontkey])) {
574
                        $this->error('Could not include font metric file');
575
                    }
576
                }
577 1
                $i = count($this->fonts)+1;
578 1
                $name = $this->coreFonts[$fontkey];
579 1
                $cw = $fpdf_charwidths[$fontkey];
580 1
                $this->fonts[$fontkey] = ['i'=>$i, 'type'=>'core', 'name'=>$name, 'up'=>-100, 'ut'=>50, 'cw'=>$cw];
581
            } else {
582
                $this->error('Undefined font: '.$family.' '.$style);
583
            }
584
        }
585
        //Select it
586 1
        $this->fontFamily = $family;
587 1
        $this->fontStyle = $style;
588 1
        $this->fontSizePt = $size;
589 1
        $this->fontSize = $size/$this->k;
590 1
        $this->currentFont =& $this->fonts[$fontkey];
591 1
        if ($this->page > 0) {
592 1
            $this->out(sprintf('BT /F%d %.2F Tf ET', $this->currentFont['i'], $this->fontSizePt));
593
        }
594 1
    }
595
    
596
    public function setFontSize($size)
597
    {
598
        //Set font size in points
599
        if ($this->fontSizePt == $size) {
600
            return;
601
        }
602
        $this->fontSizePt = $size;
603
        $this->fontSize = $size/$this->k;
604
        if ($this->page > 0) {
605
            $this->out(sprintf('BT /F%d %.2F Tf ET', $this->currentFont['i'], $this->fontSizePt));
606
        }
607
    }
608
    
609
    public function addlink()
610
    {
611
        //Create a new internal link
612
        $n = count($this->links)+1;
613
        $this->links[$n] = array(0, 0);
614
        return $n;
615
    }
616
    
617
    public function setlink($link, $y = 0, $page = -1)
618
    {
619
        //Set destination of internal link
620
        if ($y == -1) {
621
            $y = $this->y;
622
        }
623
        if ($page == -1) {
624
            $page = $this->page;
625
        }
626
        $this->links[$link] = array($page, $y);
627
    }
628
    
629
    public function link($x, $y, $w, $h, $link)
630
    {
631
        //Put a link on the page
632
        $this->PageLinks[$this->page][] = [
633
            $x*$this->k,
634
            $this->hPt-$y*$this->k,
635
            $w*$this->k,
636
            $h*$this->k,
637
            $link
638
        ];
639
    }
640
    
641 1
    public function text($x, $y, $txt)
642
    {
643
        //Output a string
644 1
        $s = sprintf('BT %.2F %.2F Td (%s) Tj ET', $x*$this->k, ($this->h-$y)*$this->k, $this->escape($txt));
645 1
        if ($this->underline && $txt!='') {
646
            $s .= ' '.$this->doUnderLine($x, $y, $txt);
647
        }
648 1
        if ($this->colorFlag) {
649 1
            $s = 'q '.$this->textColor.' '.$s.' Q';
650
        }
651 1
        $this->out($s);
652 1
    }
653
    
654
    public function acceptPageBreak()
655
    {
656
        //Accept automatic page break or not
657
        return $this->autoPageBreak;
658
    }
659
    
660
    public function cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = false, $link = '')
661
    {
662
        //Output a cell
663
        $k = $this->k;
664
        if ($this->y+$h > $this->PageBreakTrigger
0 ignored issues
show
Bug introduced by
The property PageBreakTrigger does not seem to exist. Did you mean pageBreakTrigger?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
665
            && !$this->InHeader
0 ignored issues
show
Bug introduced by
The property InHeader does not seem to exist. Did you mean inHeader?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
666
            && !$this->InFooter
0 ignored issues
show
Bug introduced by
The property InFooter does not seem to exist. Did you mean inFooter?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
667
            && $this->acceptPageBreak()
668
        ) {
669
            //Automatic page break
670
            $x = $this->x;
671
            $ws = $this->ws;
672
            if ($ws > 0) {
673
                $this->ws = 0;
674
                $this->out('0 Tw');
675
            }
676
            $this->addPage($this->curOrientation, $this->curPageFormat);
0 ignored issues
show
Documentation introduced by
$this->curPageFormat is of type array<integer,integer|do...,"1":"integer|double"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
677
            $this->x = $x;
678
            if ($ws > 0) {
679
                $this->ws = $ws;
680
                $this->out(sprintf('%.3F Tw', $ws*$k));
681
            }
682
        }
683
        if ($w == 0) {
684
            $w = $this->w-$this->rMargin-$this->x;
685
        }
686
        $s='';
687
        if ($fill || $border==1) {
688
            if ($fill) {
689
                $op=($border==1) ? 'B' : 'f';
690
            } else {
691
                $op='S';
692
            }
693
            $s=sprintf('%.2F %.2F %.2F %.2F re %s ', $this->x*$k, ($this->h-$this->y)*$k, $w*$k, -$h*$k, $op);
694
        }
695
        if (is_string($border)) {
696
            $x = $this->x;
697
            $y = $this->y;
698
            if (strpos($border, 'L') !== false) {
699
                $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $x*$k, ($this->h-$y)*$k, $x*$k, ($this->h-($y+$h))*$k);
700
            }
701
            if (strpos($border, 'T') !== false) {
702
                $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $x*$k, ($this->h-$y)*$k, ($x+$w)*$k, ($this->h-$y)*$k);
703
            }
704
            if (strpos($border, 'R') !== false) {
705
                $s .= sprintf(
706
                    '%.2F %.2F m %.2F %.2F l S ',
707
                    ($x+$w)*$k,
708
                    ($this->h-$y)*$k,
709
                    ($x+$w)*$k,
710
                    ($this->h-($y+$h))*$k
711
                );
712
            }
713
            if (strpos($border, 'B') !== false) {
714
                $s .= sprintf(
715
                    '%.2F %.2F m %.2F %.2F l S ',
716
                    $x*$k,
717
                    ($this->h-($y+$h))*$k,
718
                    ($x+$w)*$k,
719
                    ($this->h-($y+$h))*$k
720
                );
721
            }
722
        }
723
        if ($txt !== '') {
724
            if ($align == 'R') {
725
                $dx = $w-$this->cMargin-$this->getStringWidth($txt);
726
            } elseif ($align == 'C') {
727
                $dx = ($w-$this->getStringWidth($txt))/2;
728
            } else {
729
                $dx = $this->cMargin;
730
            }
731
            if ($this->colorFlag) {
732
                $s .= 'q '.$this->textColor.' ';
733
            }
734
            $txt2 = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)));
735
            $s .= sprintf(
736
                'BT %.2F %.2F Td (%s) Tj ET',
737
                ($this->x+$dx)*$k,
738
                ($this->h-($this->y+.5*$h+.3*$this->fontSize))*$k,
739
                $txt2
740
            );
741
            if ($this->underline) {
742
                $s .= ' '.$this->doUnderLine($this->x+$dx, $this->y+.5*$h+.3*$this->fontSize, $txt);
743
            }
744
            if ($this->colorFlag) {
745
                $s.=' Q';
746
            }
747
            if ($link) {
748
                $this->link(
749
                    $this->x+$dx,
750
                    $this->y+.5*$h-.5*$this->fontSize,
751
                    $this->getStringWidth($txt),
752
                    $this->fontSize,
753
                    $link
754
                );
755
            }
756
        }
757
        if ($s) {
758
            $this->out($s);
759
        }
760
        $this->lasth = $h;
761
        if ($ln > 0) {
762
            //Go to next line
763
            $this->y += $h;
764
            if ($ln == 1) {
765
                $this->x = $this->lMargin;
766
            }
767
        } else {
768
            $this->x += $w;
769
        }
770
    }
771
    
772
    public function multicell($w, $h, $txt, $border = 0, $align = 'J', $fill = false)
773
    {
774
        //Output text with automatic or explicit line breaks
775
        $cw =& $this->currentFont['cw'];
776
        if ($w == 0) {
777
            $w = $this->w-$this->rMargin-$this->x;
778
        }
779
        $wmax = ($w-2*$this->cMargin)*1000/$this->fontSize;
780
        $s = str_replace("\r", '', $txt);
781
        $nb = strlen($s);
782
        if ($nb>0 && $s[$nb-1] == "\n") {
783
            $nb--;
784
        }
785
        $b = 0;
786
        if ($border) {
787
            if ($border == 1) {
788
                $border = 'LTRB';
789
                $b = 'LRT';
790
                $b2 = 'LR';
791
            } else {
792
                $b2 = '';
793
                if (strpos($border, 'L') !== false) {
794
                    $b2 .= 'L';
795
                }
796
                if (strpos($border, 'R') !== false) {
797
                    $b2 .= 'R';
798
                }
799
                $b=(strpos($border, 'T') !== false) ? $b2.'T' : $b2;
800
            }
801
        }
802
        $sep = -1;
803
        $i = 0;
804
        $j = 0;
805
        $l = 0;
806
        $ns = 0;
807
        $nl = 1;
808
        while ($i<$nb) {
809
            //Get next character
810
            $c = $s[$i];
811
            if ($c == "\n") {
812
                //Explicit line break
813
                if ($this->ws > 0) {
814
                    $this->ws = 0;
815
                    $this->out('0 Tw');
816
                }
817
                $this->cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill);
818
                $i++;
819
                $sep = -1;
820
                $j = $i;
821
                $l = 0;
822
                $ns = 0;
823
                $nl++;
824
                if ($border && $nl == 2) {
825
                    $b=$b2;
0 ignored issues
show
Bug introduced by
The variable $b2 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
826
                }
827
                continue;
828
            }
829
            if ($c == ' ') {
830
                $sep = $i;
831
                $ls = $l;
832
                $ns++;
833
            }
834
            $l += $cw[$c];
835
            if ($l > $wmax) {
836
                //Automatic line break
837
                if ($sep == -1) {
838
                    if ($i == $j) {
839
                        $i++;
840
                    }
841
                    if ($this->ws > 0) {
842
                        $this->ws = 0;
843
                        $this->out('0 Tw');
844
                    }
845
                    $this->cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill);
846
                } else {
847
                    if ($align=='J') {
848
                        $this->ws = ($ns>1) ? ($wmax-$ls)/1000*$this->fontSize/($ns-1) : 0;
0 ignored issues
show
Bug introduced by
The variable $ls does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
849
                        $this->out(sprintf('%.3F Tw', $this->ws*$this->k));
850
                    }
851
                    $this->cell($w, $h, substr($s, $j, $sep-$j), $b, 2, $align, $fill);
852
                    $i = $sep+1;
853
                }
854
                $sep = -1;
855
                $j = $i;
856
                $l = 0;
857
                $ns = 0;
858
                $nl++;
859
                if ($border && $nl == 2) {
860
                    $b = $b2;
861
                }
862
            } else {
863
                $i++;
864
            }
865
        }
866
        //Last chunk
867
        if ($this->ws > 0) {
868
            $this->ws = 0;
869
            $this->out('0 Tw');
870
        }
871
        if ($border && strpos($border, 'B')!==false) {
872
            $b .= 'B';
873
        }
874
        $this->cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill);
875
        $this->x = $this->lMargin;
876
    }
877
    
878
    
879
    public function write($h, $txt, $link = '')
880
    {
881
        //Output text in flowing mode
882
        $cw =& $this->currentFont['cw'];
883
        $w = $this->w-$this->rMargin-$this->x;
884
        $wmax = ($w-2*$this->cMargin)*1000/$this->fontSize;
885
        $s = str_replace("\r", '', $txt);
886
        $nb = strlen($s);
887
        $sep = -1;
888
        $i = 0;
889
        $j = 0;
890
        $l = 0;
891
        $nl = 1;
892
        while ($i < $nb) {
893
            //Get next character
894
            $c=$s[$i];
895
            if ($c=="\n") {
896
                //Explicit line break
897
                $this->cell($w, $h, substr($s, $j, $i-$j), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
898
                $i++;
899
                $sep = -1;
900
                $j = $i;
901
                $l = 0;
902
                if ($nl == 1) {
903
                    $this->x = $this->lMargin;
904
                    $w = $this->w-$this->rMargin-$this->x;
905
                    $wmax = ($w-2*$this->cMargin)*1000/$this->fontSize;
906
                }
907
                $nl++;
908
                continue;
909
            }
910
            if ($c == ' ') {
911
                $sep = $i;
912
            }
913
            $l += $cw[$c];
914
            if ($l > $wmax) {
915
                //Automatic line break
916
                if ($sep == -1) {
917
                    if ($this->x > $this->lMargin) {
918
                        //Move to next line
919
                        $this->x = $this->lMargin;
920
                        $this->y += $h;
921
                        $w = $this->w-$this->rMargin-$this->x;
922
                        $wmax = ($w-2*$this->cMargin)*1000/$this->fontSize;
923
                        $i++;
924
                        $nl++;
925
                        continue;
926
                    }
927
                    if ($i == $j) {
928
                        $i++;
929
                    }
930
                    $this->cell($w, $h, substr($s, $j, $i-$j), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
931
                } else {
932
                    $this->cell($w, $h, substr($s, $j, $sep-$j), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
933
                    $i = $sep+1;
934
                }
935
                $sep = -1;
936
                $j = $i;
937
                $l = 0;
938
                if ($nl == 1) {
939
                    $this->x = $this->lMargin;
940
                    $w = $this->w-$this->rMargin-$this->x;
941
                    $wmax = ($w-2*$this->cMargin)*1000/$this->fontSize;
942
                }
943
                $nl++;
944
            } else {
945
                $i++;
946
            }
947
        }
948
        //Last chunk
949
        if ($i != $j) {
950
            $this->cell($l/1000*$this->fontSize, $h, substr($s, $j), 0, 0, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
951
        }
952
    }
953
    
954
    public function ln($h = null)
955
    {
956
        //Line feed; default value is last cell height
957
        $this->x = $this->lMargin;
958
        if ($h === null) {
959
            $this->y += $this->lasth;
960
        } else {
961
            $this->y += $h;
962
        }
963
    }
964
    
965
    public function image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '')
966
    {
967
        //Put an image on the page
968
        if (!isset($this->images[$file])) {
969
            //First use of this image, get info
970
            if ($type == '') {
971
                $pos = strrpos($file, '.');
972
                if (!$pos) {
973
                    $this->error('Image file has no extension and no type was specified: '.$file);
974
                }
975
                $type = substr($file, $pos+1);
976
            }
977
            $type = strtolower($type);
978
            if ($type == 'jpeg') {
979
                $type = 'jpg';
980
            }
981
            $mtd = 'parse'.strtoupper($type);
982
            if (!method_exists($this, $mtd)) {
983
                $this->error('Unsupported image type: '.$type);
984
            }
985
            $info = $this->$mtd($file);
986
            $info['i'] = count($this->images)+1;
987
            $this->images[$file] = $info;
988
        } else {
989
            $info = $this->images[$file];
990
        }
991
        //Automatic width and height calculation if needed
992
        if ($w == 0 && $h == 0) {
993
            //Put image at 72 dpi
994
            $w = $info['w']/$this->k;
995
            $h = $info['h']/$this->k;
996
        } elseif ($w == 0) {
997
            $w = $h*$info['w']/$info['h'];
998
        } elseif ($h == 0) {
999
            $h = $w*$info['h']/$info['w'];
1000
        }
1001
        //Flowing mode
1002
        if ($y === null) {
1003
            if ($this->y+$h > $this->pageBreakTrigger
1004
                && !$this->inHeader
1005
                && !$this->inFooter
1006
                && $this->acceptPageBreak()
1007
            ) {
1008
                //Automatic page break
1009
                $x2 = $this->x;
1010
                $this->addPage($this->curOrientation, $this->curPageFormat);
0 ignored issues
show
Documentation introduced by
$this->curPageFormat is of type array<integer,integer|do...,"1":"integer|double"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1011
                $this->x = $x2;
1012
            }
1013
            $y = $this->y;
1014
            $this->y += $h;
1015
        }
1016
        if ($x === null) {
1017
            $x = $this->x;
1018
        }
1019
        $this->out(
1020
            sprintf(
1021
                'q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q',
1022
                $w*$this->k,
1023
                $h*$this->k,
1024
                $x*$this->k,
1025
                ($this->h-($y+$h))*$this->k,
1026
                $info['i']
1027
            )
1028
        );
1029
        if ($link) {
1030
            $this->link($x, $y, $w, $h, $link);
1031
        }
1032
    }
1033
    
1034
    
1035
    public function getX()
1036
    {
1037
        //Get x position
1038
        return $this->x;
1039
    }
1040
    
1041
    
1042
    public function setX($x)
1043
    {
1044
        //Set x position
1045
        if ($x >= 0) {
1046
            $this->x = $x;
1047
        } else {
1048
            $this->x = $this->w+$x;
1049
        }
1050
    }
1051
    
1052
    
1053
    public function getY()
1054
    {
1055
        //Get y position
1056
        return $this->y;
1057
    }
1058
    
1059
    
1060
    public function setY($y)
1061
    {
1062
        //Set y position and reset x
1063
        $this->x = $this->lMargin;
1064
        if ($y >= 0) {
1065
            $this->y = $y;
1066
        } else {
1067
            $this->y = $this->h+$y;
1068
        }
1069
    }
1070
    
1071
    
1072
    public function setXY($x, $y)
1073
    {
1074
        //Set x and y positions
1075
        $this->setY($y);
1076
        $this->setX($x);
1077
    }
1078
    
1079
    public function getPdf()
1080
    {
1081
        if ($this->state < 3) {
1082
            $this->close();
1083
        }
1084
        return $this->buffer;
1085
    }
1086
    
1087 1
    public function output($name = '', $dest = '')
1088
    {
1089
        //Output PDF to some destination
1090 1
        if ($this->state < 3) {
1091 1
            $this->close();
1092
        }
1093 1
        $dest = strtoupper($dest);
1094 1
        if ($dest == '') {
1095
            if ($name == '') {
1096
                $name = 'doc.pdf';
1097
                $dest = 'I';
1098
            } else {
1099
                $dest = 'F';
1100
            }
1101
        }
1102
        switch ($dest) {
1103 1
            case 'I':
1104
                //Send to standard output
1105
                if (ob_get_length()) {
1106
                    $this->error('Some data has already been output, can\'t send PDF file');
1107
                }
1108
                if (php_sapi_name() != 'cli') {
1109
                    //We send to a browser
1110
                    header('Content-Type: application/pdf');
1111
                    if (headers_sent()) {
1112
                        $this->error('Some data has already been output, can\'t send PDF file');
1113
                    }
1114
                    header('Content-Length: '.strlen($this->buffer));
1115
                    header('Content-Disposition: inline; filename="'.$name.'"');
1116
                    header('Cache-Control: private, max-age=0, must-revalidate');
1117
                    header('Pragma: public');
1118
                    ini_set('zlib.output_compression', '0');
1119
                }
1120
                echo $this->buffer;
1121
                break;
1122 1
            case 'D':
1123
                //Download file
1124
                if (ob_get_length()) {
1125
                    $this->error('Some data has already been output, can\'t send PDF file');
1126
                }
1127
                header('Content-Type: application/x-download');
1128
                if (headers_sent()) {
1129
                    $this->error('Some data has already been output, can\'t send PDF file');
1130
                }
1131
                header('Content-Length: '.strlen($this->buffer));
1132
                header('Content-Disposition: attachment; filename="'.$name.'"');
1133
                header('Cache-Control: private, max-age=0, must-revalidate');
1134
                header('Pragma: public');
1135
                ini_set('zlib.output_compression', '0');
1136
                echo $this->buffer;
1137
                break;
1138 1
            case 'F':
1139
                //Save to local file
1140 1
                $f=fopen($name, 'wb');
1141 1
                if (!$f) {
1142
                    $this->error('Unable to create output file: '.$name);
1143
                }
1144 1
                fwrite($f, $this->buffer, strlen($this->buffer));
1145 1
                fclose($f);
1146 1
                break;
1147
            case 'S':
1148
                //Return as a string
1149
                return $this->buffer;
1150
            default:
1151
                $this->error('Incorrect output destination: '.$dest);
1152
        }
1153 1
        return '';
1154
    }
1155
    
1156
    
1157 1
    protected function dochecks()
1158
    {
1159
        //Check availability of %F
1160 1
        if (sprintf('%.1F', 1.0)!='1.0') {
1161
            $this->error('This version of PHP is not supported');
1162
        }
1163
        //Check mbstring overloading
1164 1
        if (ini_get('mbstring.func_overload') & 2) {
1165
            $this->error('mbstring overloading must be disabled');
1166
        }
1167 1
    }
1168
    
1169
    
1170 1
    protected function getpageformat($format)
1171
    {
1172 1
        $format=strtolower($format);
1173 1
        if (!isset($this->pageFormats[$format])) {
1174
            $this->error('Unknown page format: '.$format);
1175
        }
1176 1
        $a=$this->pageFormats[$format];
1177 1
        return array($a[0]/$this->k, $a[1]/$this->k);
1178
    }
1179
    
1180
    
1181 1
    protected function getFontPath()
1182
    {
1183 1
        if (!defined('FPDF_FONTPATH') && is_dir(dirname(__FILE__).'/font')) {
1184
            define('FPDF_FONTPATH', dirname(__FILE__).'/font/');
1185
        }
1186 1
        return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : '';
1187
    }
1188
    
1189
    
1190 1
    protected function beginPage($orientation, $format)
1191
    {
1192 1
        $this->page++;
1193 1
        $this->pages[$this->page] = '';
1194 1
        $this->state = 2;
1195 1
        $this->x = $this->lMargin;
1196 1
        $this->y = $this->tMargin;
1197 1
        $this->fontFamily = '';
1198
        //Check page size
1199 1
        if ($orientation == '') {
1200
            $orientation = $this->defOrientation;
1201
        } else {
1202 1
            $orientation = strtoupper($orientation[0]);
1203
        }
1204 1
        if ($format == '') {
1205
            $format = $this->defPageFormat;
1206
        } else {
1207 1
            if (is_string($format)) {
1208 1
                $format=$this->getpageformat($format);
1209
            }
1210
        }
1211 1
        if ($orientation != $this->curOrientation
1212 1
            || $format[0]!=$this->curPageFormat[0]
1213 1
            || $format[1]!=$this->curPageFormat[1]
1214
        ) {
1215
            //New size
1216
            if ($orientation == 'P') {
1217
                $this->w = $format[0];
1218
                $this->h = $format[1];
1219
            } else {
1220
                $this->w = $format[1];
1221
                $this->h = $format[0];
1222
            }
1223
            $this->wPt = $this->w*$this->k;
1224
            $this->hPt = $this->h*$this->k;
1225
            $this->pageBreakTrigger = $this->h-$this->bMargin;
1226
            $this->curOrientation = $orientation;
1227
            $this->curPageFormat = $format;
1228
        }
1229 1
        if ($orientation != $this->defOrientation
1230 1
            || $format[0] != $this->defPageFormat[0]
1231 1
            || $format[1] != $this->defPageFormat[1]
1232
        ) {
1233
            $this->PageSizes[$this->page] = array($this->wPt, $this->hPt);
0 ignored issues
show
Bug introduced by
The property PageSizes does not seem to exist. Did you mean pageSizes?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1234
        }
1235 1
    }
1236
    
1237
    
1238 1
    protected function endPage()
1239
    {
1240 1
        $this->state = 1;
1241 1
    }
1242
    
1243
    
1244 1
    protected function escape($s)
1245
    {
1246
        //Escape special characters in strings
1247 1
        $s = str_replace('\\', '\\\\', $s);
1248 1
        $s = str_replace('(', '\\(', $s);
1249 1
        $s = str_replace(')', '\\)', $s);
1250 1
        $s = str_replace("\r", '\\r', $s);
1251 1
        return $s;
1252
    }
1253
    
1254
    
1255 1
    protected function textString($s)
1256
    {
1257
        //Format a text string
1258 1
        return '('.$this->escape($s).')';
1259
    }
1260
    
1261
    
1262
    protected function utf8Toutf16($s)
1263
    {
1264
        //Convert UTF-8 to UTF-16BE with BOM
1265
        $res = "\xFE\xFF";
1266
        $nb = strlen($s);
1267
        $i = 0;
1268
        while ($i < $nb) {
1269
            $c1 = ord($s[$i++]);
1270
            if ($c1 >= 224) {
1271
                //3-byte character
1272
                $c2 = ord($s[$i++]);
1273
                $c3 = ord($s[$i++]);
1274
                $res .= chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2));
1275
                $res .= chr((($c2 & 0x03)<<6) + ($c3 & 0x3F));
1276
            } elseif ($c1 >= 192) {
1277
                //2-byte character
1278
                $c2 = ord($s[$i++]);
1279
                $res .= chr(($c1 & 0x1C)>>2);
1280
                $res .= chr((($c1 & 0x03)<<6) + ($c2 & 0x3F));
1281
            } else {
1282
                //Single-byte character
1283
                $res .= "\0".chr($c1);
1284
            }
1285
        }
1286
        return $res;
1287
    }
1288
    
1289
    
1290
    protected function doUnderLine($x, $y, $txt)
1291
    {
1292
        //Underline text
1293
        $up = $this->currentFont['up'];
1294
        $ut = $this->currentFont['ut'];
1295
        $w = $this->getStringWidth($txt)+$this->ws*substr_count($txt, ' ');
1296
        return sprintf(
1297
            '%.2F %.2F %.2F %.2F re f',
1298
            $x*$this->k,
1299
            ($this->h-($y-$up/1000*$this->fontSize))*$this->k,
1300
            $w*$this->k,
1301
            -$ut/1000*$this->fontSizePt
1302
        );
1303
    }
1304
    
1305
    
1306
    protected function parseJPG($file)
1307
    {
1308
        //Extract info from a JPEG file
1309
        $a = getImageSize($file);
1310
        if (!$a) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $a of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1311
            $this->error('Missing or incorrect image file: '.$file);
1312
        }
1313
        if ($a[2]!=2) {
1314
            $this->error('Not a JPEG file: '.$file);
1315
        }
1316
        if (!isset($a['channels']) || $a['channels'] == 3) {
1317
            $colspace = 'DeviceRGB';
1318
        } elseif ($a['channels'] == 4) {
1319
            $colspace = 'DeviceCMYK';
1320
        } else {
1321
            $colspace='DeviceGray';
1322
        }
1323
        $bpc = isset($a['bits']) ? $a['bits'] : 8;
1324
        //Read whole file
1325
        $f = fopen($file, 'rb');
1326
        $data = '';
1327
        while (!feof($f)) {
1328
            $data .= fread($f, 8192);
1329
        }
1330
        fclose($f);
1331
        return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data);
1332
    }
1333
    
1334
    
1335
    protected function parsePNG($file)
1336
    {
1337
        //Extract info from a PNG file
1338
        $f = fopen($file, 'rb');
1339
        if (!$f) {
1340
            $this->error('Can\'t open image file: '.$file);
1341
        }
1342
        //Check signature
1343
        if ($this->readstream($f, 8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
1344
            $this->error('Not a PNG file: '.$file);
1345
        }
1346
        //Read header chunk
1347
        $this->readstream($f, 4);
1348
        if ($this->readstream($f, 4)!='IHDR') {
1349
            $this->error('Incorrect PNG file: '.$file);
1350
        }
1351
        $w = $this->readint($f);
1352
        $h = $this->readint($f);
1353
        $bpc = ord($this->readstream($f, 1));
1354
        if ($bpc>8) {
1355
            $this->error('16-bit depth not supported: '.$file);
1356
        }
1357
        $ct = ord($this->readstream($f, 1));
1358
        if ($ct == 0) {
1359
            $colspace = 'DeviceGray';
1360
        } elseif ($ct == 2) {
1361
            $colspace = 'DeviceRGB';
1362
        } elseif ($ct == 3) {
1363
            $colspace = 'Indexed';
1364
        } else {
1365
            $this->error('Alpha channel not supported: '.$file);
1366
        }
1367
        if (ord($this->readstream($f, 1)) != 0) {
1368
            $this->error('Unknown compression method: '.$file);
1369
        }
1370
        if (ord($this->readstream($f, 1)) != 0) {
1371
            $this->error('Unknown filter method: '.$file);
1372
        }
1373
        if (ord($this->readstream($f, 1)) != 0) {
1374
            $this->error('Interlacing not supported: '.$file);
1375
        }
1376
        $this->readstream($f, 4);
1377
        $parms = '/DecodeParms <</Predictor 15 /Colors '
1378
            . ($ct==2 ? 3 : 1)
1379
            . ' /BitsPerComponent '
1380
            . $bpc
1381
            . ' /Columns '
1382
            . $w
1383
            . '>>';
1384
        //Scan chunks looking for palette, transparency and image data
1385
        $pal = '';
1386
        $trns = '';
1387
        $data = '';
1388
        do {
1389
            $n = $this->readint($f);
1390
            $type = $this->readstream($f, 4);
1391
            if ($type == 'PLTE') {
1392
                //Read palette
1393
                $pal = $this->readstream($f, $n);
1394
                $this->readstream($f, 4);
1395
            } elseif ($type == 'tRNS') {
1396
                //Read transparency info
1397
                $t = $this->readstream($f, $n);
1398
                if ($ct == 0) {
1399
                    $trns = array(ord(substr($t, 1, 1)));
1400
                } elseif ($ct == 2) {
1401
                    $trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1)));
1402
                } else {
1403
                    $pos = strpos($t, chr(0));
1404
                    if ($pos !== false) {
1405
                        $trns = array($pos);
1406
                    }
1407
                }
1408
                $this->readstream($f, 4);
1409
            } elseif ($type == 'IDAT') {
1410
                //Read image data block
1411
                $data .= $this->readstream($f, $n);
1412
                $this->readstream($f, 4);
1413
            } elseif ($type == 'IEND') {
1414
                break;
1415
            } else {
1416
                $this->readstream($f, $n+4);
1417
            }
1418
        } while ($n);
1419
        if ($colspace == 'Indexed' && empty($pal)) {
0 ignored issues
show
Bug introduced by
The variable $colspace does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1420
            $this->error('Missing palette in '.$file);
1421
        }
1422
        fclose($f);
1423
        return [
1424
            'w'=>$w,
1425
            'h'=>$h,
1426
            'cs'=>$colspace,
1427
            'bpc'=>$bpc,
1428
            'f'=>'FlateDecode',
1429
            'parms'=>$parms,
1430
            'pal'=>$pal,
1431
            'trns'=>$trns,
1432
            'data'=>$data
1433
        ];
1434
    }
1435
    
1436
    
1437
    protected function readstream($f, $n)
1438
    {
1439
        //Read n bytes from stream
1440
        $res='';
1441
        while ($n > 0 && !feof($f)) {
1442
            $s=fread($f, $n);
1443
            if ($s === false) {
1444
                $this->error('Error while reading stream');
1445
            }
1446
            $n -= strlen($s);
1447
            $res .= $s;
1448
        }
1449
        if ($n > 0) {
1450
            $this->error('Unexpected end of stream');
1451
        }
1452
        return $res;
1453
    }
1454
    
1455
    
1456
    protected function readint($f)
1457
    {
1458
        //Read a 4-byte integer from stream
1459
        $a = unpack('Ni', $this->readstream($f, 4));
1460
        return $a['i'];
1461
    }
1462
    
1463
    
1464
    protected function parseGIF($file)
1465
    {
1466
        //Extract info from a GIF file (via PNG conversion)
1467
        if (!function_exists('imagepng')) {
1468
            $this->error('GD extension is required for GIF support');
1469
        }
1470
        if (!function_exists('imagecreatefromgif')) {
1471
            $this->error('GD has no GIF read support');
1472
        }
1473
        $im = imagecreatefromgif($file);
1474
        if (!$im) {
1475
            $this->error('Missing or incorrect image file: '.$file);
1476
        }
1477
        imageinterlace($im, 0);
1478
        $tmp = tempnam('.', 'gif');
1479
        if (!$tmp) {
1480
            $this->error('Unable to create a temporary file');
1481
        }
1482
        if (!imagepng($im, $tmp)) {
1483
            $this->error('Error while saving to temporary file');
1484
        }
1485
        imagedestroy($im);
1486
        $info=$this->parsePNG($tmp);
1487
        unlink($tmp);
1488
        return $info;
1489
    }
1490
    
1491
    
1492 1
    protected function newObj()
1493
    {
1494
        //Begin a new object
1495 1
        $this->n++;
1496 1
        $this->offsets[$this->n] = strlen($this->buffer);
1497 1
        $this->out($this->n.' 0 obj');
1498 1
    }
1499
    
1500
    
1501 1
    protected function putStream($s)
1502
    {
1503 1
        $this->out('stream');
1504 1
        $this->out($s);
1505 1
        $this->out('endstream');
1506 1
    }
1507
    
1508
    
1509 1
    protected function out($s)
1510
    {
1511
        //Add a line to the document
1512 1
        if ($this->state == 2) {
1513 1
            $this->pages[$this->page].=$s."\n";
1514
        } else {
1515 1
            $this->buffer .= $s."\n";
1516
        }
1517 1
    }
1518
    
1519
    
1520 1
    protected function putPages()
1521
    {
1522 1
        $nb = $this->page;
1523 1
        if (!empty($this->aliasNbPages)) {
1524
            //Replace number of pages
1525 1
            for ($n=1; $n<=$nb; $n++) {
1526 1
                $this->pages[$n] = str_replace($this->aliasNbPages, $nb, $this->pages[$n]);
1527
            }
1528
        }
1529 1
        if ($this->defOrientation == 'P') {
1530 1
            $wPt = $this->defPageFormat[0]*$this->k;
1531 1
            $hPt = $this->defPageFormat[1]*$this->k;
1532
        } else {
1533
            $wPt = $this->defPageFormat[1]*$this->k;
1534
            $hPt = $this->defPageFormat[0]*$this->k;
1535
        }
1536 1
        $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
1537 1
        for ($n=1; $n<=$nb; $n++) {
1538
            //Page
1539 1
            $this->newObj();
1540 1
            $this->out('<</Type /Page');
1541 1
            $this->out('/Parent 1 0 R');
1542 1
            if (isset($this->PageSizes[$n])) {
0 ignored issues
show
Bug introduced by
The property PageSizes does not seem to exist. Did you mean pageSizes?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1543
                $this->out(sprintf('/MediaBox [0 0 %.2F %.2F]', $this->PageSizes[$n][0], $this->PageSizes[$n][1]));
0 ignored issues
show
Bug introduced by
The property PageSizes does not seem to exist. Did you mean pageSizes?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1544
            }
1545 1
            $this->out('/Resources 2 0 R');
1546 1
            if (isset($this->PageLinks[$n])) {
1547
                //Links
1548
                $annots = '/Annots [';
1549
                foreach ($this->PageLinks[$n] as $pl) {
1550
                    $rect = sprintf('%.2F %.2F %.2F %.2F', $pl[0], $pl[1], $pl[0]+$pl[2], $pl[1]-$pl[3]);
1551
                    $annots .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
1552
                    if (is_string($pl[4])) {
1553
                        $annots .= '/A <</S /URI /URI '.$this->textString($pl[4]).'>>>>';
1554
                    } else {
1555
                        $l = $this->links[$pl[4]];
1556
                        $h = isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt;
0 ignored issues
show
Bug introduced by
The property PageSizes does not seem to exist. Did you mean pageSizes?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1557
                        $annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>', 1+2*$l[0], $h-$l[1]*$this->k);
1558
                    }
1559
                }
1560
                $this->out($annots.']');
1561
            }
1562 1
            $this->out('/Contents '.($this->n+1).' 0 R>>');
1563 1
            $this->out('endobj');
1564
            //Page content
1565 1
            $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
1566 1
            $this->newObj();
1567 1
            $this->out('<<'.$filter.'/Length '.strlen($p).'>>');
1568 1
            $this->putStream($p);
1569 1
            $this->out('endobj');
1570
        }
1571
        //Pages root
1572 1
        $this->offsets[1]=strlen($this->buffer);
1573 1
        $this->out('1 0 obj');
1574 1
        $this->out('<</Type /Pages');
1575 1
        $kids = '/Kids [';
1576 1
        for ($i=0; $i<$nb; $i++) {
1577 1
            $kids .= (3+2*$i).' 0 R ';
1578
        }
1579 1
        $this->out($kids.']');
1580 1
        $this->out('/Count '.$nb);
1581 1
        $this->out(sprintf('/MediaBox [0 0 %.2F %.2F]', $wPt, $hPt));
1582 1
        $this->out('>>');
1583 1
        $this->out('endobj');
1584 1
    }
1585
    
1586
    
1587 1
    protected function putFonts()
1588
    {
1589 1
        $nf = $this->n;
1590 1
        foreach ($this->diffs as $diff) {
1591
            //Encodings
1592
            $this->newObj();
1593
            $this->out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
1594
            $this->out('endobj');
1595
        }
1596 1
        foreach ($this->fontFiles as $file => $info) {
1597
            //Font file embedding
1598
            $this->newObj();
1599
            $this->fontFiles[$file]['n']=$this->n;
1600
            $font='';
1601
            $f = fopen($this->getFontPath().$file, 'rb', 1);
1602
            if (!$f) {
1603
                $this->error('Font file not found');
1604
            }
1605
            while (!feof($f)) {
1606
                $font.=fread($f, 8192);
1607
            }
1608
            fclose($f);
1609
            $compressed = (substr($file, -2)=='.z');
1610
            if (!$compressed && isset($info['length2'])) {
1611
                $header = (ord($font[0])==128);
1612
                if ($header) {
1613
                    //Strip first binary header
1614
                    $font = substr($font, 6);
1615
                }
1616
                if ($header && ord($font[$info['length1']]) == 128) {
1617
                    //Strip second binary header
1618
                    $font = substr($font, 0, $info['length1']).substr($font, $info['length1']+6);
1619
                }
1620
            }
1621
            $this->out('<</Length '.strlen($font));
1622
            if ($compressed) {
1623
                $this->out('/Filter /FlateDecode');
1624
            }
1625
            $this->out('/Length1 '.$info['length1']);
1626
            if (isset($info['length2'])) {
1627
                $this->out('/Length2 '.$info['length2'].' /Length3 0');
1628
            }
1629
            $this->out('>>');
1630
            $this->putStream($font);
1631
            $this->out('endobj');
1632
        }
1633 1
        foreach ($this->fonts as $k => $font) {
1634
            //Font objects
1635 1
            $this->fonts[$k]['n']=$this->n+1;
1636 1
            $type = $font['type'];
1637 1
            $name = $font['name'];
1638 1
            if ($type == 'core') {
1639
                //Standard font
1640 1
                $this->newObj();
1641 1
                $this->out('<</Type /Font');
1642 1
                $this->out('/BaseFont /'.$name);
1643 1
                $this->out('/Subtype /Type1');
1644 1
                if ($name != 'Symbol' && $name != 'ZapfDingbats') {
1645 1
                    $this->out('/Encoding /WinAnsiEncoding');
1646
                }
1647 1
                $this->out('>>');
1648 1
                $this->out('endobj');
1649
            } elseif ($type=='Type1' || $type=='TrueType') {
1650
                //Additional Type1 or TrueType font
1651
                $this->newObj();
1652
                $this->out('<</Type /Font');
1653
                $this->out('/BaseFont /'.$name);
1654
                $this->out('/Subtype /'.$type);
1655
                $this->out('/FirstChar 32 /LastChar 255');
1656
                $this->out('/Widths '.($this->n+1).' 0 R');
1657
                $this->out('/FontDescriptor '.($this->n+2).' 0 R');
1658
                if ($font['enc']) {
1659
                    if (isset($font['diff'])) {
1660
                        $this->out('/Encoding '.($nf+$font['diff']).' 0 R');
1661
                    } else {
1662
                        $this->out('/Encoding /WinAnsiEncoding');
1663
                    }
1664
                }
1665
                $this->out('>>');
1666
                $this->out('endobj');
1667
                //Widths
1668
                $this->newObj();
1669
                $cw =& $font['cw'];
1670
                $s = '[';
1671
                for ($i=32; $i<=255; $i++) {
1672
                    $s .= $cw[chr($i)].' ';
1673
                }
1674
                $this->out($s.']');
1675
                $this->out('endobj');
1676
                //Descriptor
1677
                $this->newObj();
1678
                $s='<</Type /FontDescriptor /FontName /'.$name;
1679
                foreach ($font['desc'] as $k => $v) {
1680
                    $s .= ' /'.$k.' '.$v;
1681
                }
1682
                $file=$font['file'];
1683
                if ($file) {
1684
                    $s .= ' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->fontFiles[$file]['n'].' 0 R';
1685
                }
1686
                $this->out($s.'>>');
1687
                $this->out('endobj');
1688
            } else {
1689
                //Allow for additional types
1690
                $mtd='_put'.strtolower($type);
1691
                if (!method_exists($this, $mtd)) {
1692
                    $this->error('Unsupported font type: '.$type);
1693
                }
1694 1
                $this->$mtd($font);
1695
            }
1696
        }
1697 1
    }
1698
    
1699
    
1700 1
    protected function putImages()
1701
    {
1702 1
        $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
1703 1
        reset($this->images);
1704
       
1705 1
        foreach ($this->images as $file => $info) {
1706
            $this->newObj();
1707
            $this->images[$file]['n'] = $this->n;
1708
            $this->out('<</Type /XObject');
1709
            $this->out('/Subtype /Image');
1710
            $this->out('/Width '.$info['w']);
1711
            $this->out('/Height '.$info['h']);
1712
            if ($info['cs']=='Indexed') {
1713
                $this->out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
1714
            } else {
1715
                $this->out('/ColorSpace /'.$info['cs']);
1716
                if ($info['cs']=='DeviceCMYK') {
1717
                    $this->out('/Decode [1 0 1 0 1 0 1 0]');
1718
                }
1719
            }
1720
            $this->out('/BitsPerComponent '.$info['bpc']);
1721
            if (isset($info['f'])) {
1722
                $this->out('/Filter /'.$info['f']);
1723
            }
1724
            if (isset($info['parms'])) {
1725
                $this->out($info['parms']);
1726
            }
1727
            if (isset($info['trns']) && is_array($info['trns'])) {
1728
                $trns = '';
1729
                for ($i=0; $i<count($info['trns']); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1730
                    $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
1731
                }
1732
                $this->out('/Mask ['.$trns.']');
1733
            }
1734
            $this->out('/Length '.strlen($info['data']).'>>');
1735
            $this->putStream($info['data']);
1736
            unset($this->images[$file]['data']);
1737
            $this->out('endobj');
1738
            //Palette
1739
            if ($info['cs'] == 'Indexed') {
1740
                $this->newObj();
1741
                $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
1742
                $this->out('<<'.$filter.'/Length '.strlen($pal).'>>');
1743
                $this->putStream($pal);
1744
                $this->out('endobj');
1745
            }
1746
        }
1747 1
    }
1748
    
1749 1
    protected function putXobjectDict()
1750
    {
1751 1
        foreach ($this->images as $image) {
1752
            $this->out('/I'.$image['i'].' '.$image['n'].' 0 R');
1753
        }
1754 1
    }
1755
    
1756 1
    protected function putResourceDict()
1757
    {
1758 1
        $this->out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
1759 1
        $this->out('/Font <<');
1760 1
        foreach ($this->fonts as $font) {
1761 1
            $this->out('/F'.$font['i'].' '.$font['n'].' 0 R');
1762
        }
1763 1
        $this->out('>>');
1764 1
        $this->out('/XObject <<');
1765 1
        $this->putXobjectDict();
1766 1
        $this->out('>>');
1767 1
    }
1768
    
1769 1
    protected function putResources()
1770
    {
1771 1
        $this->putFonts();
1772 1
        $this->putImages();
1773
        //Resource dictionary
1774 1
        $this->offsets[2] = strlen($this->buffer);
1775 1
        $this->out('2 0 obj');
1776 1
        $this->out('<<');
1777 1
        $this->putResourceDict();
1778 1
        $this->out('>>');
1779 1
        $this->out('endobj');
1780 1
    }
1781
    
1782 1
    protected function putInfo()
1783
    {
1784 1
        $this->out('/Producer '.$this->textString('FPDF '. self::FPDF_VERSION));
1785 1
        if (!empty($this->title)) {
1786
            $this->out('/Title '.$this->textString($this->title));
1787
        }
1788 1
        if (!empty($this->subject)) {
1789
            $this->out('/Subject '.$this->textString($this->subject));
1790
        }
1791 1
        if (!empty($this->author)) {
1792
            $this->out('/Author '.$this->textString($this->author));
1793
        }
1794 1
        if (!empty($this->keywords)) {
1795
            $this->out('/Keywords '.$this->textString($this->keywords));
1796
        }
1797 1
        if (!empty($this->creator)) {
1798
            $this->out('/Creator '.$this->textString($this->creator));
1799
        }
1800 1
        $this->out('/CreationDate '.$this->textString('D:'.@date('YmdHis')));
1801 1
    }
1802
    
1803 1
    protected function putCatalog()
1804
    {
1805 1
        $this->out('/Type /Catalog');
1806 1
        $this->out('/Pages 1 0 R');
1807 1
        if ($this->zoomMode=='fullpage') {
1808
            $this->out('/OpenAction [3 0 R /Fit]');
1809 1
        } elseif ($this->zoomMode=='fullwidth') {
1810 1
            $this->out('/OpenAction [3 0 R /FitH null]');
1811
        } elseif ($this->zoomMode=='real') {
1812
            $this->out('/OpenAction [3 0 R /XYZ null null 1]');
1813
        } elseif (!is_string($this->zoomMode)) {
1814
            $this->out('/OpenAction [3 0 R /XYZ null null '.($this->zoomMode/100).']');
1815
        }
1816 1
        if ($this->layoutMode=='single') {
1817
            $this->out('/PageLayout /SinglePage');
1818 1
        } elseif ($this->layoutMode=='continuous') {
1819 1
            $this->out('/PageLayout /OneColumn');
1820
        } elseif ($this->layoutMode=='two') {
1821
            $this->out('/PageLayout /TwoColumnLeft');
1822
        }
1823 1
    }
1824
    
1825 1
    protected function putHeader()
1826
    {
1827 1
        $this->out('%PDF-'.$this->pdfVersion);
1828 1
    }
1829
    
1830 1
    protected function putTrailer()
1831
    {
1832 1
        $this->out('/Size '.($this->n+1));
1833 1
        $this->out('/Root '.$this->n.' 0 R');
1834 1
        $this->out('/Info '.($this->n-1).' 0 R');
1835 1
    }
1836
    
1837 1
    protected function endDoc()
1838
    {
1839 1
        $this->putHeader();
1840 1
        $this->putPages();
1841 1
        $this->putResources();
1842
        //Info
1843 1
        $this->newObj();
1844 1
        $this->out('<<');
1845 1
        $this->putInfo();
1846 1
        $this->out('>>');
1847 1
        $this->out('endobj');
1848
        //Catalog
1849 1
        $this->newObj();
1850 1
        $this->out('<<');
1851 1
        $this->putCatalog();
1852 1
        $this->out('>>');
1853 1
        $this->out('endobj');
1854
        //Cross-ref
1855 1
        $o=strlen($this->buffer);
1856 1
        $this->out('xref');
1857 1
        $this->out('0 '.($this->n+1));
1858 1
        $this->out('0000000000 65535 f ');
1859 1
        for ($i=1; $i<=$this->n; $i++) {
1860 1
            $this->out(sprintf('%010d 00000 n ', $this->offsets[$i]));
1861
        }
1862
        //Trailer
1863 1
        $this->out('trailer');
1864 1
        $this->out('<<');
1865 1
        $this->putTrailer();
1866 1
        $this->out('>>');
1867 1
        $this->out('startxref');
1868 1
        $this->out($o);
1869 1
        $this->out('%%EOF');
1870 1
        $this->state=3;
1871 1
    }
1872
}
1873