Subversion Repositories Sites.tela-botanica.org

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 david 1
<?php
2
/****************************************************************************
3
* Logiciel : FPDF                                                           *
4
* Version :  1.51                                                           *
5
* Date :     03/08/2002                                                     *
6
* Auteur :   Olivier PLATHEY                                                *
7
* Licence :  Freeware                                                       *
8
*                                                                           *
9
* Vous pouvez utiliser et modifier ce logiciel comme vous le souhaitez.     *
10
****************************************************************************/
11
define('FPDF_VERSION','1.51');
12
 
13
class FPDF
14
{
15
//Private properties
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 $DefOrientation;     //default orientation
24
var $CurOrientation;     //current orientation
25
var $OrientationChanges; //array indicating orientation changes
26
var $fwPt,$fhPt;         //dimensions of page format in points
27
var $fw,$fh;             //dimensions of page format in user unit
28
var $wPt,$hPt;           //current dimensions of page in points
29
var $k;                  //scale factor (number of points in user unit)
30
var $w,$h;               //current dimensions of page in user unit
31
var $lMargin;            //left margin
32
var $tMargin;            //top margin
33
var $rMargin;            //right margin
34
var $bMargin;            //page break margin
35
var $cMargin;            //cell margin
36
var $x,$y;               //current position in user unit for cell positionning
37
var $lasth;              //height of last cell printed
38
var $LineWidth;          //line width in user unit
39
var $CoreFonts;          //array of standard font names
40
var $fonts;              //array of used fonts
41
var $FontFiles;          //array of font files
42
var $diffs;              //array of encoding differences
43
var $images;             //array of used images
44
var $PageLinks;          //array of links in pages
45
var $links;              //array of internal links
46
var $FontFamily;         //current font family
47
var $FontStyle;          //current font style
48
var $underline;          //underlining flag
49
var $CurrentFont;        //current font info
50
var $FontSizePt;         //current font size in points
51
var $FontSize;           //current font size in user unit
52
var $DrawColor;          //commands for drawing color
53
var $FillColor;          //commands for filling color
54
var $TextColor;          //commands for text color
55
var $ColorFlag;          //indicates whether fill and text colors are different
56
var $ws;                 //word spacing
57
var $AutoPageBreak;      //automatic page breaking
58
var $PageBreakTrigger;   //threshold used to trigger page breaks
59
var $InFooter;           //flag set when processing footer
60
var $ZoomMode;           //zoom display mode
61
var $LayoutMode;         //layout display mode
62
var $title;              //title
63
var $subject;            //subject
64
var $author;             //author
65
var $keywords;           //keywords
66
var $creator;            //creator
67
var $AliasNbPages;       //alias for total number of pages
68
 
69
/****************************************************************************
70
*                                                                           *
71
*                              Public methods                               *
72
*                                                                           *
73
****************************************************************************/
74
function FPDF($orientation='P',$unit='mm',$format='A4')
75
{
76
	//Check for PHP locale-related bug
77
	if(1.1==1)
78
		$this->Error('Don\'t alter the locale before including class file');
79
	//Initialization of properties
80
	$this->page=0;
81
	$this->n=2;
82
	$this->buffer='';
83
	$this->pages=array();
84
	$this->OrientationChanges=array();
85
	$this->state=0;
86
	$this->fonts=array();
87
	$this->FontFiles=array();
88
	$this->diffs=array();
89
	$this->images=array();
90
	$this->links=array();
91
	$this->InFooter=false;
92
	$this->FontFamily='';
93
	$this->FontStyle='';
94
	$this->FontSizePt=12;
95
	$this->underline=false;
96
	$this->DrawColor='0 G';
97
	$this->FillColor='0 g';
98
	$this->TextColor='0 g';
99
	$this->ColorFlag=false;
100
	$this->ws=0;
101
	//Standard fonts
102
	$this->CoreFonts['courier']='Courier';
103
	$this->CoreFonts['courierB']='Courier-Bold';
104
	$this->CoreFonts['courierI']='Courier-Oblique';
105
	$this->CoreFonts['courierBI']='Courier-BoldOblique';
106
	$this->CoreFonts['helvetica']='Helvetica';
107
	$this->CoreFonts['helveticaB']='Helvetica-Bold';
108
	$this->CoreFonts['helveticaI']='Helvetica-Oblique';
109
	$this->CoreFonts['helveticaBI']='Helvetica-BoldOblique';
110
	$this->CoreFonts['times']='Times-Roman';
111
	$this->CoreFonts['timesB']='Times-Bold';
112
	$this->CoreFonts['timesI']='Times-Italic';
113
	$this->CoreFonts['timesBI']='Times-BoldItalic';
114
	$this->CoreFonts['symbol']='Symbol';
115
	$this->CoreFonts['zapfdingbats']='ZapfDingbats';
116
	//Scale factor
117
	if($unit=='pt')
118
		$this->k=1;
119
	elseif($unit=='mm')
120
		$this->k=72/25.4;
121
	elseif($unit=='cm')
122
		$this->k=72/2.54;
123
	elseif($unit=='in')
124
		$this->k=72;
125
	else
126
		$this->Error('Incorrect unit: '.$unit);
127
	//Page format
128
	if(is_string($format))
129
	{
130
		$format=strtolower($format);
131
		if($format=='a3')
132
			$format=array(841.89,1190.55);
133
		elseif($format=='a4')
134
			$format=array(595.28,841.89);
135
		elseif($format=='a5')
136
			$format=array(420.94,595.28);
137
		elseif($format=='letter')
138
			$format=array(612,792);
139
		elseif($format=='legal')
140
			$format=array(612,1008);
141
		else
142
			$this->Error('Unknown page format: '.$format);
143
		$this->fwPt=$format[0];
144
		$this->fhPt=$format[1];
145
	}
146
	else
147
	{
148
		$this->fwPt=$format[0]*$this->k;
149
		$this->fhPt=$format[1]*$this->k;
150
	}
151
	$this->fw=$this->fwPt/$this->k;
152
	$this->fh=$this->fhPt/$this->k;
153
	//Page orientation
154
	$orientation=strtolower($orientation);
155
	if($orientation=='p' or $orientation=='portrait')
156
	{
157
		$this->DefOrientation='P';
158
		$this->wPt=$this->fwPt;
159
		$this->hPt=$this->fhPt;
160
	}
161
	elseif($orientation=='l' or $orientation=='landscape')
162
	{
163
		$this->DefOrientation='L';
164
		$this->wPt=$this->fhPt;
165
		$this->hPt=$this->fwPt;
166
	}
167
	else
168
		$this->Error('Incorrect orientation: '.$orientation);
169
	$this->CurOrientation=$this->DefOrientation;
170
	$this->w=$this->wPt/$this->k;
171
	$this->h=$this->hPt/$this->k;
172
	//Page margins (1 cm)
173
	$margin=28.35/$this->k;
174
	$this->SetMargins($margin,$margin);
175
	//Interior cell margin (1 mm)
176
	$this->cMargin=$margin/10;
177
	//Line width (0.2 mm)
178
	$this->LineWidth=.567/$this->k;
179
	//Automatic page break
180
	$this->SetAutoPageBreak(true,2*$margin);
181
	//Full width display mode
182
	$this->SetDisplayMode('fullwidth');
183
	//Compression
184
	$this->SetCompression(true);
185
}
186
 
187
function SetMargins($left,$top,$right=-1)
188
{
189
	//Set left, top and right margins
190
	$this->lMargin=$left;
191
	$this->tMargin=$top;
192
	if($right==-1)
193
		$right=$left;
194
	$this->rMargin=$right;
195
}
196
 
197
function SetLeftMargin($margin)
198
{
199
	//Set left margin
200
	$this->lMargin=$margin;
201
	if($this->page>0 and $this->x<$margin)
202
		$this->x=$margin;
203
}
204
 
205
function SetTopMargin($margin)
206
{
207
	//Set top margin
208
	$this->tMargin=$margin;
209
}
210
 
211
function SetRightMargin($margin)
212
{
213
	//Set right margin
214
	$this->rMargin=$margin;
215
}
216
 
217
function SetAutoPageBreak($auto,$margin=0)
218
{
219
	//Set auto page break mode and triggering margin
220
	$this->AutoPageBreak=$auto;
221
	$this->bMargin=$margin;
222
	$this->PageBreakTrigger=$this->h-$margin;
223
}
224
 
225
function SetDisplayMode($zoom,$layout='continuous')
226
{
227
	//Set display mode in viewer
228
	if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
229
		$this->ZoomMode=$zoom;
230
	elseif($zoom=='zoom')
231
		$this->ZoomMode=$layout;
232
	else
233
		$this->Error('Incorrect zoom display mode: '.$zoom);
234
	if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='default')
235
		$this->LayoutMode=$layout;
236
	elseif($zoom!='zoom')
237
		$this->Error('Incorrect layout display mode: '.$layout);
238
}
239
 
