FPDF::MultiCell()   F
last analyzed

Complexity

Conditions 26
Paths 5600

Size

Total Lines 112
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 79
nc 5600
nop 6
dl 0
loc 112
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style introduced by
File has mixed line endings; this may cause incorrect results
Loading history...
2
/*******************************************************************************
3
* FPDF                                                                         *
4
*                                                                              *
5
* Version: 1.7                                                                 *
6
* Date:    2011-06-18                                                          *
7
* Author:  Olivier PLATHEY                                                     *
8
*******************************************************************************/
9
10
if ( ! class_exists('FPDF'))
11
{
12
define('FPDF_VERSION', '1.7');
13
14
class FPDF
15
{
16
var $page; // current page number
17
var $n; // current object number
18
var $offsets; // array of object offsets
19
var $buffer; // buffer holding in-memory PDF
20
var $pages; // array containing pages
21
var $state; // current document state
22
var $compress; // compression flag
23
var $k; // scale factor (number of points in user unit)
24
var $DefOrientation; // default orientation
25
var $CurOrientation; // current orientation
26
var $StdPageSizes; // standard page sizes
27
var $DefPageSize; // default page size
28
var $CurPageSize; // current page size
29
var $PageSizes; // used for pages with non default sizes or orientations
30
var $wPt, $hPt; // dimensions of current page in points
31
var $w, $h; // dimensions of current page in user unit
32
var $lMargin; // left margin
33
var $tMargin; // top margin
34
var $rMargin; // right margin
35
var $bMargin; // page break margin
36
var $cMargin; // cell margin
37
var $x, $y; // current position in user unit
38
var $lasth; // height of last printed cell
39
var $LineWidth; // line width in user unit
40
var $fontpath; // path containing fonts
41
var $CoreFonts; // array of core font names
42
var $fonts; // array of used fonts
43
var $FontFiles; // array of font files
44
var $diffs; // array of encoding differences
45
var $FontFamily; // current font family
46
var $FontStyle; // current font style
47
var $underline; // underlining flag
48
var $CurrentFont; // current font info
49
var $FontSizePt; // current font size in points
50
var $FontSize; // current font size in user unit
51
var $DrawColor; // commands for drawing color
52
var $FillColor; // commands for filling color
53
var $TextColor; // commands for text color
54
var $ColorFlag; // indicates whether fill and text colors are different
55
var $ws; // word spacing
56
var $images; // array of used images
57
var $PageLinks; // array of links in pages
58
var $links; // array of internal links
59
var $AutoPageBreak; // automatic page breaking
60
var $PageBreakTrigger; // threshold used to trigger page breaks
61
var $InHeader; // flag set when processing header
62
var $InFooter; // flag set when processing footer
63
var $ZoomMode; // zoom display mode
64
var $LayoutMode; // layout display mode
65
var $title; // title
66
var $subject; // subject
67
var $author; // author
68
var $keywords; // keywords
69
var $creator; // creator
70
var $AliasNbPages; // alias for total number of pages
71
var $PDFVersion; // PDF version number
72
73
/*******************************************************************************
74
*                                                                              *
75
*                               Public methods                                 *
76
*                                                                              *
77
*******************************************************************************/
78
function FPDF($props = array())
79
{
80
	 if(count($props) == 3)
81
	 {
82
		 list($orientation,$unit,$format) = $props;
83
		 $this->initialize($orientation,$unit,$format);
84
	 }	
85
}
86
87
function initialize($orientation='P',$unit='mm',$size='A4')
88
{
89
	// Some checks
90
	$this->_dochecks();
91
	// Initialization of properties
92
	$this->page = 0;
93
	$this->n = 2;
94
	$this->buffer = '';
95
	$this->pages = array();
96
	$this->PageSizes = array();
97
	$this->state = 0;
98
	$this->fonts = array();
99
	$this->FontFiles = array();
100
	$this->diffs = array();
101
	$this->images = array();
102
	$this->links = array();
103
	$this->InHeader = false;
104
	$this->InFooter = false;
105
	$this->lasth = 0;
106
	$this->FontFamily = '';
107
	$this->FontStyle = '';
108
	$this->FontSizePt = 12;
109
	$this->underline = false;
110
	$this->DrawColor = '0 G';
111
	$this->FillColor = '0 g';
112
	$this->TextColor = '0 g';
113
	$this->ColorFlag = false;
114
	$this->ws = 0;
115
	// Font path
116
	if (defined('FPDF_FONTPATH'))
117
	{
118
		$this->fontpath = FPDF_FONTPATH;
119
		if (substr($this->fontpath, -1) != '/' && substr($this->fontpath, -1) != '\\')
120
			$this->fontpath .= '/';
121
	}
122
	elseif (is_dir(dirname(__FILE__).'/font'))
123
		$this->fontpath = dirname(__FILE__).'/font/';
124
	else
125
		$this->fontpath = '';	
126
	// Core fonts
127
	$this->CoreFonts = array('courier', 'helvetica', 'times', 'symbol', 'zapfdingbats');
128
	// Scale factor
129
	if ($unit == 'pt')
130
		$this->k = 1;
131
	elseif ($unit == 'mm')
132
		$this->k = 72 / 25.4;
133
	elseif ($unit == 'cm')
134
		$this->k = 72 / 2.54;
135
	elseif ($unit == 'in')
136
		$this->k = 72;
137
	else
138
		$this->Error('Incorrect unit: '.$unit);
139
	// Page sizes
140
	$this->StdPageSizes = array('a3'=>array(841.89, 1190.55), 'a4'=>array(595.28, 841.89), 'a5'=>array(420.94, 595.28),
141
		'letter'=>array(612, 792), 'legal'=>array(612, 1008));
142
	$size = $this->_getpagesize($size);
143
	$this->DefPageSize = $size;
144
	$this->CurPageSize = $size;
145
	// Page orientation
146
	$orientation = strtolower($orientation);
147
	if ($orientation == 'p' || $orientation == 'portrait')
148
	{
149
		$this->DefOrientation = 'P';
150
		$this->w = $size[0];
151
		$this->h = $size[1];
152
	}
153
	elseif ($orientation == 'l' || $orientation == 'landscape')
154
	{
155
		$this->DefOrientation = 'L';
156
		$this->w = $size[1];
157
		$this->h = $size[0];
158
	}
159
	else
160
		$this->Error('Incorrect orientation: '.$orientation);
161
	$this->CurOrientation = $this->DefOrientation;
162
	$this->wPt = $this->w * $this->k;
163
	$this->hPt = $this->h * $this->k;
164
	// Page margins (1 cm)
165
	$margin = 28.35 / $this->k;
166
	$this->SetMargins($margin, $margin);
167
	// Interior cell margin (1 mm)
168
	$this->cMargin = $margin / 10;
169
	// Line width (0.2 mm)
170
	$this->LineWidth = .567 / $this->k;
171
	// Automatic page break
172
	$this->SetAutoPageBreak(true, 2 * $margin);
173
	// Default display mode
174
	$this->SetDisplayMode('default');
175
	// Enable compression
176
	$this->SetCompression(true);
177
	// Set default PDF version number
178
	$this->PDFVersion = '1.3';
179
}
180
181
/**
182
 * @param double $left
183
 * @param double $top
184
 */
185
function SetMargins($left, $top, $right=null)
186
{
187
	// Set left, top and right margins
188
	$this->lMargin = $left;
189
	$this->tMargin = $top;
190
	if($right===null) {
191
			$right = $left;
192
	}
193
	$this->rMargin = $right;
194
}
195
196
function SetLeftMargin($margin)
197
{
198
	// Set left margin
199
	$this->lMargin = $margin;
200
	if ($this->page > 0 && $this->x < $margin)
201
		$this->x = $margin;
202
}
203
204
function SetTopMargin($margin)
205
{
206
	// Set top margin
207
	$this->tMargin = $margin;
208
}
209
210
function SetRightMargin($margin)
211
{
212
	// Set right margin
213
	$this->rMargin = $margin;
214
}
215
216
/**
217
 * @param boolean $auto
218
 */
219
function SetAutoPageBreak($auto, $margin=0)
220
{
221
	// Set auto page break mode and triggering margin
222
	$this->AutoPageBreak = $auto;
223
	$this->bMargin = $margin;
224
	$this->PageBreakTrigger = $this->h-$margin;
225
}
226
227
/**
228
 * @param string $zoom
229
 */
230
function SetDisplayMode($zoom, $layout='default')
231
{
232
	// Set display mode in viewer
233
	if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom))
234
		$this->ZoomMode = $zoom;
235
	else
236
		$this->Error('Incorrect zoom display mode: '.$zoom);
237
	if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default')
238
		$this->LayoutMode = $layout;
239
	else
240
		$this->Error('Incorrect layout display mode: '.$layout);
241
}
242
243
/**
244
 * @param boolean $compress
245
 */
