GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

FPDF::GetStringWidth()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 10
rs 9.4285
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
/*******************************************************************************
3
* Software: FPDF                                                               *
4
* Version:  1.52                                                               *
5
* Date:     2003-12-30                                                         *
6
* Author:   Olivier PLATHEY                                                    *
7
* License:  Freeware                                                           *
8
*                                                                              *
9
* You may use and modify this software as you wish.                            *
10
*******************************************************************************/
11
12
if (!class_exists('FPDF')) {
13
14
define('FPDF_FONTPATH',dirname(__FILE__)."/fpdf/");
15
define('FPDF_VERSION','1.52');
16
17
class FPDF
18
{
19
    //Private properties
20
    var $page;               //current page number
21
    var $n;                  //current object number
22
    var $offsets;            //array of object offsets
23
    var $buffer;             //buffer holding in-memory PDF
24
    var $pages;              //array containing pages
25
    var $state;              //current document state
26
    var $compress;           //compression flag
27
    var $DefOrientation;     //default orientation
28
    var $CurOrientation;     //current orientation
29
    var $OrientationChanges; //array indicating orientation changes
30
    var $k;                  //scale factor (number of points in user unit)
31
    var $fwPt,$fhPt;         //dimensions of page format in points
32
    var $fw,$fh;             //dimensions of page format in user unit
33
    var $wPt,$hPt;           //current dimensions of page in points
34
    var $w,$h;               //current dimensions of page in user unit
35
    var $lMargin;            //left margin
36
    var $tMargin;            //top margin
37
    var $rMargin;            //right margin
38
    var $bMargin;            //page break margin
39
    var $cMargin;            //cell margin
40
    var $x,$y;               //current position in user unit for cell positioning
41
    var $lasth;              //height of last cell printed
42
    var $LineWidth;          //line width in user unit
43
    var $CoreFonts;          //array of standard font names
44
    var $fonts;              //array of used fonts
45
    var $FontFiles;          //array of font files
46
    var $diffs;              //array of encoding differences
47
    var $images;             //array of used images
48
    var $PageLinks;          //array of links in pages
49
    var $links;              //array of internal links
50
    var $FontFamily;         //current font family
51
    var $FontStyle;          //current font style
52
    var $underline;          //underlining flag
53
    var $CurrentFont;        //current font info
54
    var $FontSizePt;         //current font size in points
55
    var $FontSize;           //current font size in user unit
56
    var $DrawColor;          //commands for drawing color
57
    var $FillColor;          //commands for filling color
58
    var $TextColor;          //commands for text color
59
    var $ColorFlag;          //indicates whether fill and text colors are different
60
    var $ws;                 //word spacing
61
    var $AutoPageBreak;      //automatic page breaking
62
    var $PageBreakTrigger;   //threshold used to trigger page breaks
63
    var $InFooter;           //flag set when processing footer
64
    var $ZoomMode;           //zoom display mode
65
    var $LayoutMode;         //layout display mode
66
    var $title;              //title
67
    var $subject;            //subject
68
    var $author;             //author
69
    var $keywords;           //keywords
70
    var $creator;            //creator
71
    var $producer;            //Producer
72
    var $AliasNbPages;       //alias for total number of pages
73
74
/*******************************************************************************
75
*                                                                              *
76
*                               Public methods                                 *
77
*                                                                              *
78
*******************************************************************************/
79
    function FPDF ($orientation='P', $unit='mm', $format='A4') {
80
	//Some checks
81
	$this->_dochecks();
82
	//Initialization of properties
83
	$this->page=0;
84
	$this->n=2;
85
	$this->buffer='';
86
	$this->pages=array();
87
	$this->OrientationChanges=array();
88
	$this->state=0;
89
	$this->fonts=array();
90
	$this->FontFiles=array();
91
	$this->diffs=array();
92
	$this->images=array();
93
	$this->links=array();
94
	$this->InFooter=false;
95
	$this->lasth=0;
96
	$this->FontFamily='';
97
	$this->FontStyle='';
98
	$this->FontSizePt=12;
99
	$this->underline=false;
100
	$this->DrawColor='0 G';
101
	$this->FillColor='0 g';
102
	$this->TextColor='0 g';
103
	$this->ColorFlag=false;
104
	$this->ws=0;
105
	//Standard fonts
106
	$this->CoreFonts=array('japanees'=>'Japanees',
107
                               'courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique',
108
                               'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique',
109
                               'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic',
110
                               'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats');
111
	//Scale factor
112
	if ($unit=='pt')
113
            $this->k=1;
114
	elseif ($unit=='mm')
115
            $this->k=72/25.4;
116
	elseif ($unit=='cm')
117
            $this->k=72/2.54;
118
	elseif ($unit=='in')
119
            $this->k=72;
120
	else
121
            $this->Error('Incorrect unit: '.$unit);
122
	//Page format
123
	if (is_string($format))
124
	{
125
            $format=strtolower($format);
126
            if ($format=='a3')
127
                $format=array(841.89,1190.55);
128
            elseif ($format=='a4')
129
                $format=array(595.28,841.89);
130
            elseif ($format=='a5')
131
                $format=array(420.94,595.28);
132
            elseif ($format=='letter')
133
                $format=array(612,792);
134
            elseif ($format=='legal')
135
                $format=array(612,1008);
136
            else
137
                $this->Error('Unknown page format: '.$format);
138
            $this->fwPt=$format[0];
139
            $this->fhPt=$format[1];
140
	}
141
	else
142
	{
143
            $this->fwPt=$format[0]*$this->k;
144
            $this->fhPt=$format[1]*$this->k;
145
	}
146
	$this->fw=$this->fwPt/$this->k;
147
	$this->fh=$this->fhPt/$this->k;
148
	//Page orientation
149
	$orientation=strtolower($orientation);
150
	if ($orientation=='p' or $orientation=='portrait')
151
	{
152
            $this->DefOrientation='P';
153
            $this->wPt=$this->fwPt;
154
            $this->hPt=$this->fhPt;
155
	}
156
	elseif ($orientation=='l' or $orientation=='landscape')
157
	{
158
            $this->DefOrientation='L';
159
            $this->wPt=$this->fhPt;
160
            $this->hPt=$this->fwPt;
161
	}
162
	else
163
            $this->Error('Incorrect orientation: '.$orientation);
164
	$this->CurOrientation=$this->DefOrientation;
165
	$this->w=$this->wPt/$this->k;
166
	$this->h=$this->hPt/$this->k;
167
	//Page margins (1 cm)
168
	$margin=28.35/$this->k;
169
	$this->SetMargins($margin,$margin);
170
	//Interior cell margin (1 mm)
171
	$this->cMargin=$margin/10;
172
	//Line width (0.2 mm)
173
	$this->LineWidth=.567/$this->k;
174
	//Automatic page break
175
	$this->SetAutoPageBreak(true,2*$margin);
176
	//Full width display mode
177
	$this->SetDisplayMode('fullwidth');
178
	//Compression
179
	$this->SetCompression(true);
180
    }
181
182
    function SetMargins($left,$top,$right=-1) {
183
	//Set left, top and right margins
184
	$this->lMargin=$left;
185
	$this->tMargin=$top;
186
	if ($right==-1)
187
            $right=$left;
188
	$this->rMargin=$right;
189
    }
190
191
    function SetLeftMargin($margin) {
192
	//Set left margin
193
	$this->lMargin=$margin;
194
	if ($this->page>0 and $this->x<$margin)
195
            $this->x=$margin;
196
    }
197
198
    function SetTopMargin($margin) {
199
	//Set top margin
200
	$this->tMargin=$margin;
201
    }
202
203
    function SetRightMargin($margin) {
204
	//Set right margin
205
	$this->rMargin=$margin;
206
    }
207
208
    function SetAutoPageBreak($auto,$margin=0) {
209
	//Set auto page break mode and triggering margin
210
	$this->AutoPageBreak=$auto;
211
	$this->bMargin=$margin;
212
	$this->PageBreakTrigger=$this->h-$margin;
213
    }
214
215
    function SetDisplayMode($zoom,$layout='continuous') {
216
	//Set display mode in viewer
217
	if ($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
218
            $this->ZoomMode=$zoom;
219
	else
220
            $this->Error('Incorrect zoom display mode: '.$zoom);
221
	if ($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='default')
222
            $this->LayoutMode=$layout;
223
	else
224
            $this->Error('Incorrect layout display mode: '.$layout);
225
    }
226
227
    function SetCompression($compress) {
228
	//Set page compression
229
	if (function_exists('gzcompress'))
230
            $this->compress=$compress;
231
	else
232
            $this->compress=false;
233
    }
234
235
    function SetTitle($title) {
236
	//Title of document
237
	$this->title=$title;
238
    }
239
240
    function SetSubject($subject) {
241
	//Subject of document
242
	$this->subject=$subject;
243
    }
244
245
    function SetAuthor($author) {
246
	//Author of document
247
	$this->author=$author;
248
    }
249
250
    function SetKeywords($keywords) {
251
	//Keywords of document
252
	$this->keywords=$keywords;
253
    }
254
255
    function SetCreator($creator) {
256
	//Creator of document
257
	$this->creator=$creator;
258
    }
259
260
    function SetProducer($producer) {
261
	//Producer of document
262
	$this->producer=$producer;
263
    }
264
265
    function AliasNbPages($alias='{nb}') {
266
	//Define an alias for total number of pages
267
	$this->AliasNbPages=$alias;
268
    }
269
270
    function Error($msg) {
271
	//Fatal error
272
	die('<B>FPDF error: </B>'.$msg);
0 ignored issues
show
Coding Style Compatibility introduced by
The method Error() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
273
    }
274
275
    function Open() {
276
	//Begin document
277
	if ($this->state==0)
278
            $this->_begindoc();
279
    }
280
281
    function Close() {
282
	//Terminate document
283
	if ($this->state==3)
284
            return;
285
	if ($this->page==0)
286
            $this->AddPage();
287
	//Page footer
288
	$this->InFooter=true;
289
	$this->Footer();
290
	$this->InFooter=false;
291
	//Close page
292
	$this->_endpage();
293
	//Close document
294
	$this->_enddoc();
295
    }
296
297
    function AddPage($orientation='') {
298
	//Start a new page
299
	if ($this->state==0)
300
            $this->Open();
301
	$family=$this->FontFamily;
302
	$style=$this->FontStyle.($this->underline ? 'U' : '');
303
	$size=$this->FontSizePt;
304
	$lw=$this->LineWidth;
305
	$dc=$this->DrawColor;
306
	$fc=$this->FillColor;
307
	$tc=$this->TextColor;
308
	$cf=$this->ColorFlag;
309
	if ($this->page>0) {
310
            //Page footer
311
            $this->InFooter=true;
312
            $this->Footer();
313
            $this->InFooter=false;
314
            //Close page
315
            $this->_endpage();
316
        }
317
	//Start new page
318
	$this->_beginpage($orientation);
319
	//Set line cap style to square
320
	$this->_out('2 J');
321
	//Set line width
322
	$this->LineWidth=$lw;
323
	$this->_out(sprintf('%.2f w',$lw*$this->k));
324
	//Set font
325
	if ($family)
326
            $this->SetFont($family,$style,$size);
327
	//Set colors
328
	$this->DrawColor=$dc;
329
	if ($dc!='0 G')
330
            $this->_out($dc);
331
	$this->FillColor=$fc;
332
	if ($fc!='0 g')
333
            $this->_out($fc);
334
	$this->TextColor=$tc;
335
	$this->ColorFlag=$cf;
336
	//Page header
337
	$this->Header();
338
	//Restore line width
339
	if ($this->LineWidth!=$lw) {
340
            $this->LineWidth=$lw;
341
            $this->_out(sprintf('%.2f w',$lw*$this->k));
342
        }
343
	//Restore font
344
	if ($family)
345
            $this->SetFont($family,$style,$size);
346
	//Restore colors
347
	if ($this->DrawColor!=$dc) {
348
            $this->DrawColor=$dc;
349
            $this->_out($dc);
350
        }
351
	if ($this->FillColor!=$fc) {
352
            $this->FillColor=$fc;
353
            $this->_out($fc);
354
        }
355
	$this->TextColor=$tc;
356
	$this->ColorFlag=$cf;
357
    }
358
359
    function Header() {
360
	//To be implemented in your own inherited class
361
    }
362
363
    function Footer() {
364
	//To be implemented in your own inherited class
365
    }
366
367
    function PageNo() {
368
	//Get current page number
369
	return $this->page;
370
    }
371
372
    function SetDrawColor($r,$g=-1,$b=-1) {
373
	//Set color for all stroking operations
374
	if (($r==0 and $g==0 and $b==0) or $g==-1)
375
            $this->DrawColor=sprintf('%.3f G',$r/255);
376
	else
377
            $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
378
	if ($this->page>0)
379
            $this->_out($this->DrawColor);
380
    }
381
382
    function SetFillColor($r,$g=-1,$b=-1) {
383
	//Set color for all filling operations
384
	if (($r==0 and $g==0 and $b==0) or $g==-1)
385
            $this->FillColor=sprintf('%.3f g',$r/255);
386
	else
387
            $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
388
	$this->ColorFlag=($this->FillColor!=$this->TextColor);
389
	if ($this->page>0)
390
            $this->_out($this->FillColor);
391
    }
392
393
    function SetTextColor($r,$g=-1,$b=-1) {
394
	//Set color for text
395
	if (($r==0 and $g==0 and $b==0) or $g==-1)
396
            $this->TextColor=sprintf('%.3f g',$r/255);
397
	else
398
            $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
399
	$this->ColorFlag=($this->FillColor!=$this->TextColor);
400
    }
401
402
    function GetStringWidth($s) {
403
	//Get width of a string in the current font
404
	$s=(string)$s;
405
	$cw=&$this->CurrentFont['cw'];
406
	$w=0;
407
	$l=strlen($s);
408
	for($i=0;$i<$l;$i++)
409
            $w+=$cw[$s{$i}];
410
	return $w*$this->FontSize/1000;
411
    }
412
413
    function SetLineWidth($width) {
414
	//Set line width
415
	$this->LineWidth=$width;
416
	if ($this->page>0)
417
            $this->_out(sprintf('%.2f w',$width*$this->k));
418
    }
419
420
    function Line($x1,$y1,$x2,$y2) {
421
	//Draw a line
422
	$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));
423
    }
424
425
    function Rect($x,$y,$w,$h,$style='') {
426
	//Draw a rectangle
427
	if ($style=='F')
428
            $op='f';
429
	elseif ($style=='FD' or $style=='DF')
430
            $op='B';
431
	else
432
            $op='S';
433
	$this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
434
    }
435
436
    function AddFont($family,$style='',$file='') {
437
	//Add a TrueType or Type1 font
438
	$family=strtolower($family);
439
	if ($family=='arial')
440
            $family='helvetica';
441
	$style=strtoupper($style);
442
	if ($style=='IB')
443
            $style='BI';
444
	if (isset($this->fonts[$family.$style]))
445
            $this->Error('Font already added: '.$family.' '.$style);
446
	if ($file=='')
447
            $file=str_replace(' ','',$family).strtolower($style).'.php';
448
	if (defined('FPDF_FONTPATH'))
449
            $file = FPDF_FONTPATH . $file;
450
	include($file);
451
	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...
452
            $this->Error('Could not include font definition file');
453
	$i=count($this->fonts)+1;
454
	$this->fonts[$family.$style]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file);
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...
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...
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...
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...
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...
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...
455
	if ($diff) {
456
            //Search existing encodings
457
            $d=0;
458
            $nb=count($this->diffs);
459
            for ($i=1;$i<=$nb;$i++)
460
                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...
461
                    $d=$i;
462
                    break;
463
                }
464
            if ($d==0) {
465
                $d=$nb+1;
466
                $this->diffs[$d]=$diff;
467
            }
468
            $this->fonts[$family.$style]['diff']=$d;
469
        }