240
function SetCompression($compress)
241
{
242
	//Set page compression
243
	if(function_exists('gzcompress'))
244
		$this->compress=$compress;
245
	else
246
		$this->compress=false;
247
}
248
 
249
function SetTitle($title)
250
{
251
	//Title of document
252
	$this->title=$title;
253
}
254
 
255
function SetSubject($subject)
256
{
257
	//Subject of document
258
	$this->subject=$subject;
259
}
260
 
261
function SetAuthor($author)
262
{
263
	//Author of document
264
	$this->author=$author;
265
}
266
 
267
function SetKeywords($keywords)
268
{
269
	//Keywords of document
270
	$this->keywords=$keywords;
271
}
272
 
273
function SetCreator($creator)
274
{
275
	//Creator of document
276
	$this->creator=$creator;
277
}
278
 
279
function AliasNbPages($alias='{nb}')
280
{
281
	//Define an alias for total number of pages
282
	$this->AliasNbPages=$alias;
283
}
284
 
285
function Error($msg)
286
{
287
	//Fatal error
288
	die('<B>FPDF error: </B>'.$msg);
289
}
290
 
291
function Open()
292
{
293
	//Begin document
294
	$this->_begindoc();
295
}
296
 
297
function Close()
298
{
299
	//Terminate document
300
	if($this->page==0)
301
		$this->AddPage();
302
	//Page footer
303
	$this->InFooter=true;
304
	$this->Footer();
305
	$this->InFooter=false;
306
	//Close page
307
	$this->_endpage();
308
	//Close document
309
	$this->_enddoc();
310
}
311
 
312
function AddPage($orientation='')
313
{
314
	//Start a new page
315
	$family=$this->FontFamily;
316
	$style=$this->FontStyle.($this->underline ? 'U' : '');
317
	$size=$this->FontSizePt;
318
	$lw=$this->LineWidth;
319
	$dc=$this->DrawColor;
320
	$fc=$this->FillColor;
321
	$tc=$this->TextColor;
322
	$cf=$this->ColorFlag;
323
	if($this->page>0)
324
	{
325
		//Page footer
326
		$this->InFooter=true;
327
		$this->Footer();
328
		$this->InFooter=false;
329
		//Close page
330
		$this->_endpage();
331
	}
332
	//Start new page
333
	$this->_beginpage($orientation);
334
	//Set line cap style to square
335
	$this->_out('2 J');
336
	//Set line width
337
	$this->LineWidth=$lw;
338
	$this->_out(sprintf('%.2f w',$lw*$this->k));
339
	//Set font
340
	if($family)
341
		$this->SetFont($family,$style,$size);
342
	//Set colors
343
	$this->DrawColor=$dc;
344
	if($dc!='0 G')
345
		$this->_out($dc);
346
	$this->FillColor=$fc;
347
	if($fc!='0 g')
348
		$this->_out($fc);
349
	$this->TextColor=$tc;
350
	$this->ColorFlag=$cf;
351
	//Page header
352
	$this->Header();
353
	//Restore line width
354
	if($this->LineWidth!=$lw)
355
	{
356
		$this->LineWidth=$lw;
357
		$this->_out(sprintf('%.2f w',$lw*$this->k));
358
	}
359
	//Restore font
360
	if($family)
361
		$this->SetFont($family,$style,$size);
362
	//Restore colors
363
	if($this->DrawColor!=$dc)
364
	{
365
		$this->DrawColor=$dc;
366
		$this->_out($dc);
367
	}
368
	if($this->FillColor!=$fc)
369
	{
370
		$this->FillColor=$fc;
371
		$this->_out($fc);
372
	}
373
	$this->TextColor=$tc;
374
	$this->ColorFlag=$cf;
375
}
376
 