246
function SetCompression($compress)
247
{
248
	// Set page compression
249
	if (function_exists('gzcompress'))
250
		$this->compress = $compress;
251
	else
252
		$this->compress = false;
253
}
254
255
function SetTitle($title, $isUTF8 = false)
256
{
257
	// Title of document
258
	if ($isUTF8)
259
		$title = $this->_UTF8toUTF16($title);
260
	$this->title = $title;
261
}
262
263
function SetSubject($subject, $isUTF8 = false)
264
{
265
	// Subject of document
266
	if ($isUTF8)
267
		$subject = $this->_UTF8toUTF16($subject);
268
	$this->subject = $subject;
269
}
270
271
function SetAuthor($author, $isUTF8 = false)
272
{
273
	// Author of document
274
	if ($isUTF8)
275
		$author = $this->_UTF8toUTF16($author);
276
	$this->author = $author;
277
}
278
279
function SetKeywords($keywords, $isUTF8 = false)
280
{
281
	// Keywords of document
282
	if ($isUTF8)
283
		$keywords = $this->_UTF8toUTF16($keywords);
284
	$this->keywords = $keywords;
285
}
286
287
function SetCreator($creator, $isUTF8 = false)
288
{
289
	// Creator of document
290
	if ($isUTF8)
291
		$creator = $this->_UTF8toUTF16($creator);
292
	$this->creator = $creator;
293
}
294
295
function AliasNbPages($alias = '{nb}')
296
{
297
	// Define an alias for total number of pages
298
	$this->AliasNbPages = $alias;
299
}
300
301
function Error($msg)
302
{
303
	// Fatal error
304
	die('<b>FPDF error:</b> '.$msg);
305
}
306
307
function Open()
308
{
309
	// Begin document
310
	$this->state = 1;
311
}
312
313
function Close()
314
{
315
	// Terminate document
316
	if ($this->state == 3)
317
		return;
318
	if ($this->page == 0)
319
		$this->AddPage();
320
	// Page footer
321
	$this->InFooter = true;
322
	$this->Footer();
323
	$this->InFooter = false;
324
	// Close page
325
	$this->_endpage();
326
	// Close document
327
	$this->_enddoc();
328
}
329
330
function AddPage($orientation = '', $size = '')
331
{
332
	// Start a new page
333
	if ($this->state == 0)
334
		$this->Open();
335
	$family = $this->FontFamily;
336
	$style = $this->FontStyle.($this->underline ? 'U' : '');
337
	$fontsize = $this->FontSizePt;
338
	$lw = $this->LineWidth;
339
	$dc = $this->DrawColor;
340
	$fc = $this->FillColor;
341
	$tc = $this->TextColor;
342
	$cf = $this->ColorFlag;
343
	if ($this->page > 0)
344
	{
345
		// Page footer
346
		$this->InFooter = true;
347
		$this->Footer();
348
		$this->InFooter = false;
349
		// Close page
350
		$this->_endpage();
351
	}
352
	// Start new page
353
	$this->_beginpage($orientation, $size);
354
	// Set line cap style to square
355
	$this->_out('2 J');
356
	// Set line width
357
	$this->LineWidth = $lw;
358
	$this->_out(sprintf('%.2F w', $lw * $this->k));
359
	// Set font
360
	if ($family)
361
		$this->SetFont($family, $style, $fontsize);
362
	// Set colors
363
	$this->DrawColor = $dc;
364
	if ($dc != '0 G')
365
		$this->_out($dc);
366
	$this->FillColor = $fc;
367
	if ($fc != '0 g')
368
		$this->_out($fc);
369
	$this->TextColor = $tc;
370
	$this->ColorFlag = $cf;
371
	// Page header
372
	$this->InHeader = true;
373
	$this->Header();
374
	$this->InHeader = false;
375
	// Restore line width
376
	if ($this->LineWidth != $lw)
377
	{
378
		$this->LineWidth = $lw;
379
		$this->_out(sprintf('%.2F w', $lw * $this->k));
380
	}
381
	// Restore font
382
	if ($family)
383
		$this->SetFont($family, $style, $fontsize);
384
	// Restore colors
385
	if ($this->DrawColor != $dc)
386
	{
387
		$this->DrawColor = $dc;
388
		$this->_out($dc);
389
	}
390
	if ($this->FillColor != $fc)
391
	{
392
		$this->FillColor = $fc;
393
		$this->_out($fc);
394
	}
395
	$this->TextColor = $tc;
396
	$this->ColorFlag = $cf;
397
}
398
399
function Header()
400
{
401
	// To be implemented in your own inherited class
402
}
403
404
function Footer()
405
{
406
	// To be implemented in your own inherited class
407
}
408
409
function PageNo()
410
{
411
	// Get current page number
412
	return $this->page;
413
}
414
415 View Code Duplication
function SetDrawColor($r, $g=null, $b=null)
416
{
417
	// Set color for all stroking operations
418
	if(($r==0 && $g==0 && $b==0) || $g===null)
419
		$this->DrawColor = sprintf('%.3F G',$r/255);
420
	else
421
		$this->DrawColor = sprintf('%.3F %.3F %.3F RG',$r/255,$g/255,$b/255);
422
	if($this->page>0)
423
		$this->_out($this->DrawColor);
424
}
425
426
/**
427
 * @param integer $r
428
 * @param integer $g
429
 * @param integer $b
430
 */
431
function SetFillColor($r, $g=null, $b=null)
432
{
433
	// Set color for all filling operations
434
	if(($r==0 && $g==0 && $b==0) || $g===null)
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $g of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
Bug introduced by
It seems like you are loosely comparing $b of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
435
		$this->FillColor = sprintf('%.3F g',$r/255);
436
	else
437
		$this->FillColor = sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
438
	$this->ColorFlag = ($this->FillColor!=$this->TextColor);
439
	if($this->page>0)
440
		$this->_out($this->FillColor);
441
}
442
443 View Code Duplication
function SetTextColor($r, $g=null, $b=null)
444
{
445
	// Set color for text
446
	if(($r==0 && $g==0 && $b==0) || $g===null)
447
		$this->TextColor = sprintf('%.3F g',$r/255);
448
	else
449
		$this->TextColor = sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
450
	$this->ColorFlag = ($this->FillColor!=$this->TextColor);
451
}
452
453
function GetStringWidth($s)
454
{
455
	// Get width of a string in the current font
456
	$s = (string)$s;
457
	$cw = &$this->CurrentFont['cw'];
458
	$w = 0;
459
	$l = strlen($s);
460
	for($i=0;$i<$l;$i++) {
461
			$w += $cw[$s[$i]];
462
	}
463
	return $w*$this->FontSize/1000;
464
}
465
466
function SetLineWidth($width)
467
{
468
	// Set line width
469
	$this->LineWidth = $width;
470
	if($this->page>0) {
471
			$this->_out(sprintf('%.2F w',$width*$this->k));
472
	}
473
	}
474
475
/**
476
 * @param integer $x1
477
 * @param integer $x2
478
 */