470
	if ($file) {
471
            if ($type=='TrueType')
472
                $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...
473
            else
474
                $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...
475
        }
476
    }
477
478
    function SetFont($family,$style='',$size=0) {
479
	//Select a font; size given in points
480
	global $fpdf_charwidths;
481
482
	$family=strtolower($family);
483
	if ($family=='')
484
            $family=$this->FontFamily;
485
	if ($family=='arial')
486
            $family='helvetica';
487
	elseif ($family=='symbol' or $family=='zapfdingbats')
488
            $style='';
489
	$style=strtoupper($style);
490
	if (is_int(strpos($style,'U'))) {
491
            $this->underline=true;
492
            $style=str_replace('U','',$style);
493
        }
494
	else
495
            $this->underline=false;
496
	if ($style=='IB')
497
            $style='BI';
498
	if ($size==0)
499
            $size=$this->FontSizePt;
500
	//Test if font is already selected
501
	if ($this->FontFamily==$family and $this->FontStyle==$style and $this->FontSizePt==$size)
502
            return;
503
	//Test if used for the first time
504
	$fontkey=$family.$style;
505
	if (!isset($this->fonts[$fontkey])) {
506
            //Check if one of the standard fonts
507
            if (isset($this->CoreFonts[$fontkey])) {
508
                if (!isset($fpdf_charwidths[$fontkey])) {
509
                    //Load metric file
510
                    $file=$family;
511
                    if ($family=='times' or $family=='helvetica')
512
                        $file.=strtolower($style);
513
                    $file.='.php';
514
                    if (defined('FPDF_FONTPATH'))
515
                        $file=FPDF_FONTPATH.$file;
516
                    include($file);
517
                    if (!isset($fpdf_charwidths[$fontkey]))
518
                        $this->Error('Could not include font metric file');
519
                }
520
                $i=count($this->fonts)+1;
521
                $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]);
522
            }