377
function Header()
378
{
379
	//To be implemented in your own inherited class
380
}
381
 
382
function Footer()
383
{
384
	//To be implemented in your own inherited class
385
}
386
 
387
function PageNo()
388
{
389
	//Get current page number
390
	return $this->page;
391
}
392
 
393
function SetDrawColor($r,$g=-1,$b=-1)
394
{
395
	//Set color for all stroking operations
396
	if(($r==0 and $g==0 and $b==0) or $g==-1)
397
		$this->DrawColor=sprintf('%.3f G',$r/255);
398
	else
399
		$this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
400
	if($this->page>0)
401
		$this->_out($this->DrawColor);
402
}
403
 
404
function SetFillColor($r,$g=-1,$b=-1)
405
{
406
	//Set color for all filling operations
407
	if(($r==0 and $g==0 and $b==0) or $g==-1)
408
		$this->FillColor=sprintf('%.3f g',$r/255);
409
	else
410
		$this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
411
	$this->ColorFlag=($this->FillColor!=$this->TextColor);
412
	if($this->page>0)
413
		$this->_out($this->FillColor);
414
}
415
 
416
function SetTextColor($r,$g=-1,$b=-1)
417
{
418
	//Set color for text
419
	if(($r==0 and $g==0 and $b==0) or $g==-1)
420
		$this->TextColor=sprintf('%.3f g',$r/255);
421
	else
422
		$this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
423
	$this->ColorFlag=($this->FillColor!=$this->TextColor);
424
}
425
 
426
function GetStringWidth($s)
427
{
428
	//Get width of a string in the current font
429
	$s=(string)$s;
430
	$cw=&$this->CurrentFont['cw'];
431
	$w=0;
432
	$l=strlen($s);
433
	for($i=0;$i<$l;$i++)
434
		$w+=$cw[$s{$i}];
435
	return $w*$this->FontSize/1000;
436
}
437
 
438
function SetLineWidth($width)
439
{
440
	//Set line width
441
	$this->LineWidth=$width;
442
	if($this->page>0)
443
		$this->_out(sprintf('%.2f w',$width*$this->k));
444
}
445
 
446
function Line($x1,$y1,$x2,$y2)
447
{
448
	//Draw a line
449
	$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));
450
}
451
 
452
function Rect($x,$y,$w,$h,$style='')
453
{
454
	//Draw a rectangle
455
	if($style=='F')
456
		$op='f';
457
	elseif($style=='FD' or $style=='DF')
458
		$op='B';
459
	else
460
		$op='S';
461
	$this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
462
}
463
 
464
function AddFont($family,$style='',$file='')
465
{
466
	//Add a TrueType or Type1 font
467
	$family=strtolower($family);
468
	if($family=='arial')
469
		$family='helvetica';
470
	$style=strtoupper($style);
471
	if($style=='IB')
472
		$style='BI';
473
	if(isset($this->fonts[$family.$style]))
474
		$this->Error('Font already added: '.$family.' '.$style);
475
	if($file=='')
476
		$file=str_replace(' ','',$family).strtolower($style).'.php';
477
	if(defined('FPDF_FONTPATH'))
478
		$file=FPDF_FONTPATH.$file;
479
	include($file);
480
	if(!isset($name))
481
		$this->Error('Could not include font definition file');
482
	$i=count($this->fonts)+1;
483
	$this->fonts[$family.$style]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file);
484
	if($diff)
485
	{
486
		//Search existing encodings
487
		$d=0;
488
		$nb=count($this->diffs);
489
		for($i=1;$i<=$nb;$i++)
490
			if($this->diffs[$i]==$diff)
491
			{
492
				$d=$i;
493
				break;
494
			}
495
		if($d==0)
496
		{
497
			$d=$nb+1;
498
			$this->diffs[$d]=$diff;
499
		}
500
		$this->fonts[$family.$style]['diff']=$d;
501
	}
502
	if($file)
503
	{
504
		if($type=='TrueType')
505
			$this->FontFiles[$file]=array('length1'=>$originalsize);
506
		else
507
			$this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
508
	}
509
}
510
 
511
function SetFont($family,$style='',$size=0)
512
{
513
	//Select a font; size given in points
514
	global $fpdf_charwidths;
515
 
516
	$family=strtolower($family);
517
	if($family=='')
518
		$family=$this->FontFamily;
519
	if($family=='arial')
520
		$family='helvetica';
521
	elseif($family=='symbol' or $family=='zapfdingbats')
522
		$style='';
523
	$style=strtoupper($style);
524
	if(is_int(strpos($style,'U')))
525
	{
526
		$this->underline=true;
527
		$style=str_replace('U','',$style);
528
	}
529
	else
530
		$this->underline=false;
531
	if($style=='IB')
532
		$style='BI';
533
	if($size==0)
534
		$size=$this->FontSizePt;
535
	//Test if font is already selected
536
	if($this->FontFamily==$family and $this->FontStyle==$style and $this->FontSizePt==$size)
537
		return;
538
	//Test if used for the first time
539
	$fontkey=$family.$style;
540
	if(!isset($this->fonts[$fontkey]))
541
	{
542
		//Check if one of the standard fonts
543
		if(isset($this->CoreFonts[$fontkey]))
544
		{
545
			if(!isset($fpdf_charwidths[$fontkey]))
546
			{
547
				//Load metric file
548
				$file=$family;
549
				if($family=='times' or $family=='helvetica')
550
					$file.=strtolower($style);
551
				$file.='.php';
552
				if(defined('FPDF_FONTPATH'))
553
					$file=FPDF_FONTPATH.$file;
554
				include($file);
555
				if(!isset($fpdf_charwidths[$fontkey]))
556
					$this->Error('Could not include font metric file');
557
			}
558
			$i=count($this->fonts)+1;
559
			$this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]);
560
		}
561
		else
562
			$this->Error('Undefined font: '.$family.' '.$style);
563
	}
564
	//Select it
565
	$this->FontFamily=$family;
566
	$this->FontStyle=$style;
567
	$this->FontSizePt=$size;
568
	$this->FontSize=$size/$this->k;
569
	$this->CurrentFont=&$this->fonts[$fontkey];
570
	if($this->page>0)
571
		$this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
