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); |
|
|
|
|
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)) |
|
|
|
|
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); |
|
|
|
|
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) { |
|
|
|
|
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); |
|
|
|
|
473
|
|
|
else |
474
|
|
|
$this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2); |
|
|
|
|
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++) |
|
|
|
|
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) { |
|
|
|
|
1374
|
|
|
$bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor); |
|
|
|
|
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) { |
|
|
|
|
1381
|
|
|
$bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor); |
|
|
|
|
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) |
|
|
|
|
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
|
|
|
?> |
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.