523
            else
524
                $this->Error('Undefined font: '.$family.' '.$style);
525
        }
526
	//Select it
527
	$this->FontFamily=$family;
528
	$this->FontStyle=$style;
529
	$this->FontSizePt=$size;
530
	$this->FontSize=$size/$this->k;
531
	$this->CurrentFont=&$this->fonts[$fontkey];
532
	if ($this->page>0)
533
            $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
534
    }
535
536
    function SetFontSize($size) {
537
	//Set font size in points
538
	if ($this->FontSizePt==$size)
539
            return;
540
	$this->FontSizePt=$size;
541
	$this->FontSize=$size/$this->k;
542
	if ($this->page>0)
543
            $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
544
    }
545
546
    function AddLink() {
547
	//Create a new internal link
548
	$n=count($this->links)+1;
549
	$this->links[$n]=array(0,0);
550
	return $n;
551
    }
552
553
    function SetLink($link,$y=0,$page=-1) {
554
	//Set destination of internal link
555
	if ($y==-1)
556
            $y=$this->y;
557
	if ($page==-1)
558
            $page=$this->page;
559
	$this->links[$link]=array($page,$y);
560
    }
561
562
    function Link($x,$y,$w,$h,$link) {
563
	//Put a link on the page
564
	$this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
565
    }
566
567
    function Text($x,$y,$txt) {
568
	//Output a string
569
	$s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt));
570
	if ($this->underline and $txt!='')
571
            $s.=' '.$this->_dounderline($x,$y,$txt);
572
	if ($this->ColorFlag)
573
            $s='q '.$this->TextColor.' '.$s.' Q';
574
	$this->_out($s);
575
    }
576
577
    function AcceptPageBreak() {
578
	//Accept automatic page break or not
579
	return $this->AutoPageBreak;
580
    }