572
}
573
 
574
function SetFontSize($size)
575
{
576
	//Set font size in points
577
	if($this->FontSizePt==$size)
578
		return;
579
	$this->FontSizePt=$size;
580
	$this->FontSize=$size/$this->k;
581
	if($this->page>0)
582
		$this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
583
}
584
 
585
function AddLink()
586
{
587
	//Create a new internal link
588
	$n=count($this->links)+1;
589
	$this->links[$n]=array(0,0);
590
	return $n;
591
}
592
 
593
function SetLink($link,$y=0,$page=-1)
594
{
595
	//Set destination of internal link
596
	if($y==-1)
597
		$y=$this->y;
598
	if($page==-1)
599
		$page=$this->page;
600
	$this->links[$link]=array($page,$y);
601
}
602
 
603
function Link($x,$y,$w,$h,$link)
604
{
605
	//Put a link on the page
606
	$this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
607
}
608
 
609
function Text($x,$y,$txt)
610
{
611
	//Output a string
612
	$txt=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
613
	$s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$txt);
614
	if($this->underline and $txt!='')
615
		$s.=' '.$this->_dounderline($x,$y,$txt);
616
	if($this->ColorFlag)
617
		$s='q '.$this->TextColor.' '.$s.' Q';
618
	$this->_out($s);
619
}
620
 
621
function AcceptPageBreak()
622
{
623
	//Accept automatic page break or not
624
	return $this->AutoPageBreak;
625
}
626
 
627
function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
628
{
629
	//Output a cell
630
	$k=$this->k;
631
	if($this->y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak())
632
	{
633
		$x=$this->x;
634
		$ws=$this->ws;
635
		if($ws>0)
636
		{
637
			$this->ws=0;
638
			$this->_out('0 Tw');
639
		}
640
		$this->AddPage($this->CurOrientation);
641
		$this->x=$x;
642
		if($ws>0)
643
		{
644
			$this->ws=$ws;
645
			$this->_out(sprintf('%.3f Tw',$ws*$k));
646
		}
647
	}
648
	if($w==0)
649
		$w=$this->w-$this->rMargin-$this->x;
650
	$s='';
651
	if($fill==1 or $border==1)
652
	{
653
		if($fill==1)
654
			$op=($border==1) ? 'B' : 'f';
655
		else
656
			$op='S';
657
		$s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
658
	}
659
	if(is_string($border))
660
	{
661
		$x=$this->x;
662
		$y=$this->y;
663
		if(is_int(strpos($border,'L')))
664
			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
665
		if(is_int(strpos($border,'T')))
666
			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
667
		if(is_int(strpos($border,'R')))
668
			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
669
		if(is_int(strpos($border,'B')))
670
			$s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
671
	}
672
	if($txt!='')
673
	{
674
		if($align=='R')
675
			$dx=$w-$this->cMargin-$this->GetStringWidth($txt);
676
		elseif($align=='C')
677
			$dx=($w-$this->GetStringWidth($txt))/2;
678
		else
679
			$dx=$this->cMargin;
680
		$txt=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
681
		if($this->ColorFlag)
682
			$s.='q '.$this->TextColor.' ';
683
		$s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt);
684
		if($this->underline)
685
			$s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
686
		if($this->ColorFlag)
687
			$s.=' Q';
688
		if($link)
689
			$this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
690
	}
691
	if($s)
692
		$this->_out($s);
693
	$this->lasth=$h;
694
	if($ln>0)
695
	{
696
		//Go to next line
697
		$this->y+=$h;
698
		if($ln==1)
699
			$this->x=$this->lMargin;
700
	}
701
	else
702
		$this->x+=$w;
703
}
704
 
705
function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0)
706
{
707
	//Output text with automatic or explicit line breaks
708
	$cw=&$this->CurrentFont['cw'];
709
	if($w==0)
710
		$w=$this->w-$this->rMargin-$this->x;
711
	$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
712
	$s=str_replace("\r",'',$txt);
713
	$nb=strlen($s);
714
	if($nb>0 and $s[$nb-1]=="\n")
715
		$nb--;
716
	$b=0;
717
	if($border)
718
	{
719
		if($border==1)
720
		{
721
			$border='LTRB';
722
			$b='LRT';
723
			$b2='LR';
724
		}
725
		else
726
		{
727
			$b2='';
728
			if(is_int(strpos($border,'L')))
729
				$b2.='L';
730
			if(is_int(strpos($border,'R')))
731
				$b2.='R';
732
			$b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
733
		}
734
	}
735
	$sep=-1;
736
	$i=0;
737
	$j=0;
738
	$l=0;
739
	$ns=0;
740
	$nl=1;
741
	while($i<$nb)
742
	{
743
		//Get next character
744
		$c=$s[$i];
745
		if($c=="\n")
746
		{
747
			//Explicit line break
748
			if($this->ws>0)
749
			{
750
				$this->ws=0;
751
				$this->_out('0 Tw');
752
			}
753
			$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
754
			$i++;
755
			$sep=-1;
756
			$j=$i;
757
			$l=0;
758
			$ns=0;
759
			$nl++;
760
			if($border and $nl==2)
761
				$b=$b2;
762
			continue;
763
		}
764
		if($c==' ')
765
		{
766
			$sep=$i;
767
			$ls=$l;
768
			$ns++;
769
		}
770
		$l+=$cw[$c];
771
		if($l>$wmax)
772
		{
773
			//Automatic line break
774
			if($sep==-1)
775
			{
776
				if($i==$j)
777
					$i++;
778
				if($this->ws>0)
779
				{
780
					$this->ws=0;
781
					$this->_out('0 Tw');
782
				}
783
				$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
784
			}
785
			else
786
			{
787
				if($align=='J')
788
				{
789
					$this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
790
					$this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
791
				}
792
				$this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
793
				$i=$sep+1;
794
			}
795
			$sep=-1;
796
			$j=$i;
797
			$l=0;
798
			$ns=0;
799
			$nl++;
800
			if($border and $nl==2)
801
				$b=$b2;
802
		}
803
		else
804
			$i++;
805
	}
806
	//Last chunk
807
	if($this->ws>0)
808
	{
809
		$this->ws=0;
810
		$this->_out('0 Tw');
811
	}
812
	if($border and is_int(strpos($border,'B')))
813
		$b.='B';
814
	$this->Cell($w,$h,substr($s,$j,$i),$b,2,$align,$fill);
815
	$this->x=$this->lMargin;
816
}
817
 