479
function Line($x1, $y1, $x2, $y2)
480
{
481
	// Draw a line
482
	$this->_out(sprintf('%.2F %.2F m %.2F %.2F l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k));
483
}
484
485
function Rect($x, $y, $w, $h, $style='')
486
{
487
	// Draw a rectangle
488 View Code Duplication
	if($style=='F') {
489
			$op = 'f';
490
	} elseif($style=='FD' || $style=='DF') {
491
			$op = 'B';
492
	} else {
493
			$op = 'S';
494
	}
495
	$this->_out(sprintf('%.2F %.2F %.2F %.2F re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
496
}
497
498
/**
499
 * @param string $family
500
 */
501
function AddFont($family, $style='', $file='')
502
{
503
	// Add a TrueType, OpenType or Type1 font
504
	$family = strtolower($family);
505
	if($file=='') {
506
			$file = str_replace(' ','',$family).strtolower($style).'.php';
507
	}
508
	$style = strtoupper($style);
509
	if($style=='IB') {
510
			$style = 'BI';
511
	}
512
	$fontkey = $family.$style;
513
	if(isset($this->fonts[$fontkey])) {
514
			return;
515
	}
516
	$info = $this->_loadfont($file);
517
	$info['i'] = count($this->fonts)+1;
518
	if(!empty($info['diff']))
519
	{
520
		// Search existing encodings
521
		$n = array_search($info['diff'],$this->diffs);
522
		if(!$n)
523
		{
524
			$n = count($this->diffs)+1;
525
			$this->diffs[$n] = $info['diff'];
526
		}
527
		$info['diffn'] = $n;
528
	}
529
	if(!empty($info['file']))
530
	{
531
		// Embedded font
532
		if($info['type']=='TrueType') {
533
					$this->FontFiles[$info['file']] = array('length1'=>$info['originalsize']);
534
		} else {
535
					$this->FontFiles[$info['file']] = array('length1'=>$info['size1'], 'length2'=>$info['size2']);
536
		}
537
	}
538
	$this->fonts[$fontkey] = $info;
539
}
540
541
/**
542
 * @param string $family
543
 */
544
function SetFont($family, $style='', $size=0)
545
{
546
	// Select a font; size given in points
547
	if($family=='') {
548
			$family = $this->FontFamily;
549
	} else {
550
			$family = strtolower($family);
551
	}
552
	$style = strtoupper($style);
553
	if(strpos($style,'U')!==false)
554
	{
555
		$this->underline = true;
556
		$style = str_replace('U','',$style);
557
	} else {
558
			$this->underline = false;
559
	}
560
	if($style=='IB') {
561
			$style = 'BI';
562
	}
563
	if($size==0) {
564
			$size = $this->FontSizePt;
565
	}
566
	// Test if font is already selected
567
	if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size) {
568
			return;
569
	}
570
	// Test if font is already loaded
571
	$fontkey = $family.$style;
572
	if(!isset($this->fonts[$fontkey]))
573
	{
574
		// Test if one of the core fonts
575
		if($family=='arial') {
576
					$family = 'helvetica';
577
		}
578
		if(in_array($family,$this->CoreFonts))
579
		{
580
			if($family=='symbol' || $family=='zapfdingbats') {
581
							$style = '';
582
			}
583
			$fontkey = $family.$style;
584
			if(!isset($this->fonts[$fontkey])) {
585
							$this->AddFont($family,$style);
586
			}
587
		} else {
588
					$this->Error('Undefined font: '.$family.' '.$style);
589
		}
590
	}
591
	// Select it
592
	$this->FontFamily = $family;
593
	$this->FontStyle = $style;
594
	$this->FontSizePt = $size;
595
	$this->FontSize = $size / $this->k;
596
	$this->CurrentFont = &$this->fonts[$fontkey];
597 View Code Duplication
	if ($this->page > 0)
598
		$this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
599
}
600
601
function SetFontSize($size)
602
{
603
	// Set font size in points
604
	if ($this->FontSizePt == $size)
605
		return;
606
	$this->FontSizePt = $size;
607
	$this->FontSize = $size / $this->k;
608 View Code Duplication
	if ($this->page > 0)
609
		$this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
610
}
611
612
function AddLink()
613
{
614
	// Create a new internal link
615
	$n = count($this->links) + 1;
616
	$this->links[$n] = array(0, 0);
617
	return $n;
618
}
619
620
function SetLink($link, $y = 0, $page = -1)
621
{
622
	// Set destination of internal link
623
	if ($y == -1)
624
		$y = $this->y;
625
	if ($page == -1)
626
		$page = $this->page;
627
	$this->links[$link] = array($page, $y);
628
}
629
630
/**
631
 * @param double $y
632
 * @param string $link
633
 */
634
function Link($x, $y, $w, $h, $link)
635
{
636
	// Put a link on the page
637
	$this->PageLinks[$this->page][] = array($x * $this->k, $this->hPt - $y * $this->k, $w * $this->k, $h * $this->k, $link);
638
}
639
640
function Text($x, $y, $txt)
641
{
642
	// Output a string
643
	$s = sprintf('BT %.2F %.2F Td (%s) Tj ET', $x * $this->k, ($this->h - $y) * $this->k, $this->_escape($txt));
644
	if ($this->underline && $txt != '')
645
		$s .= ' '.$this->_dounderline($x, $y, $txt);
646
	if ($this->ColorFlag)
647
		$s = 'q '.$this->TextColor.' '.$s.' Q';
648
	$this->_out($s);
649
}
650
651
function AcceptPageBreak()
652
{
653
	// Accept automatic page break or not
654
	return $this->AutoPageBreak;
655
}
656
657
function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='')
658
{
659
	// Output a cell
660
	$k = $this->k;
661
	if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
662
	{
663
		// Automatic page break
664
		$x = $this->x;
665
		$ws = $this->ws;
666
		if($ws>0)
667
		{
668
			$this->ws = 0;
669
			$this->_out('0 Tw');
670
		}
671
		$this->AddPage($this->CurOrientation,$this->CurPageSize);
672
		$this->x = $x;
673
		if($ws>0)
674
		{
675
			$this->ws = $ws;
676
			$this->_out(sprintf('%.3F Tw',$ws*$k));
677
		}
678
	}
679
	if($w==0)
680
		$w = $this->w-$this->rMargin-$this->x;
681
	$s = '';
682
	if($fill || $border==1)
683
	{
684
		if($fill)
685
			$op = ($border==1) ? 'B' : 'f';
686
		else
687
			$op = 'S';
688
		$s = sprintf('%.2F %.2F %.2F %.2F re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
689
	}
690
	if(is_string($border))
691
	{
692
		$x = $this->x;
693
		$y = $this->y;
694 View Code Duplication
		if(strpos($border,'L')!==false)
695
			$s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
696 View Code Duplication
		if(strpos($border,'T')!==false)
697
			$s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
698 View Code Duplication
		if(strpos($border,'R')!==false)
699
			$s .= sprintf('%.2F %.2F m %.2F %.2F l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
700 View Code Duplication
		if(strpos($border,'B')!==false)
701
			$s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
702
	}
703
	if($txt!=='')
704
	{
705
		if($align=='R')
706
			$dx = $w-$this->cMargin-$this->GetStringWidth($txt);
707
		elseif($align=='C')
708
			$dx = ($w-$this->GetStringWidth($txt))/2;
709
		else
710
			$dx = $this->cMargin;
711
		if($this->ColorFlag)
712
			$s .= 'q '.$this->TextColor.' ';
713
		$txt2 = str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
714
		$s .= sprintf('BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2);
715
		if($this->underline)
716
			$s .= ' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
717
		if($this->ColorFlag)
718
			$s .= ' Q';
719
		if($link)
720
			$this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
721
	}
722
	if($s)
723
		$this->_out($s);
724
	$this->lasth = $h;
725
	if($ln>0)
726
	{
727
		// Go to next line
728
		$this->y += $h;
729
		if($ln==1)
730
			$this->x = $this->lMargin;
731
	}
732
	else
733
		$this->x += $w;
734
}
735
736
/**
737
 * @param integer $w
738
 * @param integer $h
739
 */
740
function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false)
741
{
742
	// Output text with automatic or explicit line breaks
743
	$cw = &$this->CurrentFont['cw'];
744
	if($w==0)
745
		$w = $this->w-$this->rMargin-$this->x;
746
	$wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
747
	$s = str_replace("\r",'',$txt);
748
	$nb = strlen($s);
749
	if($nb>0 && $s[$nb-1]=="\n")
750
		$nb--;
751
	$b = 0;
752
	if($border)
753
	{
754
		if($border==1)
755
		{
756
			$border = 'LTRB';
757
			$b = 'LRT';
758
			$b2 = 'LR';
759
		}
760
		else
761
		{
762
			$b2 = '';
763
			if (strpos($border, 'L') !== false)
764
				$b2 .= 'L';
765
			if (strpos($border, 'R') !== false)
766
				$b2 .= 'R';
767
			$b = (strpos($border, 'T') !== false) ? $b2.'T' : $b2;
768
		}
769
	}
770
	$sep = -1;
771
	$i = 0;
772
	$j = 0;
773
	$l = 0;
774
	$ns = 0;
775
	$nl = 1;
776
	while ($i < $nb)
777
	{
778
		// Get next character
779
		$c = $s[$i];
780
		if ($c == "\n")
781
		{
782
			// Explicit line break
783
			if ($this->ws > 0)
784
			{
785
				$this->ws = 0;
786
				$this->_out('0 Tw');
787
			}
788
			$this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
789
			$i++;
790
			$sep = -1;
791
			$j = $i;
792
			$l = 0;
793
			$ns = 0;
794
			$nl++;
795
			if ($border && $nl == 2)
796
				$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...
797
			continue;
798
		}
799
		if ($c == ' ')
800
		{
801
			$sep = $i;
802
			$ls = $l;
803
			$ns++;
804
		}
805
		$l += $cw[$c];
806
		if ($l > $wmax)
807
		{
808
			// Automatic line break
809
			if ($sep == -1)
810
			{
811
				if ($i == $j)
812
					$i++;
813
				if ($this->ws > 0)
814
				{
815
					$this->ws = 0;
816
					$this->_out('0 Tw');
817
				}
818
				$this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
819
			}
820
			else
821
			{
822
				if ($align == 'J')
823
				{
824
					$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...
825
					$this->_out(sprintf('%.3F Tw', $this->ws * $this->k));
826
				}
827
				$this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill);
828
				$i = $sep + 1;
829
			}
830
			$sep = -1;
831
			$j = $i;
832
			$l = 0;
833
			$ns = 0;
834
			$nl++;
835
			if ($border && $nl == 2)
836
				$b = $b2;
837
		}
838
		else
839
			$i++;
840
	}
841
	// Last chunk
842
	if ($this->ws > 0)
843
	{
844
		$this->ws = 0;
845
		$this->_out('0 Tw');
846
	}
847
	if ($border && strpos($border, 'B') !== false)
848
		$b .= 'B';
849
	$this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
850
	$this->x = $this->lMargin;
851
}
852
853
function Write($h, $txt, $link = '')
854
{
855
	// Output text in flowing mode
856
	$cw = &$this->CurrentFont['cw'];
857
	$w = $this->w - $this->rMargin - $this->x;
858
	$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
859
	$s = str_replace("\r", '', $txt);
860
	$nb = strlen($s);
861
	$sep = -1;
862
	$i = 0;
863
	$j = 0;
864
	$l = 0;
865
	$nl = 1;
866
	while ($i < $nb)
867
	{
868
		// Get next character
869
		$c = $s[$i];
870
		if ($c == "\n")
871
		{
872
			// Explicit line break
873
			$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...
874
			$i++;
875
			$sep = -1;
876
			$j = $i;
877
			$l = 0;
878 View Code Duplication
			if ($nl == 1)
879
			{
880
				$this->x = $this->lMargin;
881
				$w = $this->w - $this->rMargin - $this->x;
882
				$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
883
			}
884
			$nl++;
885
			continue;
886
		}
887
		if ($c == ' ')
888
			$sep = $i;
889
		$l += $cw[$c];
890
		if ($l > $wmax)
891
		{
892
			// Automatic line break
893
			if ($sep == -1)
894
			{
895
				if ($this->x > $this->lMargin)
896
				{
897
					// Move to next line
898
					$this->x = $this->lMargin;
899
					$this->y += $h;
900
					$w = $this->w - $this->rMargin - $this->x;
901
					$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
902
					$i++;
903
					$nl++;
904
					continue;
905
				}
906
				if ($i == $j)
907
					$i++;
908
				$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...
909
			}
910
			else
911
			{
912
				$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...
913
				$i = $sep + 1;
914
			}
915
			$sep = -1;
916
			$j = $i;
917
			$l = 0;
918 View Code Duplication
			if ($nl == 1)
919
			{
920
				$this->x = $this->lMargin;
921
				$w = $this->w - $this->rMargin - $this->x;
922
				$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
923
			}
924
			$nl++;
925
		}
926
		else
927
			$i++;
928
	}
929
	// Last chunk
930
	if ($i != $j)
931
		$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...
932
}
933
934
function Ln($h = null)
935
{
936
	// Line feed; default value is last cell height
937
	$this->x = $this->lMargin;
938
	if ($h === null)
939
		$this->y += $this->lasth;
940
	else
941
		$this->y += $h;
942
}
943
944
function Image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '')
945
{
946
	// Put an image on the page
947
	if ( ! isset($this->images[$file]))
948
	{
949
		// First use of this image, get info
950
		if ($type == '')
951
		{
952
			$pos = strrpos($file, '.');
953
			if ( ! $pos)
954
				$this->Error('Image file has no extension and no type was specified: '.$file);
955
			$type = substr($file, $pos + 1);
956
		}
957
		$type = strtolower($type);
958
		if ($type == 'jpeg')
959
			$type = 'jpg';
960
		$mtd = '_parse'.$type;
961
		if ( ! method_exists($this, $mtd))
962
			$this->Error('Unsupported image type: '.$type);
963
		$info = $this->$mtd($file);
964
		$info['i'] = count($this->images) + 1;
965
		$this->images[$file] = $info;
966
	}
967
	else
968
		$info = $this->images[$file];
969
970
	// Automatic width and height calculation if needed
971
	if ($w == 0 && $h == 0)
972
	{
973
		// Put image at 96 dpi
974
		$w = -96;
975
		$h = -96;
976
	}
977
	if ($w < 0)
978
		$w = -$info['w'] * 72 / $w / $this->k;
979
	if ($h < 0)
980
		$h = -$info['h'] * 72 / $h / $this->k;
981
	if ($w == 0)
982
		$w = $h * $info['w'] / $info['h'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
983
	if ($h == 0)
984
		$h = $w * $info['h'] / $info['w'];
985
986
	// Flowing mode
987
	if ($y === null)
988
	{
989
		if ($this->y + $h > $this->PageBreakTrigger && ! $this->InHeader && ! $this->InFooter && $this->AcceptPageBreak())
990
		{
991
			// Automatic page break
992
			$x2 = $this->x;
993
			$this->AddPage($this->CurOrientation, $this->CurPageSize);
994
			$this->x = $x2;
995
		}
996
		$y = $this->y;
997
		$this->y += $h;
998
	}
999
1000
	if ($x === null)
1001
		$x = $this->x;
1002
	$this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q', $w * $this->k, $h * $this->k, $x * $this->k, ($this->h - ($y + $h)) * $this->k, $info['i']));
1003
	if ($link)
1004
		$this->Link($x, $y, $w, $h, $link);
1005
}
1006
1007
function GetX()
1008
{
1009
	// Get x position
1010
	return $this->x;
1011
}
1012
1013
function SetX($x)
1014
{
1015
	// Set x position
1016
	if ($x >= 0)
1017
		$this->x = $x;
1018
	else
1019
		$this->x = $this->w + $x;
1020
}
1021
1022
function GetY()
1023
{
1024
	// Get y position
1025
	return $this->y;
1026
}
1027
1028
function SetY($y)
1029
{
1030
	// Set y position and reset x
1031
	$this->x = $this->lMargin;
1032
	if ($y >= 0)
1033
		$this->y = $y;
1034
	else
1035
		$this->y = $this->h + $y;
1036
}
1037
1038
/**
1039
 * @param integer $x
1040
 */
1041
function SetXY($x, $y)
1042
{
1043
	// Set x and y positions
1044
	$this->SetY($y);
1045
	$this->SetX($x);
1046
}
1047
1048
function Output($name = '', $dest = '')
1049
{
1050
	// Output PDF to some destination
1051
	if ($this->state < 3)
1052
		$this->Close();
1053
	$dest = strtoupper($dest);
1054
	if ($dest == '')
1055
	{
1056
		if ($name == '')
1057
		{
1058
			$name = 'doc.pdf';
1059
			$dest = 'I';
1060
		} else {
1061
					$dest = 'F';
1062
		}
1063
	}
1064
	switch ($dest)
1065
	{
1066 View Code Duplication
		case 'I':
1067
			// Send to standard output
1068
			$this->_checkoutput();
1069
			if (PHP_SAPI != 'cli')
1070
			{
1071
				// We send to a browser
1072
				header('Content-Type: application/pdf');
1073
				header('Content-Disposition: inline; filename="'.$name.'"');
1074
				header('Cache-Control: private, max-age=0, must-revalidate');
1075
				header('Pragma: public');
1076
			}
1077
			echo $this->buffer;
1078
			break;
1079 View Code Duplication
		case 'D':
1080
			// Download file
1081
			$this->_checkoutput();
1082
			header('Content-Type: application/pdf');
1083
// 			header('Content-Type: application/x-download');
1084
			header('Content-Disposition: attachment; filename="'.$name.'"');
1085
			header('Cache-Control: private, max-age=0, must-revalidate');
1086
			header('Pragma: public');
1087
			echo $this->buffer;
1088
			break;
1089
		case 'F':
1090
			// Save to local file
1091
			$f = fopen($name, 'wb');
1092
			if ( ! $f)
1093
				$this->Error('Unable to create output file: '.$name);
1094
			fwrite($f, $this->buffer, strlen($this->buffer));
1095
			fclose($f);
1096
			break;
1097
		case 'S':
1098
			// Return as a string
1099
			return $this->buffer;
1100
		default:
1101
			$this->Error('Incorrect output destination: '.$dest);
1102
	}
1103
	return '';
1104
}
1105
1106
/*******************************************************************************
1107
*                                                                              *
1108
*                              Protected methods                               *
1109
*                                                                              *
1110
*******************************************************************************/
1111
function _dochecks()
1112
{
1113
	// Check availability of %F
1114
	if (sprintf('%.1F', 1.0) != '1.0')
1115
		$this->Error('This version of PHP is not supported');
1116
	// Check mbstring overloading
1117
	if (ini_get('mbstring.func_overload') & 2)
1118
		$this->Error('mbstring overloading must be disabled');
1119
	// Ensure runtime magic quotes are disabled
1120
	if (get_magic_quotes_runtime())
1121
		@set_magic_quotes_runtime(0);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1122
}
1123
1124
function _checkoutput()
1125
{
1126
	if (PHP_SAPI != 'cli')
1127
	{
1128
		if (headers_sent($file, $line))
1129
			$this->Error("Some data has already been output, can't send PDF file (output started at $file:$line)");
1130
	}
1131
	if (ob_get_length())
1132
	{
1133
		// The output buffer is not empty
1134
		if (preg_match('/^(\xEF\xBB\xBF)?\s*$/', ob_get_contents()))
1135
		{
1136
			// It contains only a UTF-8 BOM and/or whitespace, let's clean it
1137
			ob_clean();
1138
		} else {
1139
					$this->Error("Some data has already been output, can't send PDF file");
1140
		}
1141
	}
1142
}
1143
1144
function _getpagesize($size)
1145
{
1146
	if (is_string($size))
1147
	{
1148
		$size = strtolower($size);
1149
		if ( ! isset($this->StdPageSizes[$size]))
1150
			$this->Error('Unknown page size: '.$size);
1151
		$a = $this->StdPageSizes[$size];
1152
		return array($a[0] / $this->k, $a[1] / $this->k);
1153
	}
1154
	else
1155
	{
1156
		if ($size[0] > $size[1])
1157
			return array($size[1], $size[0]);
1158
		else
1159
			return $size;
1160
	}
1161
}
1162
1163
/**
1164
 * @param string $orientation
1165
 * @param string $size
1166
 */
1167
function _beginpage($orientation, $size)
1168
{
1169
	$this->page++;
1170
	$this->pages[$this->page] = '';
1171
	$this->state = 2;
1172
	$this->x = $this->lMargin;
1173
	$this->y = $this->tMargin;
1174
	$this->FontFamily = '';
1175
	// Check page size and orientation
1176 View Code Duplication
	if ($orientation == '')
1177
		$orientation = $this->DefOrientation;
1178
	else
1179
		$orientation = strtoupper($orientation[0]);
1180
	if ($size == '')
1181
		$size = $this->DefPageSize;
1182
	else
1183
		$size = $this->_getpagesize($size);
1184 View Code Duplication
	if ($orientation != $this->CurOrientation || $size[0] != $this->CurPageSize[0] || $size[1] != $this->CurPageSize[1])
1185
	{
1186
		// New size or orientation
1187
		if ($orientation == 'P')
1188
		{
1189
			$this->w = $size[0];
1190
			$this->h = $size[1];
1191
		} else
1192
		{
1193
			$this->w = $size[1];
1194
			$this->h = $size[0];
1195
		}
1196
		$this->wPt = $this->w * $this->k;
1197
		$this->hPt = $this->h * $this->k;
1198
		$this->PageBreakTrigger = $this->h - $this->bMargin;
1199
		$this->CurOrientation = $orientation;
1200
		$this->CurPageSize = $size;
1201
	}
1202 View Code Duplication
	if ($orientation != $this->DefOrientation || $size[0] != $this->DefPageSize[0] || $size[1] != $this->DefPageSize[1])
1203
		$this->PageSizes[$this->page] = array($this->wPt, $this->hPt);
1204
}
1205
1206
function _endpage()
1207
{
1208
	$this->state = 1;
1209
}
1210
1211
/**
1212
 * @param string $font
1213
 */
1214
function _loadfont($font)
1215
{
1216
	// Load a font definition file from the font directory
1217
	include($this->fontpath.$font);
1218
	$a = get_defined_vars();
1219
	if ( ! isset($a['name']))
1220
		$this->Error('Could not include font definition file');
1221
	return $a;
1222
}
1223
1224
function _escape($s)
1225
{
1226
	// Escape special characters in strings
1227
	$s = str_replace('\\', '\\\\', $s);
1228
	$s = str_replace('(', '\\(', $s);
1229
	$s = str_replace(')', '\\)', $s);
1230
	$s = str_replace("\r", '\\r', $s);
1231
	return $s;
1232
}
1233
1234
function _textstring($s)
1235
{
1236
	// Format a text string
1237
	return '('.$this->_escape($s).')';
1238
}
1239
1240
function _UTF8toUTF16($s)
1241
{
1242
	// Convert UTF-8 to UTF-16BE with BOM
1243
	$res = "\xFE\xFF";
1244
	$nb = strlen($s);
1245
	$i = 0;
1246
	while ($i < $nb)
1247
	{
1248
		$c1 = ord($s[$i++]);
1249
		if ($c1 >= 224)
1250
		{
1251
			// 3-byte character
1252
			$c2 = ord($s[$i++]);
1253
			$c3 = ord($s[$i++]);
1254
			$res .= chr((($c1 & 0x0F) << 4) + (($c2 & 0x3C) >> 2));
1255
			$res .= chr((($c2 & 0x03) << 6) + ($c3 & 0x3F));
1256
		}
1257
		elseif ($c1 >= 192)
1258
		{
1259
			// 2-byte character
1260
			$c2 = ord($s[$i++]);
1261
			$res .= chr(($c1 & 0x1C) >> 2);
1262
			$res .= chr((($c1 & 0x03) << 6) + ($c2 & 0x3F));
1263
		}
1264
		else
1265
		{
1266
			// Single-byte character
1267
			$res .= "\0".chr($c1);
1268
		}
1269
	}
1270
	return $res;
1271
}
1272
1273
function _dounderline($x, $y, $txt)
1274
{
1275
	// Underline text
1276
	$up = $this->CurrentFont['up'];
1277
	$ut = $this->CurrentFont['ut'];
1278
	$w = $this->GetStringWidth($txt) + $this->ws * substr_count($txt, ' ');
1279
	return sprintf('%.2F %.2F %.2F %.2F re f', $x * $this->k, ($this->h - ($y - $up / 1000 * $this->FontSize)) * $this->k, $w * $this->k, -$ut / 1000 * $this->FontSizePt);
1280
}
1281
1282
function _parsejpg($file)
1283
{
1284
	// Extract info from a JPEG file
1285
	$a = getimagesize($file);
1286
	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...
1287
		$this->Error('Missing or incorrect image file: '.$file);
1288
	if ($a[2] != 2)
1289
		$this->Error('Not a JPEG file: '.$file);
1290
	if ( ! isset($a['channels']) || $a['channels'] == 3)
1291
		$colspace = 'DeviceRGB';
1292
	elseif ($a['channels'] == 4)
1293
		$colspace = 'DeviceCMYK';
1294
	else
1295
		$colspace = 'DeviceGray';
1296
	$bpc = isset($a['bits']) ? $a['bits'] : 8;
1297
	$data = file_get_contents($file);
1298
	return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data);
1299
}
1300
1301
/**
1302
 * @param string $file
1303
 */
1304
function _parsepng($file)
1305
{
1306
	// Extract info from a PNG file
1307
	$f = fopen($file, 'rb');
1308
	if ( ! $f)
1309
		$this->Error('Can\'t open image file: '.$file);
1310
	$info = $this->_parsepngstream($f, $file);
1311
	fclose($f);
1312
	return $info;
1313
}
1314
1315
function _parsepngstream($f, $file)
1316
{
1317
	// Check signature
1318
	if ($this->_readstream($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
1319
		$this->Error('Not a PNG file: '.$file);
1320
1321
	// Read header chunk
1322
	$this->_readstream($f, 4);
1323
	if ($this->_readstream($f, 4) != 'IHDR')
1324
		$this->Error('Incorrect PNG file: '.$file);
1325
	$w = $this->_readint($f);
1326
	$h = $this->_readint($f);
1327
	$bpc = ord($this->_readstream($f, 1));
1328
	if ($bpc > 8)
1329
		$this->Error('16-bit depth not supported: '.$file);
1330
	$ct = ord($this->_readstream($f, 1));
1331
	if ($ct == 0 || $ct == 4)
1332
		$colspace = 'DeviceGray';
1333
	elseif ($ct == 2 || $ct == 6)
1334
		$colspace = 'DeviceRGB';
1335
	elseif ($ct == 3)
1336
		$colspace = 'Indexed';
1337
	else
1338
		$this->Error('Unknown color type: '.$file);
1339
	if (ord($this->_readstream($f, 1)) != 0)
1340
		$this->Error('Unknown compression method: '.$file);
1341
	if (ord($this->_readstream($f, 1)) != 0)
1342
		$this->Error('Unknown filter method: '.$file);
1343
	if (ord($this->_readstream($f, 1)) != 0)
1344
		$this->Error('Interlacing not supported: '.$file);
1345
	$this->_readstream($f, 4);
1346
	$dp = '/Predictor 15 /Colors '.($colspace == 'DeviceRGB' ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w;
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...
1347
1348
	// Scan chunks looking for palette, transparency and image data
1349
	$pal = '';
1350
	$trns = '';
1351
	$data = '';
1352
	do
1353
	{
1354
		$n = $this->_readint($f);
1355
		$type = $this->_readstream($f, 4);
1356
		if ($type == 'PLTE')
1357
		{
1358
			// Read palette
1359
			$pal = $this->_readstream($f, $n);
1360
			$this->_readstream($f, 4);
1361
		}
1362
		elseif ($type == 'tRNS')
1363
		{
1364
			// Read transparency info
1365
			$t = $this->_readstream($f, $n);
1366
			if ($ct == 0)
1367
				$trns = array(ord(substr($t, 1, 1)));
1368
			elseif ($ct == 2)
1369
				$trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1)));
1370
			else
1371
			{
1372
				$pos = strpos($t, chr(0));
1373
				if ($pos !== false)
1374
					$trns = array($pos);
1375
			}
1376
			$this->_readstream($f, 4);
1377
		}
1378
		elseif ($type == 'IDAT')
1379
		{
1380
			// Read image data block
1381
			$data .= $this->_readstream($f, $n);
1382
			$this->_readstream($f, 4);
1383
		}
1384
		elseif ($type == 'IEND')
1385
			break;
1386
		else
1387
			$this->_readstream($f, $n + 4);
1388
	}
1389
	while ($n);
1390
1391
	if ($colspace == 'Indexed' && empty($pal))
1392
		$this->Error('Missing palette in '.$file);
1393
	$info = array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'dp'=>$dp, 'pal'=>$pal, 'trns'=>$trns);
1394
	if ($ct >= 4)
1395
	{
1396
		// Extract alpha channel
1397
		if ( ! function_exists('gzuncompress'))
1398
			$this->Error('Zlib not available, can\'t handle alpha channel: '.$file);
1399
		$data = gzuncompress($data);
1400
		$color = '';
1401
		$alpha = '';
1402
		if ($ct == 4)
1403
		{
1404
			// Gray image
1405
			$len = 2 * $w;
1406 View Code Duplication
			for ($i = 0; $i < $h; $i++)
1407
			{
1408
				$pos = (1 + $len) * $i;
1409
				$color .= $data[$pos];
1410
				$alpha .= $data[$pos];
1411
				$line = substr($data, $pos + 1, $len);
1412
				$color .= preg_replace('/(.)./s', '$1', $line);
1413
				$alpha .= preg_replace('/.(.)/s', '$1', $line);
1414
			}
1415
		} else
1416
		{
1417
			// RGB image
1418
			$len = 4 * $w;
1419 View Code Duplication
			for ($i = 0; $i < $h; $i++)
1420
			{
1421
				$pos = (1 + $len) * $i;
1422
				$color .= $data[$pos];
1423
				$alpha .= $data[$pos];
1424
				$line = substr($data, $pos + 1, $len);
1425
				$color .= preg_replace('/(.{3})./s', '$1', $line);
1426
				$alpha .= preg_replace('/.{3}(.)/s', '$1', $line);
1427
			}
1428
		}
1429
		unset($data);
1430
		$data = gzcompress($color);
1431
		$info['smask'] = gzcompress($alpha);
1432
		if ($this->PDFVersion < '1.4')
1433
			$this->PDFVersion = '1.4';
1434
	}
1435
	$info['data'] = $data;
1436
	return $info;
1437
}
1438
1439
function _readstream($f, $n)
1440
{
1441
	// Read n bytes from stream
1442
	$res = '';
1443
	while ($n > 0 && ! feof($f))
1444
	{
1445
		$s = fread($f, $n);
1446
		if ($s === false)
1447
			$this->Error('Error while reading stream');
1448
		$n -= strlen($s);
1449
		$res .= $s;
1450
	}
1451
	if ($n > 0)
1452
		$this->Error('Unexpected end of stream');
1453
	return $res;
1454
}
1455
1456
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
function _parsegif($file)
1464
{
1465
	// Extract info from a GIF file (via PNG conversion)
1466
	if ( ! function_exists('imagepng'))
1467
		$this->Error('GD extension is required for GIF support');
1468
	if ( ! function_exists('imagecreatefromgif'))
1469
		$this->Error('GD has no GIF read support');
1470
	$im = imagecreatefromgif($file);
1471
	if ( ! $im)
1472
		$this->Error('Missing or incorrect image file: '.$file);
1473
	imageinterlace($im, 0);
1474
	$f = @fopen('php://temp', 'rb+');
1475
	if ($f)
1476
	{
1477
		// Perform conversion in memory
1478
		ob_start();
1479
		imagepng($im);
1480
		$data = ob_get_clean();
1481
		imagedestroy($im);
1482
		fwrite($f, $data);
1483
		rewind($f);
1484
		$info = $this->_parsepngstream($f, $file);
1485
		fclose($f);
1486
	}
1487
	else
1488
	{
1489
		// Use temporary file
1490
		$tmp = tempnam('.', 'gif');
1491
		if ( ! $tmp)
1492
			$this->Error('Unable to create a temporary file');
1493
		if ( ! imagepng($im, $tmp))
1494
			$this->Error('Error while saving to temporary file');
1495
		imagedestroy($im);
1496
		$info = $this->_parsepng($tmp);
1497
		unlink($tmp);
1498
	}
1499
	return $info;
1500
}
1501
1502
function _newobj()
1503
{
1504
	// Begin a new object
1505
	$this->n++;
1506
	$this->offsets[$this->n] = strlen($this->buffer);
1507
	$this->_out($this->n.' 0 obj');
1508
}
1509
1510
function _putstream($s)
1511
{
1512
	$this->_out('stream');
1513
	$this->_out($s);
1514
	$this->_out('endstream');
1515
}
1516
1517
function _out($s)
1518
{
1519
	// Add a line to the document
1520
	if ($this->state == 2)
1521
		$this->pages[$this->page] .= $s."\n";
1522
	else
1523
		$this->buffer .= $s."\n";
1524
}
1525
1526
function _putpages()
1527
{
1528
	$nb = $this->page;
1529
	if ( ! empty($this->AliasNbPages))
1530
	{
1531
		// Replace number of pages
1532
		for ($n = 1; $n <= $nb; $n++)
1533
			$this->pages[$n] = str_replace($this->AliasNbPages, $nb, $this->pages[$n]);
1534
	}
1535
	if ($this->DefOrientation == 'P')
1536
	{
1537
		$wPt = $this->DefPageSize[0] * $this->k;
1538
		$hPt = $this->DefPageSize[1] * $this->k;
1539
	}
1540
	else
1541
	{
1542
		$wPt = $this->DefPageSize[1] * $this->k;
1543
		$hPt = $this->DefPageSize[0] * $this->k;
1544
	}
1545
	$filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
1546
	for ($n = 1; $n <= $nb; $n++)
1547
	{
1548
		// Page
1549
		$this->_newobj();
1550
		$this->_out('<</Type /Page');
1551
		$this->_out('/Parent 1 0 R');
1552
		if (isset($this->PageSizes[$n]))
1553
			$this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $this->PageSizes[$n][0], $this->PageSizes[$n][1]));
1554
		$this->_out('/Resources 2 0 R');
1555
		if (isset($this->PageLinks[$n]))
1556
		{
1557
			// Links
1558
			$annots = '/Annots [';
1559
			foreach ($this->PageLinks[$n] as $pl)
1560
			{
1561
				$rect = sprintf('%.2F %.2F %.2F %.2F', $pl[0], $pl[1], $pl[0] + $pl[2], $pl[1] - $pl[3]);
1562
				$annots .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
1563
				if (is_string($pl[4]))
1564
					$annots .= '/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
1565
				else
1566
				{
1567
					$l = $this->links[$pl[4]];
1568
					$h = isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt;
1569
					$annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>', 1 + 2 * $l[0], $h - $l[1] * $this->k);
1570
				}
1571
			}
1572
			$this->_out($annots.']');
1573
		}
1574
		if ($this->PDFVersion > '1.3')
1575
			$this->_out('/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>');
1576
		$this->_out('/Contents '.($this->n + 1).' 0 R>>');
1577
		$this->_out('endobj');
1578
		// Page content
1579
		$p = ($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
1580
		$this->_newobj();
1581
		$this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
1582
		$this->_putstream($p);
1583
		$this->_out('endobj');
1584
	}
1585
	// Pages root
1586
	$this->offsets[1] = strlen($this->buffer);
1587
	$this->_out('1 0 obj');
1588
	$this->_out('<</Type /Pages');
1589
	$kids = '/Kids [';
1590
	for ($i = 0; $i < $nb; $i++)
1591
		$kids .= (3 + 2 * $i).' 0 R ';
1592
	$this->_out($kids.']');
1593
	$this->_out('/Count '.$nb);
1594
	$this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $wPt, $hPt));