581
582
    function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='') {
583
	//Output a cell
584
	$k=$this->k;
585
	if ($this->y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
586
            //Automatic page break
587
            $x=$this->x;
588
            $ws=$this->ws;
589
            if ($ws>0) {
590
                $this->ws=0;
591
                $this->_out('0 Tw');
592
            }
593
            $this->AddPage($this->CurOrientation);
594
            $this->x=$x;
595
            if ($ws>0) {
596
                $this->ws=$ws;
597
                $this->_out(sprintf('%.3f Tw',$ws*$k));
598
            }
599
        }
600
	if ($w==0)
601
            $w=$this->w-$this->rMargin-$this->x;
602
	$s='';
603
	if ($fill==1 or $border==1) {
604
            if ($fill==1)
605
                $op=($border==1) ? 'B' : 'f';
606
            else
607
                $op='S';
608
            $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
609
        }
610
	if (is_string($border)) {
611
            $x=$this->x;
612
            $y=$this->y;
613
            if (is_int(strpos($border,'L')))
614
                $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
615
            if (is_int(strpos($border,'T')))
616
                $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
617
            if (is_int(strpos($border,'R')))
618
                $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
619
            if (is_int(strpos($border,'B')))
620
                $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
621
        }
622
	if ($txt!='') {
623
            if ($align=='R')
624
                $dx=$w-$this->cMargin-$this->GetStringWidth($txt);
625
            elseif ($align=='C')
626
                $dx=($w-$this->GetStringWidth($txt))/2;
627
            else
628
                $dx=$this->cMargin;
629
            if ($this->ColorFlag)
630
                $s.='q '.$this->TextColor.' ';
631
            $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
632
            $s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2);
633
            if ($this->underline)
634
                $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
635
            if ($this->ColorFlag)
636
                $s.=' Q';
637
            if ($link)
638
                $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
639
        }
640
	if ($s)
641
            $this->_out($s);
642
	$this->lasth=$h;
643
	if ($ln>0) {
644
            //Go to next line
645
            $this->y+=$h;
646
            if ($ln==1)
647
                $this->x=$this->lMargin;
648
        }
649
	else
650
            $this->x+=$w;
651
    }
652
653
    function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0) {
654
	//Output text with automatic or explicit line breaks
655
	$cw=&$this->CurrentFont['cw'];
656
	if ($w==0)
657
            $w=$this->w-$this->rMargin-$this->x;
658
	$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
659
	$s=str_replace("\r",'',$txt);
660
	$nb=strlen($s);
661
	if ($nb>0 and $s[$nb-1]=="\n")
662
            $nb--;
663
	$b=0;
664
	if ($border) {
665
            if ($border==1) {
666
                $border='LTRB';
667
                $b='LRT';
668
                $b2='LR';
669
            }
670
            else
671
                {
672
                    $b2='';
673
                    if (is_int(strpos($border,'L')))
674
                        $b2.='L';
675
                    if (is_int(strpos($border,'R')))
676
                        $b2.='R';
677
                    $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
678
                }
679
        }
680
	$sep=-1;
681
	$i=0;
682
	$j=0;
683
	$l=0;
684
	$ns=0;
685
	$nl=1;
686
	while ($i<$nb) {
687
            //Get next character
688
            $c=$s{$i};
689
            if ($c=="\n") {
690
                //Explicit line break
691
                if ($this->ws>0) {
692
                    $this->ws=0;
693
                    $this->_out('0 Tw');
694
                }
695
                $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
696
                $i++;
697
                $sep=-1;
698
                $j=$i;
699
                $l=0;
700
                $ns=0;
701
                $nl++;
702
                if ($border and $nl==2)
703
                    $b=$b2;
704
                continue;
705
            }
706
            if ($c==' ') {
707
                $sep=$i;
708
                $ls=$l;
709
                $ns++;
710
            }
711
            $l+=$cw[$c];
712
            if ($l>$wmax) {
713
                //Automatic line break
714
                if ($sep==-1) {
715
                    if ($i==$j)
716
                        $i++;
717
                    if ($this->ws>0) {
718
                        $this->ws=0;
719
                        $this->_out('0 Tw');
720
                    }
721
                    $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
722
                }
723
                else
724
                    {
725
                        if ($align=='J') {
726
                            $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
727
                            $this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
728
                        }
729
                        $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
730
                        $i=$sep+1;
731
                    }
732
                $sep=-1;
733
                $j=$i;
734
                $l=0;
735
                $ns=0;
736
                $nl++;
737
                if ($border and $nl==2)
738
                    $b=$b2;
739
            }
740
            else
741
                $i++;
742
        }
743
	//Last chunk
744
	if ($this->ws>0) {
745
            $this->ws=0;
746
            $this->_out('0 Tw');
747
        }
748
	if ($border and is_int(strpos($border,'B')))
749
            $b.='B';
750
	$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
751
	$this->x=$this->lMargin;
752
    }
753
754
    function Write($h,$txt,$link='') {
755
	//Output text in flowing mode
756
	$cw=&$this->CurrentFont['cw'];
757
	$w=$this->w - $this->rMargin - $this->x;
758
	$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
759
	$s=str_replace("\r",'',$txt);
760
	$nb=strlen($s);
761
	$sep=-1;
762
	$i=0;
763
	$j=0;
764
	$l=0;
765
	$nl=1;
766
	while($i<$nb) {
767
            //Get next character
768
            $c=$s{$i};
769
            if ($c=="\n") {
770
                //Explicit line break
771
                $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
772
                $i++;
773
                $sep=-1;
774
                $j=$i;
775
                $l=0;
776
                if ($nl==1) {
777
                    $this->x=$this->lMargin;
778
                    $w=$this->w-$this->rMargin-$this->x;
779
                    $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
780
                }
781
                $nl++;
782
                continue;
783
            }
784
            if ($c==' ')
785
                $sep=$i;
786
            $l+=$cw[$c];
787
            if ($l>$wmax) {
788
                //Automatic line break
789
                if ($sep==-1) {
790
                    if ($this->x>$this->lMargin) {
791
                        //Move to next line
792
                        $this->x=$this->lMargin;
793
                        $this->y+=$h;
794
                        $w=$this->w-$this->rMargin-$this->x;
795
                        $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
796
                        $i++;
797
                        $nl++;
798
                        continue;
799
                    }
800
                    if ($i==$j)
801
                        $i++;
802
                    $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
803
                }
804
                else {
805
                    $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
806
                    $i=$sep+1;
807
                }
808
                $sep=-1;
809
                $j=$i;
810
                $l=0;
811
                if ($nl==1) {
812
                    $this->x=$this->lMargin;
813
                    $w=$this->w-$this->rMargin-$this->x;
814
                    $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
815
                }
816
                $nl++;
817
            }
818
            else
819
                $i++;
820
        }
821
	//Last chunk
822
	if ($i!=$j)
823
            $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link);
824
    }
825
826
    function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') {
827
	//Put an image on the page