818
function Write($h,$txt,$link='')
819
{
820
	//Output text in flowing mode
821
	$cw=&$this->CurrentFont['cw'];
822
	$w=$this->w-$this->rMargin-$this->x;
823
	$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
824
	$s=str_replace("\r",'',$txt);
825
	$nb=strlen($s);
826
	$sep=-1;
827
	$i=0;
828
	$j=0;
829
	$l=0;
830
	$nl=1;
831
	while($i<$nb)
832
	{
833
		//Get next character
834
		$c=$s{$i};
835
		if($c=="\n")
836
		{
837
			//Explicit line break
838
			$this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
839
			$i++;
840
			$sep=-1;
841
			$j=$i;
842
			$l=0;
843
			if($nl==1)
844
			{
845
				$this->x=$this->lMargin;
846
				$w=$this->w-$this->rMargin-$this->x;
847
				$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
848
			}
849
			$nl++;
850
			continue;
851
		}
852
		if($c==' ')
853
		{
854
			$sep=$i;
855
			$ls=$l;
856
		}
857
		$l+=$cw[$c];
858
		if($l>$wmax)
859
		{
860
			//Automatic line break
861
			if($sep==-1)
862
			{
863
				if($this->x>$this->lMargin)
864
				{
865
					//Move to next line
866
					$this->x=$this->lMargin;
867
					$this->y+=$h;
868
					$w=$this->w-$this->rMargin-$this->x;
869
					$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
870
					$i++;
871
					$nl++;
872
					continue;
873
				}
874
				if($i==$j)
875
					$i++;
876
				$this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
877
			}
878
			else
879
			{
880
				$this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
881
				$i=$sep+1;
882
			}
883
			$sep=-1;
884
			$j=$i;
885
			$l=0;
886
			if($nl==1)
887
			{
888
				$this->x=$this->lMargin;
889
				$w=$this->w-$this->rMargin-$this->x;
890
				$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
891
			}
892
			$nl++;
893
		}
894
		else
895
			$i++;
896
	}
897
	//Last chunk
898
	if($i!=$j)
899
		$this->Cell($l/1000*$this->FontSize,$h,substr($s,$j,$i),0,0,'',0,$link);
900
}
901
 
902
function Image($file,$x,$y,$w,$h=0,$type='',$link='')
903
{
904
	//Put an image on the page
905
	if(!isset($this->images[$file]))
906
	{
907
		//First use of image, get info
908
		if($type=='')
909
		{
910
			$pos=strrpos($file,'.');
911
			if(!$pos)
912
				$this->Error('Image file has no extension and no type was specified: '.$file);
913
			$type=substr($file,$pos+1);
914
		}
915
		$type=strtolower($type);
916
		$mqr=get_magic_quotes_runtime();
917
		set_magic_quotes_runtime(0);
918
		if($type=='jpg' or $type=='jpeg')
919
			$info=$this->_parsejpg($file);
920
		elseif($type=='png')
921
			$info=$this->_parsepng($file);
922
		else
923
			$this->Error('Unsupported image file type: '.$type);
924
		set_magic_quotes_runtime($mqr);
925
		$info['i']=count($this->images)+1;
926
		$this->images[$file]=$info;
927
	}
928
	else
929
		$info=$this->images[$file];
930
	//Automatic width or height calculation
931
	if($w==0)
932
		$w=$h*$info['w']/$info['h'];
933
	if($h==0)
934
		$h=$w*$info['h']/$info['w'];
935
	$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']));
936
	if($link)
937
		$this->Link($x,$y,$w,$h,$link);
938
}
939
 
940
function Ln($h='')
941
{
942
	//Line feed; default value is last cell height
943
	$this->x=$this->lMargin;
944
	if(is_string($h))
945
		$this->y+=$this->lasth;
946
	else
947
		$this->y+=$h;
948
}
949
 
950
function GetX()
951
{
952
	//Get x position
953
	return $this->x;
954
}
955
 
956
function SetX($x)
957
{
958
	//Set x position
959
	if($x>=0)
960
		$this->x=$x;
961
	else
962
		$this->x=$this->w+$x;
963
}
964
 
965
function GetY()
966
{
967
	//Get y position
968
	return $this->y;
969
}
970
 
971
function SetY($y)
972
{
973
	//Set y position and reset x
974
	$this->x=$this->lMargin;
975
	if($y>=0)
976
		$this->y=$y;
977
	else
978
		$this->y=$this->h+$y;
979
}
980
 
981
function SetXY($x,$y)
982
{
983
	//Set x and y positions
984
	$this->SetY($y);
985
	$this->SetX($x);
986
}
987
 
988
function Output($file='',$download=false)
989
{
990
	//Output PDF to file or browser
991
	global $HTTP_ENV_VARS;
992
 
993
	if($this->state<3)
994
		$this->Close();
995
	if($file=='')
996
	{
997
		//Send to browser
998
		Header('Content-Type: application/pdf');
999
		if(headers_sent())
1000
			$this->Error('Some data has already been output to browser, can\'t send PDF file');
1001
		Header('Content-Length: '.strlen($this->buffer));
1002
		Header('Content-disposition: inline; filename=doc.pdf');
1003
		echo $this->buffer;
1004
	}
1005
	else
1006
	{
1007
		if($download)
1008
		{
1009
			//Download file
1010
			if(isset($HTTP_ENV_VARS['HTTP_USER_AGENT']) and strpos($HTTP_ENV_VARS['HTTP_USER_AGENT'],'MSIE 5.5'))
1011
				Header('Content-Type: application/dummy');
1012
			else
1013
				Header('Content-Type: application/octet-stream');
1014
			if(headers_sent())
1015
				$this->Error('Some data has already been output to browser, can\'t send PDF file');
1016
			Header('Content-Length: '.strlen($this->buffer));
1017
			Header('Content-disposition: attachment; filename='.$file);
1018
			echo $this->buffer;
1019
		}
1020
		else
1021
		{
1022
			//Save file locally
1023
			$f=fopen($file,'wb');
1024
			if(!$f)
1025
				$this->Error('Unable to create output file: '.$file);
1026
			fwrite($f,$this->buffer,strlen($this->buffer));
1027
			fclose($f);
1028
		}
1029
	}
1030
}
1031
 