1595
	$this->_out('>>');
1596
	$this->_out('endobj');
1597
}
1598
1599
function _putfonts()
1600
{
1601
	$nf = $this->n;
1602
	foreach ($this->diffs as $diff)
1603
	{
1604
		// Encodings
1605
		$this->_newobj();
1606
		$this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
1607
		$this->_out('endobj');
1608
	}
1609
	foreach ($this->FontFiles as $file=>$info)
1610
	{
1611
		// Font file embedding
1612
		$this->_newobj();
1613
		$this->FontFiles[$file]['n'] = $this->n;
1614
		$font = file_get_contents($this->fontpath.$file, true);
1615
		if ( ! $font)
1616
			$this->Error('Font file not found: '.$file);
1617
		$compressed = (substr($file, -2) == '.z');
1618
		if ( ! $compressed && isset($info['length2']))
1619
			$font = substr($font, 6, $info['length1']).substr($font, 6 + $info['length1'] + 6, $info['length2']);
1620
		$this->_out('<</Length '.strlen($font));
1621
		if ($compressed)
1622
			$this->_out('/Filter /FlateDecode');
1623
		$this->_out('/Length1 '.$info['length1']);
1624
		if (isset($info['length2']))
1625
			$this->_out('/Length2 '.$info['length2'].' /Length3 0');
1626
		$this->_out('>>');
1627
		$this->_putstream($font);
1628
		$this->_out('endobj');
1629
	}
1630
	foreach ($this->fonts as $k=>$font)
1631
	{
1632
		// Font objects
1633
		$this->fonts[$k]['n'] = $this->n + 1;
1634
		$type = $font['type'];
1635
		$name = $font['name'];
1636
		if ($type == 'Core')
1637
		{
1638
			// Core font
1639
			$this->_newobj();
1640
			$this->_out('<</Type /Font');
1641
			$this->_out('/BaseFont /'.$name);
1642
			$this->_out('/Subtype /Type1');
1643
			if ($name != 'Symbol' && $name != 'ZapfDingbats')
1644
				$this->_out('/Encoding /WinAnsiEncoding');
1645
			$this->_out('>>');
1646
			$this->_out('endobj');
1647
		}
1648
		elseif ($type == 'Type1' || $type == 'TrueType')
1649
		{
1650
			// Additional Type1 or TrueType/OpenType 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 (isset($font['diffn']))
1659
				$this->_out('/Encoding '.($nf + $font['diffn']).' 0 R');
1660
			else
1661
				$this->_out('/Encoding /WinAnsiEncoding');
1662
			$this->_out('>>');
1663
			$this->_out('endobj');
1664
			// Widths
1665
			$this->_newobj();
1666
			$cw = &$font['cw'];
1667
			$s = '[';
1668 View Code Duplication
			for ($i = 32; $i <= 255; $i++)
1669
				$s .= $cw[chr($i)].' ';
1670
			$this->_out($s.']');
1671
			$this->_out('endobj');
1672
			// Descriptor
1673
			$this->_newobj();
1674
			$s = '<</Type /FontDescriptor /FontName /'.$name;
1675
			foreach ($font['desc'] as $k=>$v)
1676
				$s .= ' /'.$k.' '.$v;
1677
			if ( ! empty($font['file']))
1678
				$s .= ' /FontFile'.($type == 'Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R';
1679
			$this->_out($s.'>>');
1680
			$this->_out('endobj');
1681
		}
1682
		else
1683
		{
1684
			// Allow for additional types
1685
			$mtd = '_put'.strtolower($type);
1686
			if ( ! method_exists($this, $mtd))
1687
				$this->Error('Unsupported font type: '.$type);
1688
			$this->$mtd($font);
1689
		}
1690
	}
1691
}
1692
1693
function _putimages()
1694
{
1695
	foreach (array_keys($this->images) as $file)
1696
	{
1697
		$this->_putimage($this->images[$file]);
1698
		unset($this->images[$file]['data']);
1699
		unset($this->images[$file]['smask']);
1700
	}
1701
}
1702
1703
function _putimage(&$info)
1704
{
1705
	$this->_newobj();
1706
	$info['n'] = $this->n;
1707
	$this->_out('<</Type /XObject');
1708
	$this->_out('/Subtype /Image');
1709
	$this->_out('/Width '.$info['w']);
1710
	$this->_out('/Height '.$info['h']);
1711
	if ($info['cs'] == 'Indexed')
1712
		$this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal']) / 3 - 1).' '.($this->n + 1).' 0 R]');
1713
	else
1714
	{
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
	$this->_out('/BitsPerComponent '.$info['bpc']);
1720
	if (isset($info['f']))
1721
		$this->_out('/Filter /'.$info['f']);
1722
	if (isset($info['dp']))
1723
		$this->_out('/DecodeParms <<'.$info['dp'].'>>');
1724
	if (isset($info['trns']) && is_array($info['trns']))
1725
	{
1726
		$trns = '';
1727
		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...
1728
			$trns .= $info['trns'][$i].' '.$info['trns'][$i].' ';
1729
		$this->_out('/Mask ['.$trns.']');
1730
	}
1731
	if (isset($info['smask']))
1732
		$this->_out('/SMask '.($this->n + 1).' 0 R');
1733
	$this->_out('/Length '.strlen($info['data']).'>>');
1734
	$this->_putstream($info['data']);
1735
	$this->_out('endobj');
1736
	// Soft mask
1737
	if (isset($info['smask']))
1738
	{
1739
		$dp = '/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns '.$info['w'];
1740
		$smask = array('w'=>$info['w'], 'h'=>$info['h'], 'cs'=>'DeviceGray', 'bpc'=>8, 'f'=>$info['f'], 'dp'=>$dp, 'data'=>$info['smask']);
1741
		$this->_putimage($smask);
1742
	}
1743
	// Palette
1744
	if ($info['cs'] == 'Indexed')
1745
	{
1746
		$filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
1747
		$pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal'];
1748
		$this->_newobj();
1749
		$this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
1750
		$this->_putstream($pal);
1751
		$this->_out('endobj');
1752
	}
1753
}
1754
1755
function _putxobjectdict()
1756
{
1757
	foreach ($this->images as $image)
1758
		$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
1759
}
1760
1761
function _putresourcedict()
1762
{
1763
	$this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
1764
	$this->_out('/Font <<');
1765
	foreach ($this->fonts as $font)
1766
		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
1767
	$this->_out('>>');
1768
	$this->_out('/XObject <<');
1769
	$this->_putxobjectdict();
1770
	$this->_out('>>');
1771
}
1772
1773
function _putresources()
1774
{
1775
	$this->_putfonts();
1776
	$this->_putimages();
1777
	// Resource dictionary
1778
	$this->offsets[2] = strlen($this->buffer);
1779
	$this->_out('2 0 obj');
1780
	$this->_out('<<');
1781
	$this->_putresourcedict();
1782
	$this->_out('>>');
1783
	$this->_out('endobj');
1784
}
1785
1786
function _putinfo()
1787
{
1788
	$this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
1789
	if ( ! empty($this->title))
1790
		$this->_out('/Title '.$this->_textstring($this->title));
1791
	if ( ! empty($this->subject))
1792
		$this->_out('/Subject '.$this->_textstring($this->subject));
1793
	if ( ! empty($this->author))
1794
		$this->_out('/Author '.$this->_textstring($this->author));
1795
	if ( ! empty($this->keywords))
1796
		$this->_out('/Keywords '.$this->_textstring($this->keywords));
1797
	if ( ! empty($this->creator))
1798
		$this->_out('/Creator '.$this->_textstring($this->creator));
1799
	$this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis')));
1800
}
1801
1802
function _putcatalog()
1803
{
1804
	$this->_out('/Type /Catalog');
1805
	$this->_out('/Pages 1 0 R');
1806
	if ($this->ZoomMode == 'fullpage')
1807
		$this->_out('/OpenAction [3 0 R /Fit]');
1808
	elseif ($this->ZoomMode == 'fullwidth')
1809
		$this->_out('/OpenAction [3 0 R /FitH null]');
1810
	elseif ($this->ZoomMode == 'real')
1811
		$this->_out('/OpenAction [3 0 R /XYZ null null 1]');
1812
	elseif ( ! is_string($this->ZoomMode))
1813
		$this->_out('/OpenAction [3 0 R /XYZ null null '.sprintf('%.2F', $this->ZoomMode / 100).']');
1814
	if ($this->LayoutMode == 'single')
1815
		$this->_out('/PageLayout /SinglePage');
1816
	elseif ($this->LayoutMode == 'continuous')
1817
		$this->_out('/PageLayout /OneColumn');
1818
	elseif ($this->LayoutMode == 'two')
1819
		$this->_out('/PageLayout /TwoColumnLeft');
1820
}
1821
1822
function _putheader()
1823
{
1824
	$this->_out('%PDF-'.$this->PDFVersion);
1825
}
1826
1827
function _puttrailer()
1828
{
1829
	$this->_out('/Size '.($this->n + 1));
1830
	$this->_out('/Root '.$this->n.' 0 R');
1831
	$this->_out('/Info '.($this->n - 1).' 0 R');
1832
}
1833
1834
function _enddoc()
1835
{
1836
	$this->_putheader();
1837
	$this->_putpages();
1838
	$this->_putresources();
1839
	// Info
1840
	$this->_newobj();
1841
	$this->_out('<<');
1842
	$this->_putinfo();
1843
	$this->_out('>>');
1844
	$this->_out('endobj');
1845
	// Catalog
1846
	$this->_newobj();
1847
	$this->_out('<<');
1848
	$this->_putcatalog();
1849
	$this->_out('>>');
1850
	$this->_out('endobj');
1851
	// Cross-ref
1852
	$o = strlen($this->buffer);
1853
	$this->_out('xref');
1854
	$this->_out('0 '.($this->n + 1));
1855
	$this->_out('0000000000 65535 f ');
1856
	for ($i = 1; $i <= $this->n; $i++)
1857
		$this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
1858
	// Trailer
1859
	$this->_out('trailer');
1860
	$this->_out('<<');
1861
	$this->_puttrailer();
1862
	$this->_out('>>');
1863
	$this->_out('startxref');
1864
	$this->_out($o);
1865
	$this->_out('%%EOF');
1866
	$this->state = 3;
1867
}
1868
// End of class
1869
}
1870
1871
// Handle special IE contype request
1872
if (isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == 'contype')
1873
{
1874
	header('Content-Type: application/pdf');
1875
	exit;
1876
}
1877
1878
}
1879
1880
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
1881