828
	if (!isset($this->images[$file])) {
829
            //First use of image, get info
830
            if ($type=='') {
831
                $pos=strrpos($file,'.');
832
                if (!$pos)
833
                    $this->Error('Image file has no extension and no type was specified: '.$file);
834
                $type=substr($file,$pos+1);
835
            }
836
            $type=strtolower($type);
837
            $mqr=get_magic_quotes_runtime();
838
            set_magic_quotes_runtime(0);
839
            if ($type=='jpg' or $type=='jpeg')
840
                $info=$this->_parsejpg($file);
841
            elseif ($type=='png')
842
                $info=$this->_parsepng($file);
843
            elseif ($type=='gif')
844
                $info=$this->_parsegif ($file);
845
            else
846
                {
847
                    //Allow for additional formats
848
                    $mtd='_parse'.$type;
849
                    if (!method_exists($this,$mtd))
850
                        $this->Error('Unsupported image type: '.$type);
851
                    $info=$this->$mtd($file);
852
                }
853
            set_magic_quotes_runtime($mqr);
854
            $info['i']=count($this->images)+1;
855
            $this->images[$file]=$info;
856
        }
857
	else
858
            $info=$this->images[$file];
859
	//Automatic width and height calculation if needed
860
	if ($w==0 and $h==0) {
861
            //Put image at 72 dpi
862
            $w=$info['w']/$this->k;
863
            $h=$info['h']/$this->k;
864
        }
865
	if ($w==0)
866
            $w=$h*$info['w']/$info['h'];
867
	if ($h==0)
868
            $h=$w*$info['h']/$info['w'];
869
	$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']));
870
	if ($link)
871
            $this->Link($x,$y,$w,$h,$link);
872
    }
873
874
    function Ln($h='') {
875
	//Line feed; default value is last cell height
876
	$this->x=$this->lMargin;
877
	if (is_string($h))
878
            $this->y+=$this->lasth;
879
	else
880
            $this->y+=$h;
881
    }
882
883
    function GetX() {
884
	//Get x position
885
	return $this->x;
886
    }
887
888
    function SetX($x) {
889
	//Set x position
890
	if ($x>=0)
891
            $this->x=$x;
892
	else
893
            $this->x=$this->w+$x;
894
    }
895
896
    function GetY() {
897
	//Get y position
898
	return $this->y;
899
    }
900
901
    function SetY($y) {
902
	//Set y position and reset x
903
	$this->x=$this->lMargin;
904
	if ($y>=0)
905
            $this->y=$y;
906
	else
907
            $this->y=$this->h+$y;
908
    }
909
910
    function SetXY($x,$y) {
911
	//Set x and y positions
912
	$this->SetY($y);
913
	$this->SetX($x);
914
    }
915
916
    function Output($name='',$dest='') {
917
	//Output PDF to some destination
918
	global $HTTP_SERVER_VARS;
919
920
	//Finish document if necessary
921
	if ($this->state<3)
922
            $this->Close();
923
	//Normalize parameters
924
	if (is_bool($dest))
925
            $dest = $dest ? 'D' : 'F';
926
	$dest = strtoupper($dest);
927
	if ($dest=='') {
928
            if ($name=='') {
929
                $name='doc.pdf';
930
                $dest='I';
931
            }
932
            else
933
                $dest='F';
934
        }
935
	switch($dest) {
936
        case 'I':
937
            //Send to standard output
938
            if (isset($HTTP_SERVER_VARS['SERVER_NAME'])) {
939
                //We send to a browser
940
                Header('Content-Type: application/pdf');
941
                if (headers_sent())
942
                    $this->Error('Some data has already been output to browser, can\'t send PDF file');
943
                Header('Content-Length: '.strlen($this->buffer));
944
                Header('Content-disposition: inline; filename='.$name);
945
            }
946
            echo $this->buffer;
947
            break;
948
        case 'D':
949
            //Download file
950
            if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) and strpos($HTTP_SERVER_VARS['HTTP_USER_AGENT'],'MSIE'))
951
                Header('Content-Type: application/force-download');
952
            else
953
                Header('Content-Type: application/octet-stream');
954
            if (headers_sent())
955
                $this->Error('Some data has already been output to browser, can\'t send PDF file');
956
            Header('Content-Length: '.strlen($this->buffer));
957
            Header('Content-disposition: attachment; filename='.$name);
958
            echo $this->buffer;
959
            break;
960
        case 'F':
961
            //Save to local file
962
            $f=fopen($name,'wb');
963
            if (!$f)
964
                $this->Error('Unable to create output file: '.$name);
965
            fwrite($f,$this->buffer,strlen($this->buffer));
966
            fclose($f);
967
            break;
968
        case 'S':
969
            //Return as a string
970
            return $this->buffer;
971
        default:
972
            $this->Error('Incorrect output destination: '.$dest);
973
        }
974
	return '';
975
    }
976
977
    /*******************************************************************************
978
     *                                                                              *
979
     *                              Protected methods                               *
980
     *                                                                              *
981
     *******************************************************************************/
982
    function _dochecks() {
983
	//Check for locale-related bug. we must have "." as comma seperator
984
	$attempts = array("C","en","en_us","English");
985
	$i = 0;
986
	while (1.1 == 1 and $i++ < count($attempts)) {
987
            setlocale(LC_NUMERIC,$attempts[$i]);
988
	}
989
	if (1.1 == 1) {
990
            $this->Error('1.1 == 1: Wrong locale with comma as dot. German? Don\'t alter the locale before including class file');
991
	}
992
	//Check for decimal separator
993
	if (sprintf('%.1f',1.0)!='1.0')
994
            setlocale(LC_NUMERIC,'C');
995
    }
996
997
    function _begindoc() {
998
	//Start document
999
	$this->state=1;
1000
	$this->_out('%PDF-1.3');
1001
    }
1002
1003
    function _putpages() {
1004
	$nb=$this->page;
1005
	if (!empty($this->AliasNbPages)) {
1006
            //Replace number of pages
1007
            for($n=1;$n<=$nb;$n++)
1008
                $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
1009
        }
1010
	if ($this->DefOrientation=='P') {
1011
            $wPt=$this->fwPt;
1012
            $hPt=$this->fhPt;
1013
        }
1014
	else
1015
            {
1016
		$wPt=$this->fhPt;
1017
		$hPt=$this->fwPt;
1018
            }
1019
	$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
1020
	for($n=1;$n<=$nb;$n++) {
1021
            //Page
1022
            $this->_newobj();
1023
            $this->_out('<</Type /Page');
1024
            $this->_out('/Parent 1 0 R');
1025
            if (isset($this->OrientationChanges[$n]))
1026
                $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
1027
            $this->_out('/Resources 2 0 R');
1028
            if (isset($this->PageLinks[$n])) {
1029
                //Links
1030
                $annots='/Annots [';
1031
                foreach($this->PageLinks[$n] as $pl) {
1032
                    $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
1033
                    $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
1034
                    if (is_string($pl[4]))
1035
                        $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
1036
                    else
1037
                        {
1038
                            $l=$this->links[$pl[4]];
1039
                            $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt;
1040
                            $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k);
1041
                        }
1042
                }
1043
                $this->_out($annots.']');
1044
            }
1045
            $this->_out('/Contents '.($this->n+1).' 0 R>>');
1046
            $this->_out('endobj');
1047
            //Page content
1048
            $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
1049
            $this->_newobj();
1050
            $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
1051
            $this->_putstream($p);
1052
            $this->_out('endobj');
1053
        }