1032
/****************************************************************************
1033
*                                                                           *
1034
*                              Private methods                              *
1035
*                                                                           *
1036
****************************************************************************/
1037
function _begindoc()
1038
{
1039
	//Start document
1040
	$this->state=1;
1041
	$this->_out('%PDF-1.3');
1042
}
1043
 
1044
function _putpages()
1045
{
1046
	$nb=$this->page;
1047
	if(!empty($this->AliasNbPages))
1048
	{
1049
		//Replace number of pages
1050
		for($n=1;$n<=$nb;$n++)
1051
			$this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
1052
	}
1053
	if($this->DefOrientation=='P')
1054
	{
1055
		$wPt=$this->fwPt;
1056
		$hPt=$this->fhPt;
1057
	}
1058
	else
1059
	{
1060
		$wPt=$this->fhPt;
1061
		$hPt=$this->fwPt;
1062
	}
1063
	$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
1064
	for($n=1;$n<=$nb;$n++)
1065
	{
1066
		//Page
1067
		$this->_newobj();
1068
		$this->_out('<</Type /Page');
1069
		$this->_out('/Parent 1 0 R');
1070
		if(isset($this->OrientationChanges[$n]))
1071
			$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
1072
		$this->_out('/Resources 2 0 R');
1073
		if(isset($this->PageLinks[$n]))
1074
		{
1075
			//Links
1076
			$annots='/Annots [';
1077
			foreach($this->PageLinks[$n] as $pl)
1078
			{
1079
				$rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
1080
				$annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
1081
				if(is_string($pl[4]))
1082
					$annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
1083
				else
1084
				{
1085
					$l=$this->links[$pl[4]];
1086
					$h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt;
1087
					$annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k);
1088
				}
1089
			}
1090
			$this->_out($annots.']');
1091
		}
1092
		$this->_out('/Contents '.($this->n+1).' 0 R>>');
1093
		$this->_out('endobj');
1094
		//Page content
1095
		$p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
1096
		$this->_newobj();
1097
		$this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
1098
		$this->_putstream($p);
1099
		$this->_out('endobj');
1100
	}
1101
	//Pages root
1102
	$this->offsets[1]=strlen($this->buffer);
1103
	$this->_out('1 0 obj');
1104
	$this->_out('<</Type /Pages');
1105
	$kids='/Kids [';
1106
	for($i=0;$i<$nb;$i++)
1107
		$kids.=(3+2*$i).' 0 R ';
1108
	$this->_out($kids.']');
1109
	$this->_out('/Count '.$nb);
1110
	$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
1111
	$this->_out('>>');
1112
	$this->_out('endobj');
1113
}
1114
 