1054
	//Pages root
1055
	$this->offsets[1]=strlen($this->buffer);
1056
	$this->_out('1 0 obj');
1057
	$this->_out('<</Type /Pages');
1058
	$kids='/Kids [';
1059
	for($i=0;$i<$nb;$i++)
1060
            $kids.=(3+2*$i).' 0 R ';
1061
	$this->_out($kids.']');
1062
	$this->_out('/Count '.$nb);
1063
	$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
1064
	$this->_out('>>');
1065
	$this->_out('endobj');
1066
    }
1067
1068
    function _putfonts() {
1069
	$nf=$this->n;
1070
	foreach($this->diffs as $diff) {
1071
            //Encodings
1072
            $this->_newobj();
1073
            $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
1074
            $this->_out('endobj');
1075
        }
1076
	$mqr=get_magic_quotes_runtime();
1077
	set_magic_quotes_runtime(0);
1078
	foreach($this->FontFiles as $file=>$info) {
1079
            //Font file embedding
1080
            $this->_newobj();
1081
            $this->FontFiles[$file]['n']=$this->n;
1082
            if (defined('FPDF_FONTPATH'))
1083
                $file=FPDF_FONTPATH.$file;
1084
            $size=filesize($file);
1085
            if (!$size)
1086
                $this->Error('Font file not found');
1087
            $this->_out('<</Length '.$size);
1088
            if (substr($file,-2)=='.z')
1089
                $this->_out('/Filter /FlateDecode');
1090
            $this->_out('/Length1 '.$info['length1']);
1091
            if (isset($info['length2']))
1092
                $this->_out('/Length2 '.$info['length2'].' /Length3 0');
1093
            $this->_out('>>');
1094
            $f=fopen($file,'rb');
1095
            $this->_putstream(fread($f,$size));
1096
            fclose($f);
1097
            $this->_out('endobj');
1098
        }
1099
	set_magic_quotes_runtime($mqr);
1100
	foreach($this->fonts as $k=>$font) {
1101
            //Font objects
1102
            $this->fonts[$k]['n']=$this->n+1;
1103
            $type=$font['type'];
1104
            $name=$font['name'];
1105
            if ($type=='core') {
1106
                //Standard font
1107
                $this->_newobj();
1108
                $this->_out('<</Type /Font');
1109
                $this->_out('/BaseFont /'.$name);
1110
                $this->_out('/Subtype /Type1');
1111
                if ($name!='Symbol' and $name!='ZapfDingbats')
1112
                    $this->_out('/Encoding /WinAnsiEncoding');
1113
                $this->_out('>>');
1114
                $this->_out('endobj');
1115
            }
1116
            elseif ($type=='Type1' or $type=='TrueType') {
1117
                //Additional Type1 or TrueType font
1118
                $this->_newobj();
1119
                $this->_out('<</Type /Font');
1120
                $this->_out('/BaseFont /'.$name);
1121
                $this->_out('/Subtype /'.$type);
1122
                $this->_out('/FirstChar 32 /LastChar 255');
1123
                $this->_out('/Widths '.($this->n+1).' 0 R');
1124
                $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
1125
                if ($font['enc']) {
1126
                    if (isset($font['diff']))
1127
                        $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
1128
                    else
1129
                        $this->_out('/Encoding /WinAnsiEncoding');
1130
                }
1131
                $this->_out('>>');
1132
                $this->_out('endobj');
1133
                //Widths
1134
                $this->_newobj();
1135
                $cw=&$font['cw'];
1136
                $s='[';
1137
                for($i=32;$i<=255;$i++)
1138
                    $s.=$cw[chr($i)].' ';
1139
                $this->_out($s.']');
1140
                $this->_out('endobj');
1141
                //Descriptor
1142
                $this->_newobj();
1143
                $s='<</Type /FontDescriptor /FontName /'.$name;
1144
                foreach($font['desc'] as $k=>$v)
1145
                    $s.=' /'.$k.' '.$v;
1146
                $file=$font['file'];
1147
                if ($file)
1148
                    $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
1149
                $this->_out($s.'>>');
1150
                $this->_out('endobj');
1151
            }
1152
            else
1153
                {
1154
                    //Allow for additional types
1155
                    $mtd='_put'.strtolower($type);
1156
                    if (!method_exists($this,$mtd))
1157
                        $this->Error('Unsupported font type: '.$type);
1158
                    $this->$mtd($font);
1159
                }
1160
        }
1161
    }
1162
1163
    function _putimages() {
1164
	$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
1165
	reset($this->images);
1166
	while(list($file,$info)=each($this->images)) {
1167
            $this->_newobj();
1168
            $this->images[$file]['n']=$this->n;
1169
            $this->_out('<</Type /XObject');
1170
            $this->_out('/Subtype /Image');
1171
            $this->_out('/Width '.$info['w']);
1172
            $this->_out('/Height '.$info['h']);
1173
            if ($info['cs']=='Indexed')
1174
                $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
1175
            else
1176
                {
1177
                    $this->_out('/ColorSpace /'.$info['cs']);
1178
                    if ($info['cs']=='DeviceCMYK')
1179
                        $this->_out('/Decode [1 0 1 0 1 0 1 0]');
1180
                }
1181
            $this->_out('/BitsPerComponent '.$info['bpc']);
1182
            $this->_out('/Filter /'.$info['f']);
1183
            if (isset($info['parms']))
1184
                $this->_out($info['parms']);
1185
            if (isset($info['trns']) and is_array($info['trns'])) {
1186
                $trns='';
1187
                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...
1188
                    $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
1189
                $this->_out('/Mask ['.$trns.']');
1190
            }
1191
            $this->_out('/Length '.strlen($info['data']).'>>');
1192
            $this->_putstream($info['data']);
1193
            unset($this->images[$file]['data']);
1194
            $this->_out('endobj');
1195
            //Palette
1196
            if ($info['cs']=='Indexed') {
1197
                $this->_newobj();
1198
                $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
1199
                $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
1200
                $this->_putstream($pal);
1201
                $this->_out('endobj');
1202
            }
1203
        }
1204
    }
1205
1206
    function _putresources() {
1207
	$this->_putfonts();
1208
	$this->_putimages();
1209
	//Resource dictionary
1210
	$this->offsets[2]=strlen($this->buffer);
1211
	$this->_out('2 0 obj');
1212
	$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
1213
	$this->_out('/Font <<');
1214
	foreach($this->fonts as $font)
1215
            $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
1216
	$this->_out('>>');
1217
	if (count($this->images)) {
1218
            $this->_out('/XObject <<');
1219
            foreach($this->images as $image)
1220
                $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
1221
            $this->_out('>>');
1222
        }
1223
	$this->_out('>>');
1224
	$this->_out('endobj');
1225
    }
1226
1227
    function _putinfo() {
1228
	if (!empty($this->producer))
1229
            $this->_out('/Producer '.$this->_textstring($this->producer));
1230
	if (!empty($this->title))
1231
            $this->_out('/Title '.$this->_textstring($this->title));
1232
	if (!empty($this->subject))
1233
            $this->_out('/Subject '.$this->_textstring($this->subject));
1234
	if (!empty($this->author))
1235
            $this->_out('/Author '.$this->_textstring($this->author));
1236
	if (!empty($this->keywords))
1237
            $this->_out('/Keywords '.$this->_textstring($this->keywords));
1238
	if (!empty($this->creator))
1239
            $this->_out('/Creator '.$this->_textstring($this->creator));
1240
	$this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
1241
    }
1242
1243
    function _putcatalog() {
1244
	$this->_out('/Type /Catalog');
1245
	$this->_out('/Pages 1 0 R');
1246
	if ($this->ZoomMode=='fullpage')
1247
            $this->_out('/OpenAction [3 0 R /Fit]');
1248
	elseif ($this->ZoomMode=='fullwidth')
1249
            $this->_out('/OpenAction [3 0 R /FitH null]');
1250
	elseif ($this->ZoomMode=='real')
1251
            $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
1252
	elseif (!is_string($this->ZoomMode))
1253
            $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
1254
	if ($this->LayoutMode=='single')
1255
            $this->_out('/PageLayout /SinglePage');
1256
	elseif ($this->LayoutMode=='continuous')
1257
            $this->_out('/PageLayout /OneColumn');
1258
	elseif ($this->LayoutMode=='two')
1259
            $this->_out('/PageLayout /TwoColumnLeft');
1260
    }
1261
1262
    function _puttrailer() {
1263
	$this->_out('/Size '.($this->n+1));
1264
	$this->_out('/Root '.$this->n.' 0 R');
1265
	$this->_out('/Info '.($this->n-1).' 0 R');
1266
    }
1267
1268
    function _enddoc() {
1269
	$this->_putpages();
1270
	$this->_putresources();
1271
	//Info
1272
	$this->_newobj();
1273
	$this->_out('<<');
1274
	$this->_putinfo();
1275
	$this->_out('>>');
1276
	$this->_out('endobj');
1277
	//Catalog
1278
	$this->_newobj();
1279
	$this->_out('<<');
1280
	$this->_putcatalog();
1281
	$this->_out('>>');
1282
	$this->_out('endobj');
1283
	//Cross-ref
1284
	$o=strlen($this->buffer);
1285
	$this->_out('xref');
1286
	$this->_out('0 '.($this->n+1));
1287
	$this->_out('0000000000 65535 f ');
1288
	for($i=1;$i<=$this->n;$i++)
1289
            $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
1290
	//Trailer
1291
	$this->_out('trailer');
1292
	$this->_out('<<');
1293
	$this->_puttrailer();
1294
	$this->_out('>>');
1295
	$this->_out('startxref');
1296
	$this->_out($o);
1297
	$this->_out('%%EOF');
1298
	$this->state=3;
1299
    }
1300
1301
    function _beginpage($orientation) {
1302
	$this->page++;
1303
	$this->pages[$this->page]='';
1304
	$this->state=2;
1305
	$this->x=$this->lMargin;
1306
	$this->y=$this->tMargin;
1307
	$this->FontFamily='';
1308
	//Page orientation
1309
	if (!$orientation)
1310
            $orientation=$this->DefOrientation;
1311
	else
1312
            {
1313
		$orientation=strtoupper($orientation{0});
1314
		if ($orientation!=$this->DefOrientation)
1315
                    $this->OrientationChanges[$this->page]=true;
1316
            }
1317
	if ($orientation!=$this->CurOrientation) {
1318
            //Change orientation
1319
            if ($orientation=='P') {
1320
                $this->wPt=$this->fwPt;
1321
                $this->hPt=$this->fhPt;
1322
                $this->w=$this->fw;
1323
                $this->h=$this->fh;
1324
            }
1325
            else
1326
                {
1327
                    $this->wPt=$this->fhPt;
1328
                    $this->hPt=$this->fwPt;
1329
                    $this->w=$this->fh;
1330
                    $this->h=$this->fw;
1331
                }
1332
            $this->PageBreakTrigger=$this->h-$this->bMargin;
1333
            $this->CurOrientation=$orientation;
1334
        }
1335
    }
1336
1337
    function _endpage() {
1338
	//End of page contents
1339
	$this->state=1;
1340
    }
1341
1342
    function _newobj() {
1343
	//Begin a new object
1344
	$this->n++;
1345
	$this->offsets[$this->n]=strlen($this->buffer);
1346
	$this->_out($this->n.' 0 obj');
1347
    }
1348
1349
    function _dounderline($x,$y,$txt) {
1350
	//Underline text
1351
	$up=$this->CurrentFont['up'];
1352
	$ut=$this->CurrentFont['ut'];
1353
	$w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
1354
	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);
1355
    }
1356
1357
    function _parsegif ($file) 