1115
function _putfonts()
1116
{
1117
	$nf=$this->n;
1118
	foreach($this->diffs as $diff)
1119
	{
1120
		//Encodings
1121
		$this->_newobj();
1122
		$this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
1123
		$this->_out('endobj');
1124
	}
1125
	$mqr=get_magic_quotes_runtime();
1126
	set_magic_quotes_runtime(0);
1127
	foreach($this->FontFiles as $file=>$info)
1128
	{
1129
		//Font file embedding
1130
		$this->_newobj();
1131
		$this->FontFiles[$file]['n']=$this->n;
1132
		if(defined('FPDF_FONTPATH'))
1133
			$file=FPDF_FONTPATH.$file;
1134
		$size=filesize($file);
1135
		if(!$size)
1136
			$this->Error('Font file not found');
1137
		$this->_out('<</Length '.$size);
1138
		if(substr($file,-2)=='.z')
1139
			$this->_out('/Filter /FlateDecode');
1140
		$this->_out('/Length1 '.$info['length1']);
1141
		if(isset($info['length2']))
1142
			$this->_out('/Length2 '.$info['length2'].' /Length3 0');
1143
		$this->_out('>>');
1144
		$f=fopen($file,'rb');
1145
		$this->_putstream(fread($f,$size));
1146
		fclose($f);
1147
		$this->_out('endobj');
1148
	}
1149
	set_magic_quotes_runtime($mqr);
1150
	foreach($this->fonts as $k=>$font)
1151
	{
1152
		//Font objects
1153
		$this->_newobj();
1154
		$this->fonts[$k]['n']=$this->n;
1155
		$name=$font['name'];
1156
		$this->_out('<</Type /Font');
1157
		$this->_out('/BaseFont /'.$name);
1158
		if($font['type']=='core')
1159
		{
1160
			//Standard font
1161
			$this->_out('/Subtype /Type1');
1162
			if($name!='Symbol' and $name!='ZapfDingbats')
1163
				$this->_out('/Encoding /WinAnsiEncoding');
1164
		}
1165
		else
1166
		{
1167
			//Additional font
1168
			$this->_out('/Subtype /'.$font['type']);
1169
			$this->_out('/FirstChar 32');
1170
			$this->_out('/LastChar 255');
1171
			$this->_out('/Widths '.($this->n+1).' 0 R');
1172
			$this->_out('/FontDescriptor '.($this->n+2).' 0 R');
1173
			if($font['enc'])
1174
			{
1175
				if(isset($font['diff']))
1176
					$this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
1177
				else
1178
					$this->_out('/Encoding /WinAnsiEncoding');
1179
			}
1180
		}
1181
		$this->_out('>>');
1182
		$this->_out('endobj');
1183
		if($font['type']!='core')
1184
		{
1185
			//Widths
1186
			$this->_newobj();
1187
			$cw=&$font['cw'];
1188
			$s='[';
1189
			for($i=32;$i<=255;$i++)
1190
				$s.=$cw[chr($i)].' ';
1191
			$this->_out($s.']');
1192
			$this->_out('endobj');
1193
			//Descriptor
1194
			$this->_newobj();
1195
			$s='<</Type /FontDescriptor /FontName /'.$name;
1196
			foreach($font['desc'] as $k=>$v)
1197
				$s.=' /'.$k.' '.$v;
1198
			$file=$font['file'];
1199
			if($file)
1200
				$s.=' /FontFile'.($font['type']=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
1201
			$this->_out($s.'>>');
1202
			$this->_out('endobj');
1203
		}
1204
	}
1205
}
1206
 
1207
function _putimages()
1208
{
1209
	$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
1210
	foreach($this->images as $file=>$info)
1211
	{
1212
		$this->_newobj();
1213
		$this->images[$file]['n']=$this->n;
1214
		$this->_out('<</Type /XObject');
1215
		$this->_out('/Subtype /Image');
1216
		$this->_out('/Width '.$info['w']);
1217
		$this->_out('/Height '.$info['h']);
1218
		if($info['cs']=='Indexed')
1219
			$this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
1220
		else
1221
		{
1222
			$this->_out('/ColorSpace /'.$info['cs']);
1223
			if($info['cs']=='DeviceCMYK')
1224
				$this->_out('/Decode [1 0 1 0 1 0 1 0]');
1225
		}
1226
		$this->_out('/BitsPerComponent '.$info['bpc']);
1227
		$this->_out('/Filter /'.$info['f']);
1228
		if(isset($info['parms']))
1229
			$this->_out($info['parms']);
1230
		if(isset($info['trns']) and is_array($info['trns']))
1231
		{
1232
			$trns='';
1233
			for($i=0;$i<count($info['trns']);$i++)
1234
				$trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
1235
			$this->_out('/Mask ['.$trns.']');
1236
		}
1237
		$this->_out('/Length '.strlen($info['data']).'>>');
1238
		$this->_putstream($info['data']);
1239
		$this->_out('endobj');
1240
		//Palette
1241
		if($info['cs']=='Indexed')
1242
		{
1243
			$this->_newobj();
1244
			$pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
1245
			$this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
1246
			$this->_putstream($pal);
1247
			$this->_out('endobj');
1248
		}
1249
	}
1250
}
1251
 
1252
function _putresources()
1253
{
1254
	$this->_putfonts();
1255
	$this->_putimages();
1256
	//Resource dictionary
1257
	$this->offsets[2]=strlen($this->buffer);
1258
	$this->_out('2 0 obj');
1259
	$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
1260
	$this->_out('/Font <<');
1261
	foreach($this->fonts as $font)
1262
		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
1263
	$this->_out('>>');
1264
	if(count($this->images))
1265
	{
1266
		$this->_out('/XObject <<');
1267
		foreach($this->images as $image)
1268
			$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
1269
		$this->_out('>>');
1270
	}
1271
	$this->_out('>>');
1272
	$this->_out('endobj');
1273
}
1274
 
1275
function _putinfo()
1276
{
1277
	$this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
1278
	if(!empty($this->title))
1279
		$this->_out('/Title '.$this->_textstring($this->title));
1280
	if(!empty($this->subject))
1281
		$this->_out('/Subject '.$this->_textstring($this->subject));
1282
	if(!empty($this->author))
1283
		$this->_out('/Author '.$this->_textstring($this->author));
1284
	if(!empty($this->keywords))
1285
		$this->_out('/Keywords '.$this->_textstring($this->keywords));
1286
	if(!empty($this->creator))
1287
		$this->_out('/Creator '.$this->_textstring($this->creator));
1288
	$this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
1289
}
1290
 
1291
function _putcatalog()
1292
{
1293
	$this->_out('/Type /Catalog');
1294
	$this->_out('/Pages 1 0 R');
1295
	if($this->ZoomMode=='fullpage')
1296
		$this->_out('/OpenAction [3 0 R /Fit]');
1297
	elseif($this->ZoomMode=='fullwidth')
1298
		$this->_out('/OpenAction [3 0 R /FitH null]');
1299
	elseif($this->ZoomMode=='real')
1300
		$this->_out('/OpenAction [3 0 R /XYZ null null 1]');
1301
	elseif(!is_string($this->ZoomMode))
1302
		$this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
1303
	if($this->LayoutMode=='single')
1304
		$this->_out('/PageLayout /SinglePage');
1305
	elseif($this->LayoutMode=='continuous')
1306
		$this->_out('/PageLayout /OneColumn');
1307
	elseif($this->LayoutMode=='two')
1308
		$this->_out('/PageLayout /TwoColumnLeft');
1309
}
1310
 
1311
function _puttrailer()
1312
{
1313
	$this->_out('/Size '.($this->n+1));
1314
	$this->_out('/Root '.$this->n.' 0 R');
1315
	$this->_out('/Info '.($this->n-1).' 0 R');
1316
}
1317
 
1318
function _enddoc()
1319
{
1320
	$this->_putpages();
1321
	$this->_putresources();
1322
	//Info
1323
	$this->_newobj();
1324
	$this->_out('<<');
1325
	$this->_putinfo();
1326
	$this->_out('>>');
1327
	$this->_out('endobj');
1328
	//Catalog
1329
	$this->_newobj();
1330
	$this->_out('<<');
1331
	$this->_putcatalog();
1332
	$this->_out('>>');
1333
	$this->_out('endobj');
1334
	//Cross-ref
1335
	$o=strlen($this->buffer);
1336
	$this->_out('xref');
1337
	$this->_out('0 '.($this->n+1));
1338
	$this->_out('0000000000 65535 f ');
1339
	for($i=1;$i<=$this->n;$i++)
1340
		$this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
1341
	//Trailer
1342
	$this->_out('trailer');
1343
	$this->_out('<<');
1344
	$this->_puttrailer();
1345
	$this->_out('>>');
1346
	$this->_out('startxref');
1347
	$this->_out($o);
1348
	$this->_out('%%EOF');
1349
	$this->state=3;
1350
}
1351
 
1352
function _beginpage($orientation)
1353
{
1354
	$this->page++;
1355
	$this->pages[$this->page]='';
1356
	$this->state=2;
1357
	$this->x=$this->lMargin;
1358
	$this->y=$this->tMargin;
1359
	$this->lasth=0;
1360
	$this->FontFamily='';
1361
	//Page orientation
1362
	if(!$orientation)
1363
		$orientation=$this->DefOrientation;
1364
	else
1365
	{
1366
		$orientation=strtoupper($orientation{0});
1367
		if($orientation!=$this->DefOrientation)
1368
			$this->OrientationChanges[$this->page]=true;
1369
	}
1370
	if($orientation!=$this->CurOrientation)
1371
	{
1372
		//Change orientation
1373
		if($orientation=='P')
1374
		{
1375
			$this->wPt=$this->fwPt;
1376
			$this->hPt=$this->fhPt;
1377
			$this->w=$this->fw;
1378
			$this->h=$this->fh;
1379
		}
1380
		else
1381
		{
1382
			$this->wPt=$this->fhPt;
1383
			$this->hPt=$this->fwPt;
1384
			$this->w=$this->fh;
1385
			$this->h=$this->fw;
1386
		}
1387
		$this->PageBreakTrigger=$this->h-$this->bMargin;
1388
		$this->CurOrientation=$orientation;
1389
	}
1390
}
1391
 
1392
function _endpage()
1393
{
1394
	//End of page contents
1395
	$this->state=1;
1396
}
1397
 
1398
function _newobj()
1399
{
1400
	//Begin a new object
1401
	$this->n++;
1402
	$this->offsets[$this->n]=strlen($this->buffer);
1403
	$this->_out($this->n.' 0 obj');
1404
}
1405
 
1406
function _dounderline($x,$y,$txt)
1407
{
1408
	//Underline text
1409
	$up=$this->CurrentFont['up'];
1410
	$ut=$this->CurrentFont['ut'];
1411
	$w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
1412
	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);
1413
}
1414
 
1415
function _parsejpg($file)
1416
{
1417
	//Extract info from a JPEG file
1418
	$a=GetImageSize($file);
1419
	if(!$a)
1420
		$this->Error('Missing or incorrect image file: '.$file);
1421
	if($a[2]!=2)
1422
		$this->Error('Not a JPEG file: '.$file);
1423
	if(!isset($a['channels']) or $a['channels']==3)
1424
		$colspace='DeviceRGB';
1425
	elseif($a['channels']==4)
1426
		$colspace='DeviceCMYK';
1427
	else
1428
		$colspace='DeviceGray';
1429
	$bpc=isset($a['bits']) ? $a['bits'] : 8;
1430
	//Read whole file
1431
	$f=fopen($file,'rb');
1432
	$data=fread($f,filesize($file));
1433
	fclose($f);
1434
	return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
1435
}
1436
 
1437
function _parsepng($file)
1438
{
1439
	//Extract info from a PNG file
1440
	$f=fopen($file,'rb');
1441
	if(!$f)
1442
		$this->Error('Can\'t open image file: '.$file);
1443
	//Check signature
1444
	if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
1445
		$this->Error('Not a PNG file: '.$file);
1446
	//Read header chunk
1447
	fread($f,4);
1448
	if(fread($f,4)!='IHDR')
1449
		$this->Error('Incorrect PNG file: '.$file);
1450
	$w=$this->_freadint($f);
1451
	$h=$this->_freadint($f);
1452
	$bpc=ord(fread($f,1));
1453
	if($bpc>8)
1454
		$this->Error('16-bit depth not supported: '.$file);
1455
	$ct=ord(fread($f,1));
1456
	if($ct==0)
1457
		$colspace='DeviceGray';
1458
	elseif($ct==2)
1459
		$colspace='DeviceRGB';
1460
	elseif($ct==3)
1461
		$colspace='Indexed';
1462
	else
1463
		$this->Error('Alpha channel not supported: '.$file);
1464
	if(ord(fread($f,1))!=0)
1465
		$this->Error('Unknown compression method: '.$file);
1466
	if(ord(fread($f,1))!=0)
1467
		$this->Error('Unknown filter method: '.$file);
1468
	if(ord(fread($f,1))!=0)
1469
		$this->Error('Interlacing not supported: '.$file);
1470
	fread($f,4);
1471
	$parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
1472
	//Scan chunks looking for palette, transparency and image data
1473
	$pal='';
1474
	$trns='';
1475
	$data='';
1476
	do
1477
	{
1478
		$n=$this->_freadint($f);
1479
		$type=fread($f,4);
1480
		if($type=='PLTE')
1481
		{
1482
			//Read palette
1483
			$pal=fread($f,$n);
1484
			fread($f,4);
1485
		}
1486
		elseif($type=='tRNS')
1487
		{
1488
			//Read transparency info
1489
			$t=fread($f,$n);
1490
			if($ct==0)
1491
				$trns=array(ord(substr($t,1,1)));
1492
			elseif($ct==2)
1493
				$trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
1494
			else
1495
			{
1496
				$pos=strpos($t,chr(0));
1497
				if(is_int($pos))
1498
					$trns=array($pos);
1499
			}
1500
			fread($f,4);
1501
		}
1502
		elseif($type=='IDAT')
1503
		{
1504
			//Read image data block
1505
			$data.=fread($f,$n);
1506
			fread($f,4);
1507
		}
1508
		elseif($type=='IEND')
1509
			break;
1510
		else
1511
			fread($f,$n+4);
1512
	}
1513
	while($n);
1514
	if($colspace=='Indexed' and empty($pal))
1515
		$this->Error('Missing palette in '.$file);
1516
	fclose($f);
1517
	return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
1518
}
1519
 
1520
function _freadint($f)
1521
{
1522
	//Read a 4-byte integer from file
1523
	$i=ord(fread($f,1))<<24;
1524
	$i+=ord(fread($f,1))<<16;
1525
	$i+=ord(fread($f,1))<<8;
1526
	$i+=ord(fread($f,1));
1527
	return $i;
1528
}
1529
 
1530
function _textstring($s)
1531
{
1532
	//Format a text string
1533
	return '('.$this->_escape($s).')';
1534
}
1535
 
1536
function _escape($s)
1537
{
1538
	//Add \ before \, ( and )
1539
	return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
1540
}
1541
 
1542
function _putstream($s)
1543
{
1544
	$this->_out('stream');
1545
	$this->_out($s);
1546
	$this->_out('endstream');
1547
}
1548
 
1549
function _out($s)
1550
{
1551
	//Add a line to the document
1552
	if($this->state==2)
1553
		$this->pages[$this->page].=$s."\n";
1554
	else
1555
		$this->buffer.=$s."\n";
1556
}
1557
//End of class
1558
}
1559
 
1560
//Handle silly IE contype request
1561
if(isset($HTTP_ENV_VARS['HTTP_USER_AGENT']) and $HTTP_ENV_VARS['HTTP_USER_AGENT']=='contype')
1562
{
1563
	Header('Content-Type: application/pdf');
1564
	exit;
1565
}
1566
 
1567
?>