1358
    { 
1359
        //Function by J�r�me Fenal
1360
        //GIF class in pure PHP from Yamasoft (http://www.yamasoft.com/php-gif.zip)
1361
        require_once 'lib/gif.php'; 
1362
1363
        $h=0;
1364
        $w=0;
1365
        $gif = new CGIF ();
1366
1367
        if (!$gif->loadFile($file, 0))
1368
            $this->Error("GIF parser: unable to open file $file");
1369
  
1370
        if ($gif->m_img->m_gih->m_bLocalClr) {
1371
            $nColors = $gif->m_img->m_gih->m_nTableSize;
1372
            $pal = $gif->m_img->m_gih->m_colorTable->toString();
1373
            if ($bgColor != -1) {
0 ignored issues
show
Bug introduced by
The variable $bgColor seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1374
                $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
0 ignored issues
show
Bug introduced by
The variable $bgColor seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1375
            }
1376
            $colspace='Indexed';
1377
	} elseif ($gif->m_gfh->m_bGlobalClr) {
1378
            $nColors = $gif->m_gfh->m_nTableSize;
1379
            $pal = $gif->m_gfh->m_colorTable->toString();
1380
            if ($bgColor != -1) {
0 ignored issues
show
Bug introduced by
The variable $bgColor seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1381
                $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
0 ignored issues
show
Bug introduced by
The variable $bgColor seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1382
            }
1383
            $colspace='Indexed';
1384
	} else {
1385
            $nColors = 0;
1386
            $bgColor = -1;
1387
            $colspace='DeviceGray';
1388
            $pal='';
1389
	}
1390
1391
	$trns='';
1392
	if ($gif->m_img->m_bTrans && ($nColors > 0)) {
1393
            $trns=array($gif->m_img->m_nTrans);
1394
	}
1395
1396
	$data=$gif->m_img->m_data;
1397
	$w=$gif->m_gfh->m_nWidth;
1398
	$h=$gif->m_gfh->m_nHeight;
1399
1400
	if ($colspace=='Indexed' and empty($pal))
1401
            $this->Error('Missing palette in '.$file);
1402
1403
	if ($this->compress) {
1404
            $data = gzcompress($data);
1405
            return array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
1406
	} else {
1407
            return array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
1408
	} 
1409
    }
1410
1411
    function _parsejpg($file) {
1412
	//Extract info from a JPEG file
1413
	$a = GetImageSize($file);
1414
	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...
1415
            $this->Error('Missing or incorrect image file: '.$file);
1416
	if ($a[2]!=2)
1417
            $this->Error('Not a JPEG file: '.$file);
1418
	if (!isset($a['channels']) or $a['channels']==3)
1419
            $colspace='DeviceRGB';
1420
	elseif ($a['channels']==4)
1421
            $colspace='DeviceCMYK';
1422
	else
1423
            $colspace='DeviceGray';
1424
	$bpc=isset($a['bits']) ? $a['bits'] : 8;
1425
	//Read whole file
1426
	$f=fopen($file,'rb');
1427
	$data='';
1428
	while(!feof($f))
1429
            $data.=fread($f,4096);
1430
	fclose($f);
1431
	return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
1432
    }
1433
1434
    function _parsepng($file) {
1435
	//Extract info from a PNG file
1436
	$f=fopen($file,'rb');
1437
	if (!$f)
1438
            $this->Error('Can\'t open image file: '.$file);
1439
	//Check signature
1440
	if (fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
1441
            $this->Error('Not a PNG file: '.$file);
1442
	//Read header chunk
1443
	fread($f,4);
1444
	if (fread($f,4)!='IHDR')
1445
            $this->Error('Incorrect PNG file: '.$file);
1446
	$w=$this->_freadint($f);
1447
	$h=$this->_freadint($f);
1448
	$bpc=ord(fread($f,1));
1449
	if ($bpc>8)
1450
            $this->Error('16-bit depth not supported: '.$file);
1451
	$ct=ord(fread($f,1));
1452
	if ($ct==0)
1453
            $colspace='DeviceGray';
1454
	elseif ($ct==2)
1455
            $colspace='DeviceRGB';
1456
	elseif ($ct==3)
1457
            $colspace='Indexed';
1458
	else
1459
            $this->Error('Alpha channel not supported: '.$file);
1460
	if (ord(fread($f,1))!=0)
1461
            $this->Error('Unknown compression method: '.$file);
1462
	if (ord(fread($f,1))!=0)
1463
            $this->Error('Unknown filter method: '.$file);
1464
	if (ord(fread($f,1))!=0)
1465
            $this->Error('Interlacing not supported: '.$file);
1466
	fread($f,4);
1467
	$parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
1468
	//Scan chunks looking for palette, transparency and image data
1469
	$pal='';
1470
	$trns='';
1471
	$data='';
1472
	do {
1473
            $n=$this->_freadint($f);
1474
            $type=fread($f,4);
1475
            if ($type=='PLTE') {
1476
                //Read palette
1477
                $pal=fread($f,$n);
1478
                fread($f,4);
1479
            }
1480
            elseif ($type=='tRNS') {
1481
                //Read transparency info
1482
                $t=fread($f,$n);
1483
                if ($ct==0)
1484
                    $trns=array(ord(substr($t,1,1)));
1485
                elseif ($ct==2)
1486
                    $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
1487
                else {
1488
                    $pos=strpos($t,chr(0));
1489
                    if (is_int($pos))
1490
                        $trns=array($pos);
1491
                }
1492
                fread($f,4);
1493
            }
1494
            elseif ($type=='IDAT') {
1495
                //Read image data block
1496
                $data.=fread($f,$n);
1497
                fread($f,4);
1498
            }
1499
            elseif ($type=='IEND')
1500
                break;
1501
            else
1502
                fread($f,$n+4);
1503
        } while($n);
1504
	if ($colspace=='Indexed' and empty($pal))
1505
            $this->Error('Missing palette in '.$file);
1506
	fclose($f);
1507
	return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
1508
    }
1509
1510
    function _freadint($f) {
1511
	//Read a 4-byte integer from file
1512
	$i=ord(fread($f,1))<<24;
1513
	$i+=ord(fread($f,1))<<16;
1514
	$i+=ord(fread($f,1))<<8;
1515
	$i+=ord(fread($f,1));
1516
	return $i;
1517
    }
1518
1519
    function _textstring($s) {
1520
	//Format a text string
1521
	return '('.$this->_escape($s).')';
1522
    }
1523
1524
    function _escape($s) {
1525
	//Add \ before \, ( and )
1526
	return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
1527
    }
1528
1529
    function _putstream($s) {
1530
	$this->_out('stream');
1531
	$this->_out($s);
1532
	$this->_out('endstream');
1533
    }
1534
1535
    function _out($s) {
1536
	//Add a line to the document
1537
	if ($this->state == 2)
1538
            $this->pages[$this->page].=$s."\n";
1539
	else
1540
            $this->buffer.=$s."\n";
1541
    }
1542
} //End of class
1543
1544
}
1545
1546
//Handle special IE contype request
1547
if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) and 
1548
    $HTTP_SERVER_VARS['HTTP_USER_AGENT']=='contype') 
1549
{
1550
    Header('Content-Type: application/pdf');
1551
    exit;
1552
}
1553
1554
// Local Variables:
1555
// mode: php
1556
// tab-width: 8
1557
// c-basic-offset: 4
1558
// c-hanging-comment-ender-p: nil
1559
// indent-tabs-mode: nil
1560
// End:
1561
?>