~hexmode/+junk/main

« back to all changes in this revision

Viewing changes to install-files/apps/phpmyadmin2.10.1/libraries/tcpdf/tcpdf.php

  • Committer: Mark A. Hershberger
  • Date: 2008-01-05 19:38:56 UTC
  • Revision ID: hershberger@spawn-xp-20080105193856-6rnzgwa4nehue3qj
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
//============================================================+
 
3
// File name   : tcpdf.php
 
4
// Begin       : 2002-08-03
 
5
// Last Update : 2006-10-27
 
6
// Author      : Nicola Asuni
 
7
// Version     : 1.53.0.TC026_PHP4
 
8
// License     : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)
 
9
//
 
10
// Description : This is a PHP4 class for generating PDF files 
 
11
//               on-the-fly without requiring external 
 
12
//               extensions.
 
13
//
 
14
// IMPORTANT:
 
15
// This class is an extension and improvement of the public Domain 
 
16
// FPDF class by Olivier Plathey (http://www.fpdf.org).
 
17
//
 
18
// Main changes by Nicola Asuni:
 
19
//    PHP4 porting;
 
20
//    UTF-8 Unicode support;
 
21
//    code refactoring;
 
22
//    source code clean up;
 
23
//    code style and formatting;
 
24
//    source code documentation using phpDocumentor (www.phpdoc.org);
 
25
//    All ISO page formats were included;
 
26
//    image scale factor;
 
27
//    includes methods to parse and printsome XHTML code, supporting the following elements: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small;
 
28
//    includes a method to print various barcode formats using an improved version of "Generic Barcode Render Class" by Karim Mribti (http://www.mribti.com/barcode/) (require GD library: http://www.boutell.com/gd/);
 
29
//    defines standard Header() and Footer() methods.
 
30
//============================================================+
 
31
 
 
32
/**
 
33
 * include configuration file
 
34
 */
 
35
// Disabled in phpMyAdmin
 
36
//require_once(dirname(__FILE__).'/config/tcpdf_config.php');
 
37
 
 
38
 
 
39
/**
 
40
 * TCPDF Class.
 
41
 * @package com.tecnick.tcpdf
 
42
 */
 
43
 
 
44
/**
 
45
 * This is a PHP4 class for generating PDF files on-the-fly without requiring external extensions.<br>
 
46
 * TCPDF project (http://tcpdf.sourceforge.net) is based on the public Domain FPDF class by Olivier Plathey (http://www.fpdf.org).<br>
 
47
 * <h3>TCPDF main changes from FPDF are:</h3><ul>
 
48
 * <li>PHP4 porting</li>
 
49
 * <li>UTF-8 Unicode support</li>
 
50
 * <li>source code clean up</li>
 
51
 * <li>code style and formatting</li>
 
52
 * <li>source code documentation using phpDocumentor (www.phpdoc.org)</li>
 
53
 * <li>All ISO page formats were included</li>
 
54
 * <li>image scale factor</li>
 
55
 * <li>includes methods to parse and printsome XHTML code, supporting the following elements: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small;</li>
 
56
 * <li>includes a method to print various barcode formats using an improved version of "Generic Barcode Render Class" by Karim Mribti (http://www.mribti.com/barcode/) (require GD library: http://www.boutell.com/gd/)</li>
 
57
 * <li>defines standard Header() and Footer() methods.</li>
 
58
 * </ul>
 
59
 * Tools to encode your unicode fonts are on fonts/ttf2ufm directory.</p>
 
60
 * @name TCPDF
 
61
 * @package com.tecnick.tcpdf
 
62
 * @abstract Class for generating PDF files on-the-fly without requiring external extensions.
 
63
 * @author Nicola Asuni
 
64
 * @copyright 2004-2006 Tecnick.com S.r.l (www.tecnick.com) Via Ugo Foscolo n.19 - 09045 Quartu Sant'Elena (CA) - ITALY - www.tecnick.com - info@tecnick.com
 
65
 * @link http://tcpdf.sourceforge.net
 
66
 * @license http://www.gnu.org/copyleft/lesser.html LGPL
 
67
 @version 1.53.0.TC026_PHP4
 
68
 */
 
69
 
 
70
if(!class_exists('TCPDF')) {
 
71
        /**
 
72
         * define default PDF document producer
 
73
         */ 
 
74
        define('PDF_PRODUCER','TCPDF 1.53.0.TC026_PHP4 (http://tcpdf.sourceforge.net)');
 
75
        
 
76
        /**
 
77
        * This is a PHP4 class for generating PDF files on-the-fly without requiring external extensions.<br>
 
78
        * This class is an extension and improvement of the FPDF class by Olivier Plathey (http://www.fpdf.org).<br>
 
79
        * This version contains some changes: [porting to PHP4, support for UTF-8 Unicode, code style and formatting, php documentation (www.phpdoc.org), ISO page formats, minor improvements, image scale factor]<br>
 
80
        * TCPDF project (http://tcpdf.sourceforge.net) is based on the public Domain FPDF class by Olivier Plathey (http://www.fpdf.org).<br>
 
81
        * To add your own TTF fonts please read /fonts/README.TXT
 
82
        * @name TCPDF
 
83
        * @package com.tecnick.tcpdf
 
84
        * @version 1.53.0.TC026_PHP4
 
85
        * @author Nicola Asuni
 
86
        * @link http://tcpdf.sourceforge.net
 
87
        * @license http://www.gnu.org/copyleft/lesser.html LGPL
 
88
        */
 
89
        class TCPDF {
 
90
                //var properties
 
91
 
 
92
                /**
 
93
                * @var current page number
 
94
                * @access protected
 
95
                */
 
96
                var $page;
 
97
 
 
98
                /**
 
99
                * @var current object number
 
100
                * @access protected
 
101
                */
 
102
                var $n;
 
103
 
 
104
                /**
 
105
                * @var array of object offsets
 
106
                * @access protected
 
107
                */
 
108
                var $offsets;
 
109
 
 
110
                /**
 
111
                * @var buffer holding in-memory PDF
 
112
                * @access protected
 
113
                */
 
114
                var $buffer;
 
115
 
 
116
                /**
 
117
                * @var array containing pages
 
118
                * @access protected
 
119
                */
 
120
                var $pages;
 
121
 
 
122
                /**
 
123
                * @var current document state
 
124
                * @access protected
 
125
                */
 
126
                var $state;
 
127
 
 
128
                /**
 
129
                * @var compression flag
 
130
                * @access protected
 
131
                */
 
132
                var $compress;
 
133
 
 
134
                /**
 
135
                * @var default orientation
 
136
                * @access protected
 
137
                */
 
138
                var $DefOrientation;
 
139
 
 
140
                /**
 
141
                * @var current orientation
 
142
                * @access protected
 
143
                */
 
144
                var $CurOrientation;
 
145
 
 
146
                /**
 
147
                * @var array indicating orientation changes
 
148
                * @access protected
 
149
                */
 
150
                var $OrientationChanges;
 
151
 
 
152
                /**
 
153
                * @var scale factor (number of points in user unit)
 
154
                * @access protected
 
155
                */
 
156
                var $k;
 
157
 
 
158
                /**
 
159
                * @var width of page format in points
 
160
                * @access protected
 
161
                */
 
162
                var $fwPt;
 
163
 
 
164
                /**
 
165
                * @var height of page format in points
 
166
                * @access protected
 
167
                */
 
168
                var $fhPt;
 
169
 
 
170
                /**
 
171
                * @var width of page format in user unit
 
172
                * @access protected
 
173
                */
 
174
                var $fw;
 
175
 
 
176
                /**
 
177
                * @var height of page format in user unit
 
178
                * @access protected
 
179
                */
 
180
                var $fh;
 
181
 
 
182
                /**
 
183
                * @var current width of page in points
 
184
                * @access protected
 
185
                */
 
186
                var $wPt;
 
187
 
 
188
                /**
 
189
                * @var current height of page in points
 
190
                * @access protected
 
191
                */
 
192
                var $hPt;
 
193
 
 
194
                /**
 
195
                * @var current width of page in user unit
 
196
                * @access protected
 
197
                */
 
198
                var $w;
 
199
 
 
200
                /**
 
201
                * @var current height of page in user unit
 
202
                * @access protected
 
203
                */
 
204
                var $h;
 
205
 
 
206
                /**
 
207
                * @var left margin
 
208
                * @access protected
 
209
                */
 
210
                var $lMargin;
 
211
 
 
212
                /**
 
213
                * @var top margin
 
214
                * @access protected
 
215
                */
 
216
                var $tMargin;
 
217
 
 
218
                /**
 
219
                * @var right margin
 
220
                * @access protected
 
221
                */
 
222
                var $rMargin;
 
223
 
 
224
                /**
 
225
                * @var page break margin
 
226
                * @access protected
 
227
                */
 
228
                var $bMargin;
 
229
 
 
230
                /**
 
231
                * @var cell margin
 
232
                * @access protected
 
233
                */
 
234
                var $cMargin;
 
235
 
 
236
                /**
 
237
                * @var current horizontal position in user unit for cell positioning
 
238
                * @access protected
 
239
                */
 
240
                var $x;
 
241
 
 
242
                /**
 
243
                * @var current vertical position in user unit for cell positioning
 
244
                * @access protected
 
245
                */
 
246
                var $y;
 
247
 
 
248
                /**
 
249
                * @var height of last cell printed
 
250
                * @access protected
 
251
                */
 
252
                var $lasth;
 
253
 
 
254
                /**
 
255
                * @var line width in user unit
 
256
                * @access protected
 
257
                */
 
258
                var $LineWidth;
 
259
 
 
260
                /**
 
261
                * @var array of standard font names
 
262
                * @access protected
 
263
                */
 
264
                var $CoreFonts;
 
265
 
 
266
                /**
 
267
                * @var array of used fonts
 
268
                * @access protected
 
269
                */
 
270
                var $fonts;
 
271
 
 
272
                /**
 
273
                * @var array of font files
 
274
                * @access protected
 
275
                */
 
276
                var $FontFiles;
 
277
 
 
278
                /**
 
279
                * @var array of encoding differences
 
280
                * @access protected
 
281
                */
 
282
                var $diffs;
 
283
 
 
284
                /**
 
285
                * @var array of used images
 
286
                * @access protected
 
287
                */
 
288
                var $images;
 
289
 
 
290
                /**
 
291
                * @var array of links in pages
 
292
                * @access protected
 
293
                */
 
294
                var $PageLinks;
 
295
 
 
296
                /**
 
297
                * @var array of internal links
 
298
                * @access protected
 
299
                */
 
300
                var $links;
 
301
 
 
302
                /**
 
303
                * @var current font family
 
304
                * @access protected
 
305
                */
 
306
                var $FontFamily;
 
307
 
 
308
                /**
 
309
                * @var current font style
 
310
                * @access protected
 
311
                */
 
312
                var $FontStyle;
 
313
 
 
314
                /**
 
315
                * @var underlining flag
 
316
                * @access protected
 
317
                */
 
318
                var $underline;
 
319
 
 
320
                /**
 
321
                * @var current font info
 
322
                * @access protected
 
323
                */
 
324
                var $CurrentFont;
 
325
 
 
326
                /**
 
327
                * @var current font size in points
 
328
                * @access protected
 
329
                */
 
330
                var $FontSizePt;
 
331
 
 
332
                /**
 
333
                * @var current font size in user unit
 
334
                * @access protected
 
335
                */
 
336
                var $FontSize;
 
337
 
 
338
                /**
 
339
                * @var commands for drawing color
 
340
                * @access protected
 
341
                */
 
342
                var $DrawColor;
 
343
 
 
344
                /**
 
345
                * @var commands for filling color
 
346
                * @access protected
 
347
                */
 
348
                var $FillColor;
 
349
 
 
350
                /**
 
351
                * @var commands for text color
 
352
                * @access protected
 
353
                */
 
354
                var $TextColor;
 
355
 
 
356
                /**
 
357
                * @var indicates whether fill and text colors are different
 
358
                * @access protected
 
359
                */
 
360
                var $ColorFlag;
 
361
 
 
362
                /**
 
363
                * @var word spacing
 
364
                * @access protected
 
365
                */
 
366
                var $ws;
 
367
 
 
368
                /**
 
369
                * @var automatic page breaking
 
370
                * @access protected
 
371
                */
 
372
                var $AutoPageBreak;
 
373
 
 
374
                /**
 
375
                * @var threshold used to trigger page breaks
 
376
                * @access protected
 
377
                */
 
378
                var $PageBreakTrigger;
 
379
 
 
380
                /**
 
381
                * @var flag set when processing footer
 
382
                * @access protected
 
383
                */
 
384
                var $InFooter;
 
385
 
 
386
                /**
 
387
                * @var zoom display mode
 
388
                * @access protected
 
389
                */
 
390
                var $ZoomMode;
 
391
 
 
392
                /**
 
393
                * @var layout display mode
 
394
                * @access protected
 
395
                */
 
396
                var $LayoutMode;
 
397
 
 
398
                /**
 
399
                * @var title
 
400
                * @access protected
 
401
                */
 
402
                var $title;
 
403
 
 
404
                /**
 
405
                * @var subject
 
406
                * @access protected
 
407
                */
 
408
                var $subject;
 
409
 
 
410
                /**
 
411
                * @var author
 
412
                * @access protected
 
413
                */
 
414
                var $author;
 
415
 
 
416
                /**
 
417
                * @var keywords
 
418
                * @access protected
 
419
                */
 
420
                var $keywords;
 
421
 
 
422
                /**
 
423
                * @var creator
 
424
                * @access protected
 
425
                */
 
426
                var $creator;
 
427
 
 
428
                /**
 
429
                * @var alias for total number of pages
 
430
                * @access protected
 
431
                */
 
432
                var $AliasNbPages;
 
433
 
 
434
                /**
 
435
                * @var right-bottom corner X coordinate of inserted image
 
436
                * @since 2002-07-31
 
437
                * @author Nicola Asuni
 
438
                * @access protected
 
439
                */
 
440
                var $img_rb_x;
 
441
 
 
442
                /**
 
443
                * @var right-bottom corner Y coordinate of inserted image
 
444
                * @since 2002-07-31
 
445
                * @author Nicola Asuni
 
446
                * @access protected
 
447
                */
 
448
                var $img_rb_y;
 
449
 
 
450
                /**
 
451
                * @var image scale factor
 
452
                * @since 2004-06-14
 
453
                * @author Nicola Asuni
 
454
                * @access protected
 
455
                */
 
456
                var $imgscale = 1;
 
457
 
 
458
                /**
 
459
                * @var boolean set to true when the input text is unicode (require unicode fonts)
 
460
                * @since 2005-01-02
 
461
                * @author Nicola Asuni
 
462
                * @access protected
 
463
                */
 
464
                var $isunicode = false;
 
465
 
 
466
                /**
 
467
                * @var PDF version
 
468
                * @since 1.5.3
 
469
                * @access protected
 
470
                */
 
471
                var $PDFVersion = "1.3";
 
472
                
 
473
                
 
474
                // ----------------------
 
475
                
 
476
                /**
 
477
                 * @var Minimum distance between header and top page margin.
 
478
                 * @access private
 
479
                 */
 
480
                var $header_margin;
 
481
                
 
482
                /**
 
483
                 * @var Minimum distance between footer and bottom page margin.
 
484
                 * @access private
 
485
                 */
 
486
                var $footer_margin;
 
487
                
 
488
                /**
 
489
                 * @var original left margin value
 
490
                 * @access private
 
491
                 * @since 1.53.0.TC013
 
492
                 */
 
493
                var $original_lMargin;
 
494
                
 
495
                /**
 
496
                 * @var original right margin value
 
497
                 * @access private
 
498
                 * @since 1.53.0.TC013
 
499
                 */
 
500
                var $original_rMargin;
 
501
                        
 
502
                /**
 
503
                 * @var Header font.
 
504
                 * @access private
 
505
                 */
 
506
                var $header_font;
 
507
                
 
508
                /**
 
509
                 * @var Footer font.
 
510
                 * @access private
 
511
                 */
 
512
                var $footer_font;
 
513
                
 
514
                /**
 
515
                 * @var Language templates.
 
516
                 * @access private
 
517
                 */
 
518
                var $l;
 
519
                
 
520
                /**
 
521
                 * @var Barcode to print on page footer (only if set).
 
522
                 * @access private
 
523
                 */
 
524
                var $barcode = false;
 
525
                
 
526
                /**
 
527
                 * @var If true prints header
 
528
                 * @access private
 
529
                 */
 
530
                var $print_header = true;
 
531
                
 
532
                /**
 
533
                 * @var If true prints footer.
 
534
                 * @access private
 
535
                 */
 
536
                var $print_footer = true;
 
537
                
 
538
                /**
 
539
                 * @var Header width (0 = full page width).
 
540
                 * @access private
 
541
                 */
 
542
                var $header_width = 0;
 
543
                
 
544
                /**
 
545
                 * @var Header image logo.
 
546
                 * @access private
 
547
                 */
 
548
                var $header_logo = "";
 
549
                
 
550
                /**
 
551
                 * @var Header image logo width in mm.
 
552
                 * @access private
 
553
                 */
 
554
                var $header_logo_width = 30;
 
555
                
 
556
                /**
 
557
                 * @var String to print as title on document header.
 
558
                 * @access private
 
559
                 */
 
560
                var $header_title = "";
 
561
                
 
562
                /**
 
563
                 * @var String to print on document header.
 
564
                 * @access private
 
565
                 */
 
566
                var $header_string = "";
 
567
                
 
568
                /**
 
569
                 * @var Default number of columns for html table.
 
570
                 * @access private
 
571
                 */
 
572
                var $default_table_columns = 4;
 
573
                
 
574
                
 
575
                // variables for html parser
 
576
                
 
577
                /**
 
578
                 * @var HTML PARSER: store current link.
 
579
                 * @access private
 
580
                 */
 
581
                var $HREF;
 
582
                
 
583
                /**
 
584
                 * @var HTML PARSER: store font list.
 
585
                 * @access private
 
586
                 */
 
587
                var $fontList;
 
588
                
 
589
                /**
 
590
                 * @var HTML PARSER: true when font attribute is set.
 
591
                 * @access private
 
592
                 */
 
593
                var $issetfont;
 
594
                
 
595
                /**
 
596
                 * @var HTML PARSER: true when color attribute is set.
 
597
                 * @access private
 
598
                 */
 
599
                var $issetcolor;
 
600
                
 
601
                /**
 
602
                 * @var HTML PARSER: true in case of ordered list (OL), false otherwise.
 
603
                 * @access private
 
604
                 */
 
605
                var $listordered = false;
 
606
                
 
607
                /**
 
608
                 * @var HTML PARSER: count list items.
 
609
                 * @access private
 
610
                 */
 
611
                var $listcount = 0;
 
612
                
 
613
                /**
 
614
                 * @var HTML PARSER: size of table border.
 
615
                 * @access private
 
616
                 */
 
617
                var $tableborder = 0;
 
618
                
 
619
                /**
 
620
                 * @var HTML PARSER: true at the beginning of table.
 
621
                 * @access private
 
622
                 */
 
623
                var $tdbegin = false;
 
624
                
 
625
                /**
 
626
                 * @var HTML PARSER: table width.
 
627
                 * @access private
 
628
                 */
 
629
                var $tdwidth = 0;
 
630
                
 
631
                /**
 
632
                 * @var HTML PARSER: table height.
 
633
                 * @access private
 
634
                 */
 
635
                var $tdheight = 0;
 
636
                
 
637
                /**
 
638
                 * @var HTML PARSER: table align.
 
639
                 * @access private
 
640
                 */
 
641
                var $tdalign = "L";
 
642
                
 
643
                /**
 
644
                 * @var HTML PARSER: table background color.
 
645
                 * @access private
 
646
                 */
 
647
                var $tdbgcolor = false;
 
648
                
 
649
                /**
 
650
                 * @var Store temporary font size in points.
 
651
                 * @access private
 
652
                 */
 
653
                var $tempfontsize = 10;
 
654
                
 
655
                /**
 
656
                 * @var Bold font style status.
 
657
                 * @access private
 
658
                 */
 
659
                var $b;
 
660
                
 
661
                /**
 
662
                 * @var Underlined font style status.
 
663
                 * @access private
 
664
                 */
 
665
                var $u;
 
666
                
 
667
                /**
 
668
                 * @var Italic font style status.
 
669
                 * @access private
 
670
                 */
 
671
                var $i;
 
672
                
 
673
                /**
 
674
                 * @var spacer for LI tags.
 
675
                 * @access private
 
676
                 */
 
677
                var $lispacer = "";
 
678
                
 
679
                /**
 
680
                 * @var default encoding
 
681
                 * @access private
 
682
                 * @since 1.53.0.TC010
 
683
                 */
 
684
                var $encoding = "UTF-8";
 
685
                
 
686
                /**
 
687
                 * @var PHP internal encoding
 
688
                 * @access private
 
689
                 * @since 1.53.0.TC016
 
690
                 */
 
691
                var $internal_encoding;
 
692
                
 
693
                /**
 
694
                 * @var store previous fill color as RGB array
 
695
                 * @access private
 
696
                 * @since 1.53.0.TC017
 
697
                 */
 
698
                var $prevFillColor = array(255,255,255);
 
699
                
 
700
                /**
 
701
                 * @var store previous text color as RGB array
 
702
                 * @access private
 
703
                 * @since 1.53.0.TC017
 
704
                 */
 
705
                var $prevTextColor = array(0,0,0);
 
706
                
 
707
                /**
 
708
                 * @var store previous font family
 
709
                 * @access private
 
710
                 * @since 1.53.0.TC017
 
711
                 */
 
712
                var $prevFontFamily;
 
713
                
 
714
                /**
 
715
                 * @var store previous font style
 
716
                 * @access private
 
717
                 * @since 1.53.0.TC017
 
718
                 */
 
719
                var $prevFontStyle;
 
720
 
 
721
                //------------------------------------------------------------
 
722
                // var methods
 
723
                //------------------------------------------------------------
 
724
 
 
725
                /**
 
726
                 * This is the class constructor. 
 
727
                 * It allows to set up the page format, the orientation and 
 
728
                 * the measure unit used in all the methods (except for the font sizes).
 
729
                 * @since 1.0
 
730
                 * @param string $orientation page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li></ul>
 
731
                 * @param string $unit User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
 
732
                 * @param mixed $format The format used for pages. It can be either one of the following values (case insensitive) or a custom format in the form of a two-element array containing the width and the height (expressed in the unit given by unit).<ul><li>4A0</li><li>2A0</li><li>A0</li><li>A1</li><li>A2</li><li>A3</li><li>A4 (default)</li><li>A5</li><li>A6</li><li>A7</li><li>A8</li><li>A9</li><li>A10</li><li>B0</li><li>B1</li><li>B2</li><li>B3</li><li>B4</li><li>B5</li><li>B6</li><li>B7</li><li>B8</li><li>B9</li><li>B10</li><li>C0</li><li>C1</li><li>C2</li><li>C3</li><li>C4</li><li>C5</li><li>C6</li><li>C7</li><li>C8</li><li>C9</li><li>C10</li><li>RA0</li><li>RA1</li><li>RA2</li><li>RA3</li><li>RA4</li><li>SRA0</li><li>SRA1</li><li>SRA2</li><li>SRA3</li><li>SRA4</li><li>LETTER</li><li>LEGAL</li><li>EXECUTIVE</li><li>FOLIO</li></ul>
 
733
                 * @param boolean $unicode TRUE means that the input text is unicode (default = true)
 
734
                 * @param String $encoding charset encoding; default is UTF-8
 
735
                 */
 
736
                function TCPDF($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding="UTF-8") {
 
737
                        
 
738
                        /* Set internal character encoding to ASCII */
 
739
                        if (function_exists("mb_internal_encoding") AND mb_internal_encoding()) {
 
740
                                $this->internal_encoding = mb_internal_encoding();
 
741
                                mb_internal_encoding("ASCII");
 
742
                        }
 
743
                                
 
744
                        //Some checks
 
745
                        $this->_dochecks();
 
746
                        //Initialization of properties
 
747
                        $this->isunicode=$unicode;
 
748
                        $this->page=0;
 
749
                        $this->n=2;
 
750
                        $this->buffer='';
 
751
                        $this->pages=array();
 
752
                        $this->OrientationChanges=array();
 
753
                        $this->state=0;
 
754
                        $this->fonts=array();
 
755
                        $this->FontFiles=array();
 
756
                        $this->diffs=array();
 
757
                        $this->images=array();
 
758
                        $this->links=array();
 
759
                        $this->InFooter=false;
 
760
                        $this->lasth=0;
 
761
                        $this->FontFamily='';
 
762
                        $this->FontStyle='';
 
763
                        $this->FontSizePt=12;
 
764
                        $this->underline=false;
 
765
                        $this->DrawColor='0 G';
 
766
                        $this->FillColor='0 g';
 
767
                        $this->TextColor='0 g';
 
768
                        $this->ColorFlag=false;
 
769
                        $this->ws=0;
 
770
                        //Standard Unicode fonts
 
771
                        $this->CoreFonts=array(
 
772
                        'courier'=>'Courier',
 
773
                        'courierB'=>'Courier-Bold',
 
774
                        'courierI'=>'Courier-Oblique',
 
775
                        'courierBI'=>'Courier-BoldOblique',
 
776
                        'helvetica'=>'Helvetica',
 
777
                        'helveticaB'=>'Helvetica-Bold',
 
778
                        'helveticaI'=>'Helvetica-Oblique',
 
779
                        'helveticaBI'=>'Helvetica-BoldOblique',
 
780
                        'times'=>'Times-Roman',
 
781
                        'timesB'=>'Times-Bold',
 
782
                        'timesI'=>'Times-Italic',
 
783
                        'timesBI'=>'Times-BoldItalic',
 
784
                        'symbol'=>'Symbol',
 
785
                        'zapfdingbats'=>'ZapfDingbats'
 
786
                        );
 
787
 
 
788
                        //Scale factor
 
789
                        // 2003-06-11 - Nicola Asuni : changed if/else with switch statement
 
790
                        switch (strtolower($unit)){
 
791
                                case 'pt': {$this->k=1; break;}
 
792
                                case 'mm': {$this->k=72/25.4; break;}
 
793
                                case 'cm': {$this->k=72/2.54; break;}
 
794
                                case 'in': {$this->k=72; break;}
 
795
                                default : {$this->Error('Incorrect unit: '.$unit); break;}
 
796
                        }
 
797
 
 
798
                        //Page format
 
799
                        if(is_string($format)) {
 
800
                                // 2002-07-24 - Nicola Asuni (info@tecnick.com)
 
801
                                // Added new page formats (45 standard ISO paper formats and 4 american common formats).
 
802
                                // Paper cordinates are calculated in this way: (inches * 72) where (1 inch = 2.54 cm)
 
803
                                switch (strtoupper($format)){
 
804
                                        case '4A0': {$format = array(4767.87,6740.79); break;}
 
805
                                        case '2A0': {$format = array(3370.39,4767.87); break;}
 
806
                                        case 'A0': {$format = array(2383.94,3370.39); break;}
 
807
                                        case 'A1': {$format = array(1683.78,2383.94); break;}
 
808
                                        case 'A2': {$format = array(1190.55,1683.78); break;}
 
809
                                        case 'A3': {$format = array(841.89,1190.55); break;}
 
810
                                        case 'A4': default: {$format = array(595.28,841.89); break;}
 
811
                                        case 'A5': {$format = array(419.53,595.28); break;}
 
812
                                        case 'A6': {$format = array(297.64,419.53); break;}
 
813
                                        case 'A7': {$format = array(209.76,297.64); break;}
 
814
                                        case 'A8': {$format = array(147.40,209.76); break;}
 
815
                                        case 'A9': {$format = array(104.88,147.40); break;}
 
816
                                        case 'A10': {$format = array(73.70,104.88); break;}
 
817
                                        case 'B0': {$format = array(2834.65,4008.19); break;}
 
818
                                        case 'B1': {$format = array(2004.09,2834.65); break;}
 
819
                                        case 'B2': {$format = array(1417.32,2004.09); break;}
 
820
                                        case 'B3': {$format = array(1000.63,1417.32); break;}
 
821
                                        case 'B4': {$format = array(708.66,1000.63); break;}
 
822
                                        case 'B5': {$format = array(498.90,708.66); break;}
 
823
                                        case 'B6': {$format = array(354.33,498.90); break;}
 
824
                                        case 'B7': {$format = array(249.45,354.33); break;}
 
825
                                        case 'B8': {$format = array(175.75,249.45); break;}
 
826
                                        case 'B9': {$format = array(124.72,175.75); break;}
 
827
                                        case 'B10': {$format = array(87.87,124.72); break;}
 
828
                                        case 'C0': {$format = array(2599.37,3676.54); break;}
 
829
                                        case 'C1': {$format = array(1836.85,2599.37); break;}
 
830
                                        case 'C2': {$format = array(1298.27,1836.85); break;}
 
831
                                        case 'C3': {$format = array(918.43,1298.27); break;}
 
832
                                        case 'C4': {$format = array(649.13,918.43); break;}
 
833
                                        case 'C5': {$format = array(459.21,649.13); break;}
 
834
                                        case 'C6': {$format = array(323.15,459.21); break;}
 
835
                                        case 'C7': {$format = array(229.61,323.15); break;}
 
836
                                        case 'C8': {$format = array(161.57,229.61); break;}
 
837
                                        case 'C9': {$format = array(113.39,161.57); break;}
 
838
                                        case 'C10': {$format = array(79.37,113.39); break;}
 
839
                                        case 'RA0': {$format = array(2437.80,3458.27); break;}
 
840
                                        case 'RA1': {$format = array(1729.13,2437.80); break;}
 
841
                                        case 'RA2': {$format = array(1218.90,1729.13); break;}
 
842
                                        case 'RA3': {$format = array(864.57,1218.90); break;}
 
843
                                        case 'RA4': {$format = array(609.45,864.57); break;}
 
844
                                        case 'SRA0': {$format = array(2551.18,3628.35); break;}
 
845
                                        case 'SRA1': {$format = array(1814.17,2551.18); break;}
 
846
                                        case 'SRA2': {$format = array(1275.59,1814.17); break;}
 
847
                                        case 'SRA3': {$format = array(907.09,1275.59); break;}
 
848
                                        case 'SRA4': {$format = array(637.80,907.09); break;}
 
849
                                        case 'LETTER': {$format = array(612.00,792.00); break;}
 
850
                                        case 'LEGAL': {$format = array(612.00,1008.00); break;}
 
851
                                        case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
 
852
                                        case 'FOLIO': {$format = array(612.00,936.00); break;}
 
853
                                        // default: {$this->Error('Unknown page format: '.$format); break;}
 
854
                                        // END CHANGES Nicola Asuni
 
855
                                }
 
856
                                $this->fwPt=$format[0];
 
857
                                $this->fhPt=$format[1];
 
858
                        }
 
859
                        else {
 
860
                                $this->fwPt=$format[0]*$this->k;
 
861
                                $this->fhPt=$format[1]*$this->k;
 
862
                        }
 
863
 
 
864
                        $this->fw=$this->fwPt/$this->k;
 
865
                        $this->fh=$this->fhPt/$this->k;
 
866
 
 
867
                        //Page orientation
 
868
                        $orientation=strtolower($orientation);
 
869
                        if($orientation=='p' or $orientation=='portrait') {
 
870
                                $this->DefOrientation='P';
 
871
                                $this->wPt=$this->fwPt;
 
872
                                $this->hPt=$this->fhPt;
 
873
                        }
 
874
                        elseif($orientation=='l' or $orientation=='landscape') {
 
875
                                $this->DefOrientation='L';
 
876
                                $this->wPt=$this->fhPt;
 
877
                                $this->hPt=$this->fwPt;
 
878
                        }
 
879
                        else {
 
880
                                $this->Error('Incorrect orientation: '.$orientation);
 
881
                        }
 
882
 
 
883
                        $this->CurOrientation=$this->DefOrientation;
 
884
                        $this->w=$this->wPt/$this->k;
 
885
                        $this->h=$this->hPt/$this->k;
 
886
                        //Page margins (1 cm)
 
887
                        $margin=28.35/$this->k;
 
888
                        $this->SetMargins($margin,$margin);
 
889
                        //Interior cell margin (1 mm)
 
890
                        $this->cMargin=$margin/10;
 
891
                        //Line width (0.2 mm)
 
892
                        $this->LineWidth=.567/$this->k;
 
893
                        //Automatic page break
 
894
                        $this->SetAutoPageBreak(true,2*$margin);
 
895
                        //Full width display mode
 
896
                        $this->SetDisplayMode('fullwidth');
 
897
                        //Compression
 
898
                        $this->SetCompression(true);
 
899
                        //Set default PDF version number
 
900
                        $this->PDFVersion = "1.3";
 
901
                        
 
902
                        $this->encoding = $encoding;
 
903
                        $this->b = 0;
 
904
                        $this->i = 0;
 
905
                        $this->u = 0;
 
906
                        $this->HREF = '';
 
907
                        $this->fontlist = array("arial", "times", "courier", "helvetica", "symbol");
 
908
                        $this->issetfont = false;
 
909
                        $this->issetcolor = false;
 
910
                        $this->tableborder = 0;
 
911
                        $this->tdbegin = false;
 
912
                        $this->tdwidth=  0;
 
913
                        $this->tdheight = 0;
 
914
                        $this->tdalign = "L";
 
915
                        $this->tdbgcolor = false;
 
916
                        
 
917
                        $this->SetFillColor(200, 200, 200, true);
 
918
                        $this->SetTextColor(0, 0, 0, true);
 
919
                }
 
920
 
 
921
                /**
 
922
                * Set the image scale.
 
923
                * @param float $scale image scale.
 
924
                * @author Nicola Asuni
 
925
                * @since 1.5.2
 
926
                */
 
927
                function setImageScale($scale) {
 
928
                        $this->imgscale=$scale;
 
929
                }
 
930
 
 
931
                /**
 
932
                * Returns the image scale.
 
933
                * @return float image scale.
 
934
                * @author Nicola Asuni
 
935
                * @since 1.5.2
 
936
                */
 
937
                function getImageScale() {
 
938
                        return $this->imgscale;
 
939
                }
 
940
 
 
941
                /**
 
942
                * Returns the page width in units.
 
943
                * @return int page width.
 
944
                * @author Nicola Asuni
 
945
                * @since 1.5.2
 
946
                */
 
947
                function getPageWidth() {
 
948
                        return $this->w;
 
949
                }
 
950
 
 
951
                /**
 
952
                * Returns the page height in units.
 
953
                * @return int page height.
 
954
                * @author Nicola Asuni
 
955
                * @since 1.5.2
 
956
                */
 
957
                function getPageHeight() {
 
958
                        return $this->h;
 
959
                }
 
960
 
 
961
                /**
 
962
                * Returns the page break margin.
 
963
                * @return int page break margin.
 
964
                * @author Nicola Asuni
 
965
                * @since 1.5.2
 
966
                */
 
967
                function getBreakMargin() {
 
968
                        return $this->bMargin;
 
969
                }
 
970
 
 
971
                /**
 
972
                * Returns the scale factor (number of points in user unit).
 
973
                * @return int scale factor.
 
974
                * @author Nicola Asuni
 
975
                * @since 1.5.2
 
976
                */
 
977
                function getScaleFactor() {
 
978
                        return $this->k;
 
979
                }
 
980
 
 
981
                /**
 
982
                * Defines the left, top and right margins. By default, they equal 1 cm. Call this method to change them.
 
983
                * @param float $left Left margin.
 
984
                * @param float $top Top margin.
 
985
                * @param float $right Right margin. Default value is the left one.
 
986
                * @since 1.0
 
987
                * @see SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak()
 
988
                */
 
989
                function SetMargins($left, $top, $right=-1) {
 
990
                        //Set left, top and right margins
 
991
                        $this->lMargin=$left;
 
992
                        $this->tMargin=$top;
 
993
                        if($right==-1) {
 
994
                                $right=$left;
 
995
                        }
 
996
                        $this->rMargin=$right;
 
997
                }
 
998
 
 
999
                /**
 
1000
                * Defines the left margin. The method can be called before creating the first page. If the current abscissa gets out of page, it is brought back to the margin.
 
1001
                * @param float $margin The margin.
 
1002
                * @since 1.4
 
1003
                * @see SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
 
1004
                */
 
1005
                function SetLeftMargin($margin) {
 
1006
                        //Set left margin
 
1007
                        $this->lMargin=$margin;
 
1008
                        if(($this->page>0) and ($this->x<$margin)) {
 
1009
                                $this->x=$margin;
 
1010
                        }
 
1011
                }
 
1012
 
 
1013
                /**
 
1014
                * Defines the top margin. The method can be called before creating the first page.
 
1015
                * @param float $margin The margin.
 
1016
                * @since 1.5
 
1017
                * @see SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
 
1018
                */
 
1019
                function SetTopMargin($margin) {
 
1020
                        //Set top margin
 
1021
                        $this->tMargin=$margin;
 
1022
                }
 
1023
 
 
1024
                /**
 
1025
                * Defines the right margin. The method can be called before creating the first page.
 
1026
                * @param float $margin The margin.
 
1027
                * @since 1.5
 
1028
                * @see SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()
 
1029
                */
 
1030
                function SetRightMargin($margin) {
 
1031
                        //Set right margin
 
1032
                        $this->rMargin=$margin;
 
1033
                }
 
1034
 
 
1035
                /**
 
1036
                * Enables or disables the automatic page breaking mode. When enabling, the second parameter is the distance from the bottom of the page that defines the triggering limit. By default, the mode is on and the margin is 2 cm.
 
1037
                * @param boolean $auto Boolean indicating if mode should be on or off.
 
1038
                * @param float $margin Distance from the bottom of the page.
 
1039
                * @since 1.0
 
1040
                * @see Cell(), MultiCell(), AcceptPageBreak()
 
1041
                */
 
1042
                function SetAutoPageBreak($auto, $margin=0) {
 
1043
                        //Set auto page break mode and triggering margin
 
1044
                        $this->AutoPageBreak=$auto;
 
1045
                        $this->bMargin=$margin;
 
1046
                        $this->PageBreakTrigger=$this->h-$margin;
 
1047
                }
 
1048
 
 
1049
                /**
 
1050
                * Defines the way the document is to be displayed by the viewer. The zoom level can be set: pages can be displayed entirely on screen, occupy the full width of the window, use real size, be scaled by a specific zooming factor or use viewer default (configured in the Preferences menu of Acrobat). The page layout can be specified too: single at once, continuous display, two columns or viewer default. By default, documents use the full width mode with continuous display.
 
1051
                * @param mixed $zoom The zoom to use. It can be one of the following string values or a number indicating the zooming factor to use. <ul><li>fullpage: displays the entire page on screen </li><li>fullwidth: uses maximum width of window</li><li>real: uses real size (equivalent to 100% zoom)</li><li>default: uses viewer default mode</li></ul>
 
1052
                * @param string $layout The page layout. Possible values are:<ul><li>single: displays one page at once</li><li>continuous: displays pages continuously (default)</li><li>two: displays two pages on two columns</li><li>default: uses viewer default mode</li></ul>
 
1053
                * @since 1.2
 
1054
                */
 
1055
                function SetDisplayMode($zoom, $layout='continuous') {
 
1056
                        //Set display mode in viewer
 
1057
                        if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom)) {
 
1058
                                $this->ZoomMode=$zoom;
 
1059
                        }
 
1060
                        else {
 
1061
                                $this->Error('Incorrect zoom display mode: '.$zoom);
 
1062
                        }
 
1063
                        if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='default') {
 
1064
                                $this->LayoutMode=$layout;
 
1065
                        }
 
1066
                        else {
 
1067
                                $this->Error('Incorrect layout display mode: '.$layout);
 
1068
                        }
 
1069
                }
 
1070
 
 
1071
                /**
 
1072
                * Activates or deactivates page compression. When activated, the internal representation of each page is compressed, which leads to a compression ratio of about 2 for the resulting document. Compression is on by default.
 
1073
                * Note: the Zlib extension is required for this feature. If not present, compression will be turned off.
 
1074
                * @param boolean $compress Boolean indicating if compression must be enabled.
 
1075
                * @since 1.4
 
1076
                */
 
1077
                function SetCompression($compress) {
 
1078
                        //Set page compression
 
1079
                        if(function_exists('gzcompress')) {
 
1080
                                $this->compress=$compress;
 
1081
                        }
 
1082
                        else {
 
1083
                                $this->compress=false;
 
1084
                        }
 
1085
                }
 
1086
 
 
1087
                /**
 
1088
                * Defines the title of the document.
 
1089
                * @param string $title The title.
 
1090
                * @since 1.2
 
1091
                * @see SetAuthor(), SetCreator(), SetKeywords(), SetSubject()
 
1092
                */
 
1093
                function SetTitle($title) {
 
1094
                        //Title of document
 
1095
                        $this->title=$title;
 
1096
                }
 
1097
 
 
1098
                /**
 
1099
                * Defines the subject of the document.
 
1100
                * @param string $subject The subject.
 
1101
                * @since 1.2
 
1102
                * @see SetAuthor(), SetCreator(), SetKeywords(), SetTitle()
 
1103
                */
 
1104
                function SetSubject($subject) {
 
1105
                        //Subject of document
 
1106
                        $this->subject=$subject;
 
1107
                }
 
1108
 
 
1109
                /**
 
1110
                * Defines the author of the document.
 
1111
                * @param string $author The name of the author.
 
1112
                * @since 1.2
 
1113
                * @see SetCreator(), SetKeywords(), SetSubject(), SetTitle()
 
1114
                */
 
1115
                function SetAuthor($author) {
 
1116
                        //Author of document
 
1117
                        $this->author=$author;
 
1118
                }
 
1119
 
 
1120
                /**
 
1121
                * Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'.
 
1122
                * @param string $keywords The list of keywords.
 
1123
                * @since 1.2
 
1124
                * @see SetAuthor(), SetCreator(), SetSubject(), SetTitle()
 
1125
                */
 
1126
                function SetKeywords($keywords) {
 
1127
                        //Keywords of document
 
1128
                        $this->keywords=$keywords;
 
1129
                }
 
1130
 
 
1131
                /**
 
1132
                * Defines the creator of the document. This is typically the name of the application that generates the PDF.
 
1133
                * @param string $creator The name of the creator.
 
1134
                * @since 1.2
 
1135
                * @see SetAuthor(), SetKeywords(), SetSubject(), SetTitle()
 
1136
                */
 
1137
                function SetCreator($creator) {
 
1138
                        //Creator of document
 
1139
                        $this->creator=$creator;
 
1140
                }
 
1141
 
 
1142
                /**
 
1143
                * Defines an alias for the total number of pages. It will be substituted as the document is closed.<br />
 
1144
                * <b>Example:</b><br />
 
1145
                * <pre>
 
1146
                * class PDF extends TCPDF {
 
1147
                *       function Footer() {
 
1148
                *               //Go to 1.5 cm from bottom
 
1149
                *               $this->SetY(-15);
 
1150
                *               //Select Arial italic 8
 
1151
                *               $this->SetFont('Arial','I',8);
 
1152
                *               //Print current and total page numbers
 
1153
                *               $this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
 
1154
                *       }
 
1155
                * }
 
1156
                * $pdf=new PDF();
 
1157
                * $pdf->AliasNbPages();
 
1158
                * </pre>
 
1159
                * @param string $alias The alias. Default value: {nb}.
 
1160
                * @since 1.4
 
1161
                * @see PageNo(), Footer()
 
1162
                */
 
1163
                function AliasNbPages($alias='{nb}') {
 
1164
                        //Define an alias for total number of pages
 
1165
                        $this->AliasNbPages = $this->_escapetext($alias);
 
1166
                }
 
1167
 
 
1168
                /**
 
1169
                * This method is automatically called in case of fatal error; it simply outputs the message and halts the execution. An inherited class may override it to customize the error handling but should always halt the script, or the resulting document would probably be invalid.
 
1170
                * 2004-06-11 :: Nicola Asuni : changed bold tag with strong
 
1171
                * @param string $msg The error message
 
1172
                * @since 1.0
 
1173
                */
 
1174
                function Error($msg) {
 
1175
                        //Fatal error
 
1176
                        die('<strong>TCPDF error: </strong>'.$msg);
 
1177
                }
 
1178
 
 
1179
                /**
 
1180
                * This method begins the generation of the PDF document. It is not necessary to call it explicitly because AddPage() does it automatically.
 
1181
                * Note: no page is created by this method
 
1182
                * @since 1.0
 
1183
                * @see AddPage(), Close()
 
1184
                */
 
1185
                function Open() {
 
1186
                        //Begin document
 
1187
                        $this->state=1;
 
1188
                }
 
1189
 
 
1190
                /**
 
1191
                * Terminates the PDF document. It is not necessary to call this method explicitly because Output() does it automatically. If the document contains no page, AddPage() is called to prevent from getting an invalid document.
 
1192
                * @since 1.0
 
1193
                * @see Open(), Output()
 
1194
                */
 
1195
                function Close() {
 
1196
                        //Terminate document
 
1197
                        if($this->state==3) {
 
1198
                                return;
 
1199
                        }
 
1200
                        if($this->page==0) {
 
1201
                                $this->AddPage();
 
1202
                        }
 
1203
                        //Page footer
 
1204
                        $this->InFooter=true;
 
1205
                        $this->Footer();
 
1206
                        $this->InFooter=false;
 
1207
                        //Close page
 
1208
                        $this->_endpage();
 
1209
                        //Close document
 
1210
                        $this->_enddoc();
 
1211
                }
 
1212
 
 
1213
                /**
 
1214
                * Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer. Then the page is added, the current position set to the top-left corner according to the left and top margins, and Header() is called to display the header.
 
1215
                * The font which was set before calling is automatically restored. There is no need to call SetFont() again if you want to continue with the same font. The same is true for colors and line width.
 
1216
                * The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.
 
1217
                * @param string $orientation Page orientation. Possible values are (case insensitive):<ul><li>P or Portrait</li><li>L or Landscape</li></ul> The default value is the one passed to the constructor.
 
1218
                * @since 1.0
 
1219
                * @see TCPDF(), Header(), Footer(), SetMargins()
 
1220
                */
 
1221
                function AddPage($orientation='') {
 
1222
                        //Start a new page
 
1223
                        if($this->state==0) {
 
1224
                                $this->Open();
 
1225
                        }
 
1226
                        $family=$this->FontFamily;
 
1227
                        $style=$this->FontStyle.($this->underline ? 'U' : '');
 
1228
                        $size=$this->FontSizePt;
 
1229
                        $lw=$this->LineWidth;
 
1230
                        $dc=$this->DrawColor;
 
1231
                        $fc=$this->FillColor;
 
1232
                        $tc=$this->TextColor;
 
1233
                        $cf=$this->ColorFlag;
 
1234
                        if($this->page>0) {
 
1235
                                //Page footer
 
1236
                                $this->InFooter=true;
 
1237
                                $this->Footer();
 
1238
                                $this->InFooter=false;
 
1239
                                //Close page
 
1240
                                $this->_endpage();
 
1241
                        }
 
1242
                        //Start new page
 
1243
                        $this->_beginpage($orientation);
 
1244
                        //Set line cap style to square
 
1245
                        $this->_out('2 J');
 
1246
                        //Set line width
 
1247
                        $this->LineWidth=$lw;
 
1248
                        $this->_out(sprintf('%.2f w',$lw*$this->k));
 
1249
                        //Set font
 
1250
                        if($family) {
 
1251
                                $this->SetFont($family,$style,$size);
 
1252
                        }
 
1253
                        //Set colors
 
1254
                        $this->DrawColor=$dc;
 
1255
                        if($dc!='0 G') {
 
1256
                                $this->_out($dc);
 
1257
                        }
 
1258
                        $this->FillColor=$fc;
 
1259
                        if($fc!='0 g') {
 
1260
                                $this->_out($fc);
 
1261
                        }
 
1262
                        $this->TextColor=$tc;
 
1263
                        $this->ColorFlag=$cf;
 
1264
                        //Page header
 
1265
                        $this->Header();
 
1266
                        //Restore line width
 
1267
                        if($this->LineWidth!=$lw) {
 
1268
                                $this->LineWidth=$lw;
 
1269
                                $this->_out(sprintf('%.2f w',$lw*$this->k));
 
1270
                        }
 
1271
                        //Restore font
 
1272
                        if($family) {
 
1273
                                $this->SetFont($family,$style,$size);
 
1274
                        }
 
1275
                        //Restore colors
 
1276
                        if($this->DrawColor!=$dc) {
 
1277
                                $this->DrawColor=$dc;
 
1278
                                $this->_out($dc);
 
1279
                        }
 
1280
                        if($this->FillColor!=$fc) {
 
1281
                                $this->FillColor=$fc;
 
1282
                                $this->_out($fc);
 
1283
                        }
 
1284
                        $this->TextColor=$tc;
 
1285
                        $this->ColorFlag=$cf;
 
1286
                }
 
1287
                
 
1288
                
 
1289
                
 
1290
                /**
 
1291
                 * Set header data.
 
1292
                 * @param string $ln header image logo
 
1293
                 * @param string $lw header image logo width in mm
 
1294
                 * @param string $ht string to print as title on document header
 
1295
                 * @param string $hs string to print on document header
 
1296
                */
 
1297
                function setHeaderData($ln="", $lw=0, $ht="", $hs="") {
 
1298
                        $this->header_logo = $ln;
 
1299
                        $this->header_logo_width = $lw;
 
1300
                        $this->header_title = $ht;
 
1301
                        $this->header_string = $hs;
 
1302
                }
 
1303
                
 
1304
                /**
 
1305
                 * Set header margin.
 
1306
                 * (minimum distance between header and top page margin)
 
1307
                 * @param int $hm distance in millimeters
 
1308
                */
 
1309
                function setHeaderMargin($hm=10) {
 
1310
                        $this->header_margin = $hm;
 
1311
                }
 
1312
                
 
1313
                /**
 
1314
                 * Set footer margin.
 
1315
                 * (minimum distance between footer and bottom page margin)
 
1316
                 * @param int $fm distance in millimeters
 
1317
                */
 
1318
                function setFooterMargin($fm=10) {
 
1319
                        $this->footer_margin = $fm;
 
1320
                }
 
1321
                
 
1322
                /**
 
1323
                 * This method is used to render the page header.
 
1324
                 * It is automatically called by AddPage() and could be overwritten in your own inherited class.
 
1325
                 */
 
1326
                function Header() {
 
1327
                        if ($this->print_header) {
 
1328
                                
 
1329
                                if (!isset($this->original_lMargin)) {
 
1330
                                        $this->original_lMargin = $this->lMargin;
 
1331
                                }
 
1332
                                if (!isset($this->original_rMargin)) {
 
1333
                                        $this->original_rMargin = $this->rMargin;
 
1334
                                }
 
1335
                                
 
1336
                                //set current position
 
1337
                                $this->SetXY($this->original_lMargin, $this->header_margin);
 
1338
                                
 
1339
                                if (($this->header_logo) AND ($this->header_logo != K_BLANK_IMAGE)) {
 
1340
                                        $this->Image(K_PATH_IMAGES.$this->header_logo, $this->original_lMargin, $this->header_margin, $this->header_logo_width);
 
1341
                                }
 
1342
                                else {
 
1343
                                        $this->img_rb_y = $this->GetY();
 
1344
                                }
 
1345
                                
 
1346
                                $cell_height = round((K_CELL_HEIGHT_RATIO * $this->header_font[2]) / $this->k, 2);
 
1347
                                
 
1348
                                $header_x = $this->original_lMargin + ($this->header_logo_width * 1.05); //set left margin for text data cell
 
1349
                                
 
1350
                                // header title
 
1351
                                $this->SetFont($this->header_font[0], 'B', $this->header_font[2] + 1);
 
1352
                                $this->SetX($header_x);
 
1353
                                $this->Cell($this->header_width, $cell_height, $this->header_title, 0, 1, 'L'); 
 
1354
                                
 
1355
                                // header string
 
1356
                                $this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]);
 
1357
                                $this->SetX($header_x);
 
1358
                                $this->MultiCell($this->header_width, $cell_height, $this->header_string, 0, 'L', 0);
 
1359
                                
 
1360
                                // print an ending header line
 
1361
                                if (empty($this->header_width)) {
 
1362
                                        //set style for cell border
 
1363
                                        $this->SetLineWidth(0.3);
 
1364
                                        $this->SetDrawColor(0, 0, 0);
 
1365
                                        $this->SetY(1 + max($this->img_rb_y, $this->GetY()));
 
1366
                                        $this->SetX($this->original_lMargin);
 
1367
                                        $this->Cell(0, 0, '', 'T', 0, 'C'); 
 
1368
                                }
 
1369
                                
 
1370
                                //restore position
 
1371
                                $this->SetXY($this->original_lMargin, $this->tMargin);
 
1372
                        }
 
1373
                }
 
1374
                
 
1375
                /**
 
1376
                 * This method is used to render the page footer. 
 
1377
                 * It is automatically called by AddPage() and could be overwritten in your own inherited class.
 
1378
                 */
 
1379
                function Footer() {
 
1380
                        if ($this->print_footer) {
 
1381
                                
 
1382
                                if (!isset($this->original_lMargin)) {
 
1383
                                        $this->original_lMargin = $this->lMargin;
 
1384
                                }
 
1385
                                if (!isset($this->original_rMargin)) {
 
1386
                                        $this->original_rMargin = $this->rMargin;
 
1387
                                }
 
1388
                                
 
1389
                                //set font
 
1390
                                $this->SetFont($this->footer_font[0], $this->footer_font[1] , $this->footer_font[2]);
 
1391
                                //set style for cell border
 
1392
                                $line_width = 0.3;
 
1393
                                $this->SetLineWidth($line_width);
 
1394
                                $this->SetDrawColor(0, 0, 0);
 
1395
                                
 
1396
                                $footer_height = round((K_CELL_HEIGHT_RATIO * $this->footer_font[2]) / $this->k, 2); //footer height
 
1397
                                //get footer y position
 
1398
                                $footer_y = $this->h - $this->footer_margin - $footer_height;
 
1399
                                //set current position
 
1400
                                $this->SetXY($this->original_lMargin, $footer_y); 
 
1401
                                
 
1402
                                //print document barcode
 
1403
                                if ($this->barcode) {
 
1404
                                        $this->Ln();
 
1405
                                        $barcode_width = round(($this->w - $this->original_lMargin - $this->original_rMargin)); //max width
 
1406
                                        $this->writeBarcode($this->original_lMargin, $footer_y + $line_width, $barcode_width, $footer_height - $line_width, "C128B", false, false, 2, $this->barcode);
 
1407
                                }
 
1408
                                
 
1409
                                $this->SetXY($this->original_lMargin, $footer_y); 
 
1410
                                
 
1411
                                //Print page number
 
1412
                                $this->Cell(0, $footer_height, $this->l['w_page']." ".$this->PageNo().' / {nb}', 'T', 0, 'R'); 
 
1413
                        }
 
1414
                }
 
1415
                
 
1416
                /**
 
1417
                * Returns the current page number.
 
1418
                * @return int page number
 
1419
                * @since 1.0
 
1420
                * @see AliasNbPages()
 
1421
                */
 
1422
                function PageNo() {
 
1423
                        //Get current page number
 
1424
                        return $this->page;
 
1425
                }
 
1426
 
 
1427
                /**
 
1428
                * Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
 
1429
                * @param int $r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
 
1430
                * @param int $g Green component (between 0 and 255)
 
1431
                * @param int $b Blue component (between 0 and 255)
 
1432
                * @since 1.3
 
1433
                * @see SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell()
 
1434
                */
 
1435
                function SetDrawColor($r, $g=-1, $b=-1) {
 
1436
                        //Set color for all stroking operations
 
1437
                        if(($r==0 and $g==0 and $b==0) or $g==-1) {
 
1438
                                $this->DrawColor=sprintf('%.3f G',$r/255);
 
1439
                        }
 
1440
                        else {
 
1441
                                $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
 
1442
                        }
 
1443
                        if($this->page>0) {
 
1444
                                $this->_out($this->DrawColor);
 
1445
                        }
 
1446
                }
 
1447
 
 
1448
                /**
 
1449
                * Defines the color used for all filling operations (filled rectangles and cell backgrounds). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
 
1450
                * @param int $r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
 
1451
                * @param int $g Green component (between 0 and 255)
 
1452
                * @param int $b Blue component (between 0 and 255)
 
1453
                * @param boolean $storeprev if true stores the RGB array on $prevFillColor variable.
 
1454
                * @since 1.3
 
1455
                * @see SetDrawColor(), SetTextColor(), Rect(), Cell(), MultiCell()
 
1456
                */
 
1457
                function SetFillColor($r, $g=-1, $b=-1, $storeprev=false) {
 
1458
                        //Set color for all filling operations
 
1459
                        if(($r==0 and $g==0 and $b==0) or $g==-1) {
 
1460
                                $this->FillColor=sprintf('%.3f g',$r/255);
 
1461
                        }
 
1462
                        else {
 
1463
                                $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
 
1464
                        }
 
1465
                        $this->ColorFlag=($this->FillColor!=$this->TextColor);
 
1466
                        if($this->page>0) {
 
1467
                                $this->_out($this->FillColor);
 
1468
                        }
 
1469
                        if ($storeprev) {
 
1470
                                // store color as previous value
 
1471
                                $this->prevFillColor = array($r, $g, $b);
 
1472
                        }
 
1473
                }
 
1474
 
 
1475
                /**
 
1476
                * Defines the color used for text. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
 
1477
                * @param int $r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
 
1478
                * @param int $g Green component (between 0 and 255)
 
1479
                * @param int $b Blue component (between 0 and 255)
 
1480
                * @param boolean $storeprev if true stores the RGB array on $prevTextColor variable.
 
1481
                * @since 1.3
 
1482
                * @see SetDrawColor(), SetFillColor(), Text(), Cell(), MultiCell()
 
1483
                */
 
1484
                function SetTextColor($r, $g=-1, $b=-1, $storeprev=false) {
 
1485
                        //Set color for text
 
1486
                        if(($r==0 and $g==0 and $b==0) or $g==-1) {
 
1487
                                $this->TextColor=sprintf('%.3f g',$r/255);
 
1488
                        }
 
1489
                        else {
 
1490
                                $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
 
1491
                        }
 
1492
                        $this->ColorFlag=($this->FillColor!=$this->TextColor);
 
1493
                        if ($storeprev) {
 
1494
                                // store color as previous value
 
1495
                                $this->prevTextColor = array($r, $g, $b);
 
1496
                        }
 
1497
                }
 
1498
 
 
1499
                /**
 
1500
                * Returns the length of a string in user unit. A font must be selected.<br>
 
1501
                * Support UTF-8 Unicode [Nicola Asuni, 2005-01-02]
 
1502
                * @param string $s The string whose length is to be computed
 
1503
                * @return int
 
1504
                * @since 1.2
 
1505
                */
 
1506
                function GetStringWidth($s) {
 
1507
                        //Get width of a string in the current font
 
1508
                        $s = (string)$s;
 
1509
                        $cw = &$this->CurrentFont['cw'];
 
1510
                        $w = 0;
 
1511
                        if($this->isunicode) {
 
1512
                                $unicode = $this->UTF8StringToArray($s);
 
1513
                                foreach($unicode as $char) {
 
1514
                                        if (isset($cw[$char])) {
 
1515
                                                $w+=$cw[$char];
 
1516
                                        } elseif(isset($cw[ord($char)])) {
 
1517
                                                $w+=$cw[ord($char)];
 
1518
                                        } elseif(isset($cw[chr($char)])) {
 
1519
                                                $w+=$cw[chr($char)];
 
1520
                                        } elseif(isset($this->CurrentFont['desc']['MissingWidth'])) {
 
1521
                                                $w += $this->CurrentFont['desc']['MissingWidth']; // set default size
 
1522
                                        } else {
 
1523
                                                $w += 500;
 
1524
                                        }
 
1525
                                }
 
1526
                        } else {
 
1527
                                $l = strlen($s);
 
1528
                                for($i=0; $i<$l; $i++) {
 
1529
                                        if (isset($cw[$s{$i}])) {
 
1530
                                                $w += $cw[$s{$i}];
 
1531
                                        } else if (isset($cw[ord($s{$i})])) {
 
1532
                                                $w += $cw[ord($s{$i})];
 
1533
                                        }
 
1534
                                }
 
1535
                        }
 
1536
                        return ($w * $this->FontSize / 1000);
 
1537
                }
 
1538
 
 
1539
                /**
 
1540
                * Defines the line width. By default, the value equals 0.2 mm. The method can be called before the first page is created and the value is retained from page to page.
 
1541
                * @param float $width The width.
 
1542
                * @since 1.0
 
1543
                * @see Line(), Rect(), Cell(), MultiCell()
 
1544
                */
 
1545
                function SetLineWidth($width) {
 
1546
                        //Set line width
 
1547
                        $this->LineWidth=$width;
 
1548
                        if($this->page>0) {
 
1549
                                $this->_out(sprintf('%.2f w',$width*$this->k));
 
1550
                        }
 
1551
                }
 
1552
 
 
1553
                /**
 
1554
                * Draws a line between two points.
 
1555
                * @param float $x1 Abscissa of first point
 
1556
                * @param float $y1 Ordinate of first point
 
1557
                * @param float $x2 Abscissa of second point
 
1558
                * @param float $y2 Ordinate of second point
 
1559
                * @since 1.0
 
1560
                * @see SetLineWidth(), SetDrawColor()
 
1561
                */
 
1562
                function Line($x1, $y1, $x2, $y2) {
 
1563
                        //Draw a line
 
1564
                        $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));
 
1565
                }
 
1566
 
 
1567
                /**
 
1568
                * Outputs a rectangle. It can be drawn (border only), filled (with no border) or both.
 
1569
                * @param float $x Abscissa of upper-left corner
 
1570
                * @param float $y Ordinate of upper-left corner
 
1571
                * @param float $w Width
 
1572
                * @param float $h Height
 
1573
                * @param string $style Style of rendering. Possible values are:<ul><li>D or empty string: draw (default)</li><li>F: fill</li><li>DF or FD: draw and fill</li></ul>
 
1574
                * @since 1.0
 
1575
                * @see SetLineWidth(), SetDrawColor(), SetFillColor()
 
1576
                */
 
1577
                function Rect($x, $y, $w, $h, $style='') {
 
1578
                        //Draw a rectangle
 
1579
                        if($style=='F') {
 
1580
                                $op='f';
 
1581
                        }
 
1582
                        elseif($style=='FD' or $style=='DF') {
 
1583
                                $op='B';
 
1584
                        }
 
1585
                        else {
 
1586
                                $op='S';
 
1587
                        }
 
1588
                        $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
 
1589
                }
 
1590
 
 
1591
                /**
 
1592
                * Imports a TrueType or Type1 font and makes it available. It is necessary to generate a font definition file first with the makefont.php utility. The definition file (and the font file itself when embedding) must be present either in the current directory or in the one indicated by FPDF_FONTPATH if the constant is defined. If it could not be found, the error "Could not include font definition file" is generated.
 
1593
                * Support UTF-8 Unicode [Nicola Asuni, 2005-01-02].
 
1594
                * <b>Example</b>:<br />
 
1595
                * <pre>
 
1596
                * $pdf->AddFont('Comic','I');
 
1597
                * // is equivalent to:
 
1598
                * $pdf->AddFont('Comic','I','comici.php');
 
1599
                * </pre>
 
1600
                * @param string $family Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
 
1601
                * @param string $style Font style. Possible values are (case insensitive):<ul><li>empty string: regular (default)</li><li>B: bold</li><li>I: italic</li><li>BI or IB: bold italic</li></ul>
 
1602
                * @param string $file The font definition file. By default, the name is built from the family and style, in lower case with no space.
 
1603
                * @since 1.5
 
1604
                * @see SetFont()
 
1605
                */
 
1606
                function AddFont($family, $style='', $file='') {
 
1607
                        if(empty($family)) {
 
1608
                                return;
 
1609
                        }
 
1610
 
 
1611
                        //Add a TrueType or Type1 font
 
1612
                        $family = strtolower($family);
 
1613
                        if((!$this->isunicode) AND ($family == 'arial')) {
 
1614
                                $family = 'helvetica';
 
1615
                        }
 
1616
 
 
1617
                        $style=strtoupper($style);
 
1618
                        $style=str_replace('U','',$style);
 
1619
                        if($style == 'IB') {
 
1620
                                $style = 'BI';
 
1621
                        }
 
1622
 
 
1623
                        $fontkey = $family.$style;
 
1624
                        // check if the font has been already added
 
1625
                        if(isset($this->fonts[$fontkey])) {
 
1626
                                return;
 
1627
                        }
 
1628
 
 
1629
                        if($file=='') {
 
1630
                                $file = str_replace(' ', '', $family).strtolower($style).'.php';
 
1631
                        }
 
1632
                        if(!file_exists($this->_getfontpath().$file)) {
 
1633
                                // try to load the basic file without styles
 
1634
                                $file = str_replace(' ', '', $family).'.php';
 
1635
                        }
 
1636
 
 
1637
                        include($this->_getfontpath().$file);
 
1638
 
 
1639
                        if(!isset($name) AND !isset($fpdf_charwidths)) {
 
1640
                                $this->Error('Could not include font definition file');
 
1641
                        }
 
1642
 
 
1643
                        $i = count($this->fonts)+1;
 
1644
 
 
1645
                        if($this->isunicode) {
 
1646
                                $this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'enc'=>$enc, 'file'=>$file, 'ctg'=>$ctg);
 
1647
                                $fpdf_charwidths[$fontkey] = $cw;
 
1648
                        } else {
 
1649
                                $this->fonts[$fontkey]=array('i'=>$i, 'type'=>'core', 'name'=>$this->CoreFonts[$fontkey], 'up'=>-100, 'ut'=>50, 'cw'=>$fpdf_charwidths[$fontkey]);
 
1650
                        }
 
1651
 
 
1652
                        if(isset($diff) AND (!empty($diff))) {
 
1653
                                //Search existing encodings
 
1654
                                $d=0;
 
1655
                                $nb=count($this->diffs);
 
1656
                                for($i=1;$i<=$nb;$i++) {
 
1657
                                        if($this->diffs[$i]==$diff) {
 
1658
                                                $d=$i;
 
1659
                                                break;
 
1660
                                        }
 
1661
                                }
 
1662
                                if($d==0) {
 
1663
                                        $d=$nb+1;
 
1664
                                        $this->diffs[$d]=$diff;
 
1665
                                }
 
1666
                                $this->fonts[$fontkey]['diff']=$d;
 
1667
                        }
 
1668
                        if(!empty($file)) {
 
1669
                                if((strcasecmp($type,"TrueType") == 0) OR (strcasecmp($type,"TrueTypeUnicode") == 0)) {
 
1670
                                        $this->FontFiles[$file]=array('length1'=>$originalsize);
 
1671
                                }
 
1672
                                else {
 
1673
                                        $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
 
1674
                                }
 
1675
                        }
 
1676
                }
 
1677
 
 
1678
                /**
 
1679
                * Sets the font used to print character strings. It is mandatory to call this method at least once before printing text or the resulting document would not be valid.
 
1680
                * The font can be either a standard one or a font added via the AddFont() method. Standard fonts use Windows encoding cp1252 (Western Europe).
 
1681
                * The method can be called before the first page is created and the font is retained from page to page.
 
1682
                If you just wish to change the current font size, it is simpler to call SetFontSize().
 
1683
                * Note: for the standard fonts, the font metric files must be accessible. There are three possibilities for this:<ul><li>They are in the current directory (the one where the running script lies)</li><li>They are in one of the directories defined by the include_path parameter</li><li>They are in the directory defined by the FPDF_FONTPATH constant</li></ul><br />
 
1684
                * Example for the last case (note the trailing slash):<br />
 
1685
                * <pre>
 
1686
                * define('FPDF_FONTPATH','/home/www/font/');
 
1687
                * require('tcpdf.php');
 
1688
                *
 
1689
                * //Times regular 12
 
1690
                * $pdf->SetFont('Times');
 
1691
                * //Arial bold 14
 
1692
                * $pdf->SetFont('Arial','B',14);
 
1693
                * //Removes bold
 
1694
                * $pdf->SetFont('');
 
1695
                * //Times bold, italic and underlined 14
 
1696
                * $pdf->SetFont('Times','BIU');
 
1697
                * </pre><br />
 
1698
                * If the file corresponding to the requested font is not found, the error "Could not include font metric file" is generated.
 
1699
                * @param string $family Family font. It can be either a name defined by AddFont() or one of the standard families (case insensitive):<ul><li>Courier (fixed-width)</li><li>Helvetica or Arial (synonymous; sans serif)</li><li>Times (serif)</li><li>Symbol (symbolic)</li><li>ZapfDingbats (symbolic)</li></ul>It is also possible to pass an empty string. In that case, the current family is retained.
 
1700
                * @param string $style Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li></ul>or any combination. The default value is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats
 
1701
                * @param float $size Font size in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12
 
1702
                * @since 1.0
 
1703
                * @see AddFont(), SetFontSize(), Cell(), MultiCell(), Write()
 
1704
                */
 
1705
                function SetFont($family, $style='', $size=0) {
 
1706
                        // save previous values
 
1707
                        $this->prevFontFamily = $this->FontFamily;
 
1708
                        $this->prevFontStyle = $this->FontStyle;
 
1709
 
 
1710
                        //Select a font; size given in points
 
1711
                        global $fpdf_charwidths;
 
1712
 
 
1713
                        $family=strtolower($family);
 
1714
                        if($family=='') {
 
1715
                                $family=$this->FontFamily;
 
1716
                        }
 
1717
                        if((!$this->isunicode) AND ($family == 'arial')) {
 
1718
                                $family = 'helvetica';
 
1719
                        }
 
1720
                        elseif(($family=="symbol") OR ($family=="zapfdingbats")) {
 
1721
                                $style='';
 
1722
                        }
 
1723
                        $style=strtoupper($style);
 
1724
 
 
1725
                        if(strpos($style,'U')!==false) {
 
1726
                                $this->underline=true;
 
1727
                                $style=str_replace('U','',$style);
 
1728
                        }
 
1729
                        else {
 
1730
                                $this->underline=false;
 
1731
                        }
 
1732
                        if($style=='IB') {
 
1733
                                $style='BI';
 
1734
                        }
 
1735
                        if($size==0) {
 
1736
                                $size=$this->FontSizePt;
 
1737
                        }
 
1738
 
 
1739
                        // try to add font (if not already added)
 
1740
                        if($this->isunicode) {
 
1741
                                $this->AddFont($family, $style);
 
1742
                        }
 
1743
                        
 
1744
                        //Test if font is already selected
 
1745
                        if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size)) {
 
1746
                                return;
 
1747
                        }
 
1748
                        
 
1749
                        $fontkey = $family.$style;
 
1750
                        //if(!isset($this->fonts[$fontkey]) AND isset($this->fonts[$family])) {
 
1751
                        //      $style='';
 
1752
                        //}
 
1753
 
 
1754
                        //Test if used for the first time
 
1755
                        if(!isset($this->fonts[$fontkey])) {
 
1756
                                //Check if one of the standard fonts
 
1757
                                if(isset($this->CoreFonts[$fontkey])) {
 
1758
                                        if(!isset($fpdf_charwidths[$fontkey])) {
 
1759
                                                //Load metric file
 
1760
                                                $file = $family;
 
1761
                                                if(($family!='symbol') AND ($family!='zapfdingbats')) {
 
1762
                                                        $file .= strtolower($style);
 
1763
                                                }
 
1764
                                                if(!file_exists($this->_getfontpath().$file.'.php')) {
 
1765
                                                        // try to load the basic file without styles
 
1766
                                                        $file = $family;
 
1767
                                                        $fontkey = $family;
 
1768
                                                }
 
1769
                                                include($this->_getfontpath().$file.'.php');
 
1770
                                                if (($this->isunicode AND !isset($ctg)) OR ((!$this->isunicode) AND (!isset($fpdf_charwidths[$fontkey]))) ) {
 
1771
                                                        $this->Error("Could not include font metric file [".$fontkey."]: ".$this->_getfontpath().$file.".php");
 
1772
                                                }
 
1773
                                        }
 
1774
                                        $i = count($this->fonts) + 1;
 
1775
 
 
1776
                                        if($this->isunicode) {
 
1777
                                                $this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'enc'=>$enc, 'file'=>$file, 'ctg'=>$ctg);
 
1778
                                                $fpdf_charwidths[$fontkey] = $cw;
 
1779
                                        } else {
 
1780
                                                $this->fonts[$fontkey]=array('i'=>$i, 'type'=>'core', 'name'=>$this->CoreFonts[$fontkey], 'up'=>-100, 'ut'=>50, 'cw'=>$fpdf_charwidths[$fontkey]);
 
1781
                                        }
 
1782
                                }
 
1783
                                else {
 
1784
                                        $this->Error('Undefined font: '.$family.' '.$style);
 
1785
                                }
 
1786
                        }
 
1787
                        //Select it
 
1788
                        $this->FontFamily = $family;
 
1789
                        $this->FontStyle = $style;
 
1790
                        $this->FontSizePt = $size;
 
1791
                        $this->FontSize = $size / $this->k;
 
1792
                        $this->CurrentFont = &$this->fonts[$fontkey];
 
1793
                        if($this->page>0) {
 
1794
                                $this->_out(sprintf('BT /F%d %.2f Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
 
1795
                        }
 
1796
                }
 
1797
 
 
1798
                /**
 
1799
                * Defines the size of the current font.
 
1800
                * @param float $size The size (in points)
 
1801
                * @since 1.0
 
1802
                * @see SetFont()
 
1803
                */
 
1804
                function SetFontSize($size) {
 
1805
                        //Set font size in points
 
1806
                        if($this->FontSizePt==$size) {
 
1807
                                return;
 
1808
                        }
 
1809
                        $this->FontSizePt = $size;
 
1810
                        $this->FontSize = $size / $this->k;
 
1811
                        if($this->page > 0) {
 
1812
                                $this->_out(sprintf('BT /F%d %.2f Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
 
1813
                        }
 
1814
                }
 
1815
 
 
1816
                /**
 
1817
                * Creates a new internal link and returns its identifier. An internal link is a clickable area which directs to another place within the document.<br />
 
1818
                * The identifier can then be passed to Cell(), Write(), Image() or Link(). The destination is defined with SetLink().
 
1819
                * @since 1.5
 
1820
                * @see Cell(), Write(), Image(), Link(), SetLink()
 
1821
                */
 
1822
                function AddLink() {
 
1823
                        //Create a new internal link
 
1824
                        $n=count($this->links)+1;
 
1825
                        $this->links[$n]=array(0,0);
 
1826
                        return $n;
 
1827
                }
 
1828
 
 
1829
                /**
 
1830
                * Defines the page and position a link points to
 
1831
                * @param int $link The link identifier returned by AddLink()
 
1832
                * @param float $y Ordinate of target position; -1 indicates the current position. The default value is 0 (top of page)
 
1833
                * @param int $page Number of target page; -1 indicates the current page. This is the default value
 
1834
                * @since 1.5
 
1835
                * @see AddLink()
 
1836
                */
 
1837
                function SetLink($link, $y=0, $page=-1) {
 
1838
                        //Set destination of internal link
 
1839
                        if($y==-1) {
 
1840
                                $y=$this->y;
 
1841
                        }
 
1842
                        if($page==-1) {
 
1843
                                $page=$this->page;
 
1844
                        }
 
1845
                        $this->links[$link]=array($page,$y);
 
1846
                }
 
1847
 
 
1848
                /**
 
1849
                * Puts a link on a rectangular area of the page. Text or image links are generally put via Cell(), Write() or Image(), but this method can be useful for instance to define a clickable area inside an image.
 
1850
                * @param float $x Abscissa of the upper-left corner of the rectangle
 
1851
                * @param float $y Ordinate of the upper-left corner of the rectangle
 
1852
                * @param float $w Width of the rectangle
 
1853
                * @param float $h Height of the rectangle
 
1854
                * @param mixed $link URL or identifier returned by AddLink()
 
1855
                * @since 1.5
 
1856
                * @see AddLink(), Cell(), Write(), Image()
 
1857
                */
 
1858
                function Link($x, $y, $w, $h, $link) {
 
1859
                        //Put a link on the page
 
1860
                        $this->PageLinks[$this->page][] = array($x * $this->k, $this->hPt - $y * $this->k, $w * $this->k, $h*$this->k, $link);
 
1861
                }
 
1862
 
 
1863
                /**
 
1864
                * Prints a character string. The origin is on the left of the first charcter, on the baseline. This method allows to place a string precisely on the page, but it is usually easier to use Cell(), MultiCell() or Write() which are the standard methods to print text.
 
1865
                * @param float $x Abscissa of the origin
 
1866
                * @param float $y Ordinate of the origin
 
1867
                * @param string $txt String to print
 
1868
                * @since 1.0
 
1869
                * @see SetFont(), SetTextColor(), Cell(), MultiCell(), Write()
 
1870
                */
 
1871
                function Text($x, $y, $txt) {
 
1872
                        //Output a string
 
1873
                        $s=sprintf('BT %.2f %.2f Td (%s) Tj ET', $x * $this->k, ($this->h-$y) * $this->k, $this->_escapetext($txt));
 
1874
                        if($this->underline AND ($txt!='')) {
 
1875
                                $s .= ' '.$this->_dounderline($x,$y,$txt);
 
1876
                        }
 
1877
                        if($this->ColorFlag) {
 
1878
                                $s='q '.$this->TextColor.' '.$s.' Q';
 
1879
                        }
 
1880
                        $this->_out($s);
 
1881
                }
 
1882
 
 
1883
                /**
 
1884
                * Whenever a page break condition is met, the method is called, and the break is issued or not depending on the returned value. The default implementation returns a value according to the mode selected by SetAutoPageBreak().<br />
 
1885
                * This method is called automatically and should not be called directly by the application.<br />
 
1886
                * <b>Example:</b><br />
 
1887
                * The method is overriden in an inherited class in order to obtain a 3 column layout:<br />
 
1888
                * <pre>
 
1889
                * class PDF extends TCPDF {
 
1890
                *       var $col=0;
 
1891
                *
 
1892
                *       function SetCol($col) {
 
1893
                *               //Move position to a column
 
1894
                *               $this->col=$col;
 
1895
                *               $x=10+$col*65;
 
1896
                *               $this->SetLeftMargin($x);
 
1897
                *               $this->SetX($x);
 
1898
                *       }
 
1899
                *
 
1900
                *       function AcceptPageBreak() {
 
1901
                *               if($this->col<2) {
 
1902
                *                       //Go to next column
 
1903
                *                       $this->SetCol($this->col+1);
 
1904
                *                       $this->SetY(10);
 
1905
                *                       return false;
 
1906
                *               }
 
1907
                *               else {
 
1908
                *                       //Go back to first column and issue page break
 
1909
                *                       $this->SetCol(0);
 
1910
                *                       return true;
 
1911
                *               }
 
1912
                *       }
 
1913
                * }
 
1914
                *
 
1915
                * $pdf=new PDF();
 
1916
                * $pdf->Open();
 
1917
                * $pdf->AddPage();
 
1918
                * $pdf->SetFont('Arial','',12);
 
1919
                * for($i=1;$i<=300;$i++) {
 
1920
                *     $pdf->Cell(0,5,"Line $i",0,1);
 
1921
                * }
 
1922
                * $pdf->Output();
 
1923
                * </pre>
 
1924
                * @return boolean
 
1925
                * @since 1.4
 
1926
                * @see SetAutoPageBreak()
 
1927
                */
 
1928
                function AcceptPageBreak() {
 
1929
                        //Accept automatic page break or not
 
1930
                        return $this->AutoPageBreak;
 
1931
                }
 
1932
 
 
1933
                /**
 
1934
                * Prints a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.<br />
 
1935
                * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
 
1936
                * @param float $w Cell width. If 0, the cell extends up to the right margin.
 
1937
                * @param float $h Cell height. Default value: 0.
 
1938
                * @param string $txt String to print. Default value: empty string.
 
1939
                * @param mixed $border Indicates if borders must be drawn around the cell. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
 
1940
                * @param int $ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
 
1941
                Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
 
1942
                * @param string $align Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li></ul>
 
1943
                * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
 
1944
                * @param mixed $link URL or identifier returned by AddLink().
 
1945
                * @since 1.0
 
1946
                * @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), AddLink(), Ln(), MultiCell(), Write(), SetAutoPageBreak()
 
1947
                */
 
1948
                function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=0, $link='') {
 
1949
                        //Output a cell
 
1950
                        $k=$this->k;
 
1951
                        if(($this->y + $h) > $this->PageBreakTrigger AND empty($this->InFooter) AND $this->AcceptPageBreak()) {
 
1952
                                //Automatic page break
 
1953
                                $x = $this->x;
 
1954
                                $ws = $this->ws;
 
1955
                                if($ws > 0) {
 
1956
                                        $this->ws = 0;
 
1957
                                        $this->_out('0 Tw');
 
1958
                                }
 
1959
                                $this->AddPage($this->CurOrientation);
 
1960
                                $this->x = $x;
 
1961
                                if($ws > 0) {
 
1962
                                        $this->ws = $ws;
 
1963
                                        $this->_out(sprintf('%.3f Tw',$ws * $k));
 
1964
                                }
 
1965
                        }
 
1966
                        if($w == 0) {
 
1967
                                $w = $this->w - $this->rMargin - $this->x;
 
1968
                        }
 
1969
                        $s = '';
 
1970
                        if(($fill == 1) OR ($border == 1)) {
 
1971
                                if($fill == 1) {
 
1972
                                        $op = ($border == 1) ? 'B' : 'f';
 
1973
                                }
 
1974
                                else {
 
1975
                                        $op = 'S';
 
1976
                                }
 
1977
                                $s = sprintf('%.2f %.2f %.2f %.2f re %s ', $this->x * $k, ($this->h - $this->y) * $k, $w * $k, -$h * $k, $op);
 
1978
                        }
 
1979
                        if(is_string($border)) {
 
1980
                                $x=$this->x;
 
1981
                                $y=$this->y;
 
1982
                                if(strpos($border,'L')!==false) {
 
1983
                                        $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
 
1984
                                }
 
1985
                                if(strpos($border,'T')!==false) {
 
1986
                                        $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
 
1987
                                }
 
1988
                                if(strpos($border,'R')!==false) {
 
1989
                                        $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
 
1990
                                }
 
1991
                                if(strpos($border,'B')!==false) {
 
1992
                                        $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
 
1993
                                }
 
1994
                        }
 
1995
                        if($txt != '') {
 
1996
                                $width = $this->GetStringWidth($txt);
 
1997
                                if($align == 'R') {
 
1998
                                        $dx = $w - $this->cMargin - $width;
 
1999
                                }
 
2000
                                elseif($align=='C') {
 
2001
                                        $dx = ($w - $width)/2;
 
2002
                                }
 
2003
                                else {
 
2004
                                        $dx = $this->cMargin;
 
2005
                                }
 
2006
                                if($this->ColorFlag) {
 
2007
                                        $s .= 'q '.$this->TextColor.' ';
 
2008
                                }
 
2009
                                $txt2 = $this->_escapetext($txt);
 
2010
                                $s.=sprintf('BT %.2f %.2f Td (%s) Tj ET', ($this->x + $dx) * $k, ($this->h - ($this->y + 0.5 * $h + 0.3 * $this->FontSize)) * $k, $txt2);
 
2011
                                if($this->underline) {
 
2012
                                        $s.=' '.$this->_dounderline($this->x + $dx, $this->y + 0.5 * $h + 0.3 * $this->FontSize, $txt);
 
2013
                                }
 
2014
                                if($this->ColorFlag) {
 
2015
                                        $s.=' Q';
 
2016
                                }
 
2017
                                if($link) {
 
2018
                                        $this->Link($this->x + $dx, $this->y + 0.5 * $h - 0.5 * $this->FontSize, $width, $this->FontSize, $link);
 
2019
                                }
 
2020
                        }
 
2021
                        if($s) {
 
2022
                                $this->_out($s);
 
2023
                        }
 
2024
                        $this->lasth = $h;
 
2025
                        if($ln>0) {
 
2026
                                //Go to next line
 
2027
                                $this->y += $h;
 
2028
                                if($ln == 1) {
 
2029
                                        $this->x = $this->lMargin;
 
2030
                                }
 
2031
                        }
 
2032
                        else {
 
2033
                                $this->x += $w;
 
2034
                        }
 
2035
                }
 
2036
 
 
2037
                /**
 
2038
                * This method allows printing text with line breaks. They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the \n character). As many cells as necessary are output, one below the other.<br />
 
2039
                * Text can be aligned, centered or justified. The cell block can be framed and the background painted.
 
2040
                * @param float $w Width of cells. If 0, they extend up to the right margin of the page.
 
2041
                * @param float $h Height of cells.
 
2042
                * @param string $txt String to print
 
2043
                * @param mixed $border Indicates if borders must be drawn around the cell block. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
 
2044
                * @param string $align Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align</li><li>C: center</li><li>R: right align</li><li>J: justification (default value)</li></ul>
 
2045
                * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
 
2046
                * @since 1.3
 
2047
                * @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), Cell(), Write(), SetAutoPageBreak()
 
2048
                */
 
2049
                function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=0) {
 
2050
                        //Output text with automatic or explicit line breaks
 
2051
                        $cw = &$this->CurrentFont['cw'];
 
2052
 
 
2053
                        if($w == 0) {
 
2054
                                $w = $this->w - $this->rMargin - $this->x;
 
2055
                        }
 
2056
 
 
2057
                        $wmax = ($w - 2 * $this->cMargin);
 
2058
 
 
2059
                        $s = str_replace("\r", '', $txt); // remove carriage returns
 
2060
                        $nb = strlen($s);
 
2061
 
 
2062
                        $b=0;
 
2063
                        if($border) {
 
2064
                                if($border==1) {
 
2065
                                        $border='LTRB';
 
2066
                                        $b='LRT';
 
2067
                                        $b2='LR';
 
2068
                                }
 
2069
                                else {
 
2070
                                        $b2='';
 
2071
                                        if(strpos($border,'L')!==false) {
 
2072
                                                $b2.='L';
 
2073
                                        }
 
2074
                                        if(strpos($border,'R')!==false) {
 
2075
                                                $b2.='R';
 
2076
                                        }
 
2077
                                        $b=(strpos($border,'T')!==false) ? $b2.'T' : $b2;
 
2078
                                }
 
2079
                        }
 
2080
                        $sep=-1;
 
2081
                        $i=0;
 
2082
                        $j=0;
 
2083
                        $l=0;
 
2084
                        $ns=0;
 
2085
                        $nl=1;
 
2086
                        while($i<$nb) {
 
2087
                                //Get next character
 
2088
                                $c = $s{$i};
 
2089
                                if(preg_match("/[\n]/u", $c)) {
 
2090
                                        //Explicit line break
 
2091
                                        if($this->ws > 0) {
 
2092
                                                $this->ws = 0;
 
2093
                                                $this->_out('0 Tw');
 
2094
                                        }
 
2095
                                        $this->Cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill);
 
2096
                                        $i++;
 
2097
                                        $sep=-1;
 
2098
                                        $j=$i;
 
2099
                                        $l=0;
 
2100
                                        $ns=0;
 
2101
                                        $nl++;
 
2102
                                        if($border and $nl==2) {
 
2103
                                                $b = $b2;
 
2104
                                        }
 
2105
                                        continue;
 
2106
                                }
 
2107
                                if(preg_match("/[ ]/u", $c)) {
 
2108
                                        $sep = $i;
 
2109
                                        $ls = $l;
 
2110
                                        $ns++;
 
2111
                                }
 
2112
 
 
2113
                                $l = $this->GetStringWidth(substr($s, $j, $i-$j));
 
2114
 
 
2115
                                if($l > $wmax) {
 
2116
                                        //Automatic line break
 
2117
                                        if($sep == -1) {
 
2118
                                                if($i == $j) {
 
2119
                                                        $i++;
 
2120
                                                }
 
2121
                                                if($this->ws > 0) {
 
2122
                                                        $this->ws = 0;
 
2123
                                                        $this->_out('0 Tw');
 
2124
                                                }
 
2125
                                                $this->Cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill);
 
2126
                                        }
 
2127
                                        else {
 
2128
                                                if($align=='J') {
 
2129
                                                        $this->ws = ($ns>1) ? ($wmax-$ls)/($ns-1) : 0;
 
2130
                                                        $this->_out(sprintf('%.3f Tw', $this->ws * $this->k));
 
2131
                                                }
 
2132
                                                $this->Cell($w, $h, substr($s, $j, $sep-$j), $b, 2, $align, $fill);
 
2133
                                                $i = $sep + 1;
 
2134
                                        }
 
2135
                                        $sep=-1;
 
2136
                                        $j=$i;
 
2137
                                        $l=0;
 
2138
                                        $ns=0;
 
2139
                                        $nl++;
 
2140
                                        if($border AND ($nl==2)) {
 
2141
                                                $b=$b2;
 
2142
                                        }
 
2143
                                }
 
2144
                                else {
 
2145
                                        $i++;
 
2146
                                }
 
2147
                        }
 
2148
                        //Last chunk
 
2149
                        if($this->ws>0) {
 
2150
                                $this->ws=0;
 
2151
                                $this->_out('0 Tw');
 
2152
                        }
 
2153
                        if($border and is_int(strpos($border,'B'))) {
 
2154
                                $b.='B';
 
2155
                        }
 
2156
                        $this->Cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill);
 
2157
                        $this->x=$this->lMargin;
 
2158
                }
 
2159
 
 
2160
                /**
 
2161
                * This method prints text from the current position. When the right margin is reached (or the \n character is met) a line break occurs and text continues from the left margin. Upon method exit, the current position is left just at the end of the text. It is possible to put a link on the text.<br />
 
2162
                * <b>Example:</b><br />
 
2163
                * <pre>
 
2164
                * //Begin with regular font
 
2165
                * $pdf->SetFont('Arial','',14);
 
2166
                * $pdf->Write(5,'Visit ');
 
2167
                * //Then put a blue underlined link
 
2168
                * $pdf->SetTextColor(0,0,255);
 
2169
                * $pdf->SetFont('','U');
 
2170
                * $pdf->Write(5,'www.tecnick.com','http://www.tecnick.com');
 
2171
                * </pre>
 
2172
                * @param float $h Line height
 
2173
                * @param string $txt String to print
 
2174
                * @param mixed $link URL or identifier returned by AddLink()
 
2175
                * @param int $fill Indicates if the background must be painted (1) or transparent (0). Default value: 0.
 
2176
                * @since 1.5
 
2177
                * @see SetFont(), SetTextColor(), AddLink(), MultiCell(), SetAutoPageBreak()
 
2178
                */
 
2179
                function Write($h, $txt, $link='', $fill=0) {
 
2180
 
 
2181
                        //Output text in flowing mode
 
2182
                        $cw = &$this->CurrentFont['cw'];
 
2183
                        $w = $this->w - $this->rMargin - $this->x;
 
2184
                        $wmax = ($w - 2 * $this->cMargin);
 
2185
 
 
2186
                        $s = str_replace("\r", '', $txt);
 
2187
                        $nb = strlen($s);
 
2188
 
 
2189
                        // handle single space character
 
2190
                        if(($nb==1) AND preg_match("/[ ]/u", $s)) {
 
2191
                                $this->x += $this->GetStringWidth($s);
 
2192
                                return;
 
2193
                        }
 
2194
 
 
2195
                        $sep=-1;
 
2196
                        $i=0;
 
2197
                        $j=0;
 
2198
                        $l=0;
 
2199
                        $nl=1;
 
2200
                        while($i<$nb) {
 
2201
                                //Get next character
 
2202
                                $c=$s{$i};
 
2203
                                if(preg_match("/[\n]/u", $c)) {
 
2204
                                        //Explicit line break
 
2205
                                        $this->Cell($w, $h, substr($s, $j, $i-$j), 0, 2, '', $fill, $link);
 
2206
                                        $i++;
 
2207
                                        $sep = -1;
 
2208
                                        $j = $i;
 
2209
                                        $l = 0;
 
2210
                                        if($nl == 1) {
 
2211
                                                $this->x = $this->lMargin;
 
2212
                                                $w = $this->w - $this->rMargin - $this->x;
 
2213
                                                $wmax = ($w - 2 * $this->cMargin);
 
2214
                                        }
 
2215
                                        $nl++;
 
2216
                                        continue;
 
2217
                                }
 
2218
                                if(preg_match("/[ ]/u", $c)) {
 
2219
                                        $sep= $i;
 
2220
                                }
 
2221
 
 
2222
                                $l = $this->GetStringWidth(substr($s, $j, $i-$j));
 
2223
 
 
2224
                                if($l > $wmax) {
 
2225
                                        //Automatic line break (word wrapping)
 
2226
                                        if($sep == -1) {
 
2227
                                                if($this->x > $this->lMargin) {
 
2228
                                                        //Move to next line
 
2229
                                                        $this->x = $this->lMargin;
 
2230
                                                        $this->y += $h;
 
2231
                                                        $w=$this->w - $this->rMargin - $this->x;
 
2232
                                                        $wmax=($w - 2 * $this->cMargin);
 
2233
                                                        $i++;
 
2234
                                                        $nl++;
 
2235
                                                        continue;
 
2236
                                                }
 
2237
                                                if($i==$j) {
 
2238
                                                        $i++;
 
2239
                                                }
 
2240
                                                $this->Cell($w, $h, substr($s, $j, $i-$j), 0, 2, '', $fill, $link);
 
2241
                                        }
 
2242
                                        else {
 
2243
                                                $this->Cell($w, $h, substr($s, $j, $sep-$j), 0, 2, '', $fill, $link);
 
2244
                                                $i=$sep+1;
 
2245
                                        }
 
2246
                                        $sep = -1;
 
2247
                                        $j = $i;
 
2248
                                        $l = 0;
 
2249
                                        if($nl==1) {
 
2250
                                                $this->x = $this->lMargin;
 
2251
                                                $w = $this->w - $this->rMargin - $this->x;
 
2252
                                                $wmax = ($w - 2 * $this->cMargin);
 
2253
                                        }
 
2254
                                        $nl++;
 
2255
                                }
 
2256
                                else {
 
2257
                                        $i++;
 
2258
                                }
 
2259
                        }
 
2260
                        
 
2261
                        //Last chunk
 
2262
                        if($i!=$j) {
 
2263
                                $this->Cell($this->GetStringWidth(substr($s, $j)), $h, substr($s, $j), 0, 0, '', $fill, $link);
 
2264
                        }
 
2265
                }
 
2266
 
 
2267
                /**
 
2268
                * Puts an image in the page. The upper-left corner must be given. The dimensions can be specified in different ways:<ul><li>explicit width and height (expressed in user unit)</li><li>one explicit dimension, the other being calculated automatically in order to keep the original proportions</li><li>no explicit dimension, in which case the image is put at 72 dpi</li></ul>
 
2269
                * Supported formats are JPEG and PNG.
 
2270
                * For JPEG, all flavors are allowed:<ul><li>gray scales</li><li>true colors (24 bits)</li><li>CMYK (32 bits)</li></ul>
 
2271
                * For PNG, are allowed:<ul><li>gray scales on at most 8 bits (256 levels)</li><li>indexed colors</li><li>true colors (24 bits)</li></ul>
 
2272
                * but are not supported:<ul><li>Interlacing</li><li>Alpha channel</li></ul>
 
2273
                * If a transparent color is defined, it will be taken into account (but will be only interpreted by Acrobat 4 and above).<br />
 
2274
                * The format can be specified explicitly or inferred from the file extension.<br />
 
2275
                * It is possible to put a link on the image.<br />
 
2276
                * Remark: if an image is used several times, only one copy will be embedded in the file.<br />
 
2277
                * @param string $file Name of the file containing the image.
 
2278
                * @param float $x Abscissa of the upper-left corner.
 
2279
                * @param float $y Ordinate of the upper-left corner.
 
2280
                * @param float $w Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
 
2281
                * @param float $h Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
 
2282
                * @param string $type Image format. Possible values are (case insensitive): JPG, JPEG, PNG. If not specified, the type is inferred from the file extension.
 
2283
                * @param mixed $link URL or identifier returned by AddLink().
 
2284
                * @since 1.1
 
2285
                * @see AddLink()
 
2286
                */
 
2287
                function Image($file, $x, $y, $w=0, $h=0, $type='', $link='') {
 
2288
                        //Put an image on the page
 
2289
                        if(!isset($this->images[$file])) {
 
2290
                                //First use of image, get info
 
2291
                                if($type == '') {
 
2292
                                        $pos = strrpos($file,'.');
 
2293
                                        if(empty($pos)) {
 
2294
                                                $this->Error('Image file has no extension and no type was specified: '.$file);
 
2295
                                        }
 
2296
                                        $type = substr($file, $pos+1);
 
2297
                                }
 
2298
                                $type = strtolower($type);
 
2299
                                $mqr = get_magic_quotes_runtime();
 
2300
                                set_magic_quotes_runtime(0);
 
2301
                                if($type == 'jpg' or $type == 'jpeg') {
 
2302
                                        $info=$this->_parsejpg($file);
 
2303
                                }
 
2304
                                elseif($type == 'png') {
 
2305
                                        $info=$this->_parsepng($file);
 
2306
                                }
 
2307
                                else {
 
2308
                                        //Allow for additional formats
 
2309
                                        $mtd='_parse'.$type;
 
2310
                                        if(!method_exists($this,$mtd)) {
 
2311
                                                $this->Error('Unsupported image type: '.$type);
 
2312
                                        }
 
2313
                                        $info=$this->$mtd($file);
 
2314
                                }
 
2315
                                set_magic_quotes_runtime($mqr);
 
2316
                                $info['i']=count($this->images)+1;
 
2317
                                $this->images[$file]=$info;
 
2318
                        }
 
2319
                        else {
 
2320
                                $info=$this->images[$file];
 
2321
                        }
 
2322
                        //Automatic width and height calculation if needed
 
2323
                        if(($w == 0) and ($h == 0)) {
 
2324
                                //Put image at 72 dpi
 
2325
                                // 2004-06-14 :: Nicola Asuni, scale factor where added
 
2326
                                $w = $info['w'] / ($this->imgscale * $this->k);
 
2327
                                $h = $info['h'] / ($this->imgscale * $this->k);
 
2328
                        }
 
2329
                        if($w == 0) {
 
2330
                                $w = $h * $info['w'] / $info['h'];
 
2331
                        }
 
2332
                        if($h == 0) {
 
2333
                                $h = $w * $info['h'] / $info['w'];
 
2334
                        }
 
2335
                        $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']));
 
2336
                        if($link) {
 
2337
                                $this->Link($x, $y, $w, $h, $link);
 
2338
                        }
 
2339
 
 
2340
                        //2002-07-31 - Nicola Asuni
 
2341
                        // set right-bottom corner coordinates
 
2342
                        $this->img_rb_x = $x + $w;
 
2343
                        $this->img_rb_y = $y + $h;
 
2344
                }
 
2345
 
 
2346
                /**
 
2347
                * Performs a line break. The current abscissa goes back to the left margin and the ordinate increases by the amount passed in parameter.
 
2348
                * @param float $h The height of the break. By default, the value equals the height of the last printed cell.
 
2349
                * @since 1.0
 
2350
                * @see Cell()
 
2351
                */
 
2352
                function Ln($h='') {
 
2353
                        //Line feed; default value is last cell height
 
2354
                        $this->x=$this->lMargin;
 
2355
                        if(is_string($h)) {
 
2356
                                $this->y+=$this->lasth;
 
2357
                        }
 
2358
                        else {
 
2359
                                $this->y+=$h;
 
2360
                        }
 
2361
                }
 
2362
 
 
2363
                /**
 
2364
                * Returns the abscissa of the current position.
 
2365
                * @return float
 
2366
                * @since 1.2
 
2367
                * @see SetX(), GetY(), SetY()
 
2368
                */
 
2369
                function GetX() {
 
2370
                        //Get x position
 
2371
                        return $this->x;
 
2372
                }
 
2373
 
 
2374
                /**
 
2375
                * Defines the abscissa of the current position. If the passed value is negative, it is relative to the right of the page.
 
2376
                * @param float $x The value of the abscissa.
 
2377
                * @since 1.2
 
2378
                * @see GetX(), GetY(), SetY(), SetXY()
 
2379
                */
 
2380
                function SetX($x) {
 
2381
                        //Set x position
 
2382
                        if($x>=0) {
 
2383
                                $this->x=$x;
 
2384
                        }
 
2385
                        else {
 
2386
                                $this->x=$this->w+$x;
 
2387
                        }
 
2388
                }
 
2389
 
 
2390
                /**
 
2391
                * Returns the ordinate of the current position.
 
2392
                * @return float
 
2393
                * @since 1.0
 
2394
                * @see SetY(), GetX(), SetX()
 
2395
                */
 
2396
                function GetY() {
 
2397
                        //Get y position
 
2398
                        return $this->y;
 
2399
                }
 
2400
 
 
2401
                /**
 
2402
                * Moves the current abscissa back to the left margin and sets the ordinate. If the passed value is negative, it is relative to the bottom of the page.
 
2403
                * @param float $y The value of the ordinate.
 
2404
                * @since 1.0
 
2405
                * @see GetX(), GetY(), SetY(), SetXY()
 
2406
                */
 
2407
                function SetY($y) {
 
2408
                        //Set y position and reset x
 
2409
                        $this->x=$this->lMargin;
 
2410
                        if($y>=0) {
 
2411
                                $this->y=$y;
 
2412
                        }
 
2413
                        else {
 
2414
                                $this->y=$this->h+$y;
 
2415
                        }
 
2416
                }
 
2417
 
 
2418
                /**
 
2419
                * Defines the abscissa and ordinate of the current position. If the passed values are negative, they are relative respectively to the right and bottom of the page.
 
2420
                * @param float $x The value of the abscissa
 
2421
                * @param float $y The value of the ordinate
 
2422
                * @since 1.2
 
2423
                * @see SetX(), SetY()
 
2424
                */
 
2425
                function SetXY($x, $y) {
 
2426
                        //Set x and y positions
 
2427
                        $this->SetY($y);
 
2428
                        $this->SetX($x);
 
2429
                }
 
2430
 
 
2431
                /**
 
2432
                * Send the document to a given destination: string, local file or browser. In the last case, the plug-in may be used (if present) or a download ("Save as" dialog box) may be forced.<br />
 
2433
                * The method first calls Close() if necessary to terminate the document.
 
2434
                * @param string $name The name of the file. If not given, the document will be sent to the browser (destination I) with the name doc.pdf.
 
2435
                * @param string $dest Destination where to send the document. It can take one of the following values:<ul><li>I: send the file inline to the browser. The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.</li><li>D: send to the browser and force a file download with the name given by name.</li><li>F: save to a local file with the name given by name.</li><li>S: return the document as a string. name is ignored.</li></ul>If the parameter is not specified but a name is given, destination is F. If no parameter is specified at all, destination is I.<br />Note: for compatibility with previous versions, a boolean value is also accepted (false for F and true for D).
 
2436
                * @since 1.0
 
2437
                * @see Close()
 
2438
                */
 
2439
                function Output($name='',$dest='') {
 
2440
                        //Output PDF to some destination
 
2441
                        //Finish document if necessary
 
2442
                        if($this->state < 3) {
 
2443
                                $this->Close();
 
2444
                        }
 
2445
                        //Normalize parameters
 
2446
                        if(is_bool($dest)) {
 
2447
                                $dest=$dest ? 'D' : 'F';
 
2448
                        }
 
2449
                        $dest=strtoupper($dest);
 
2450
                        if($dest=='') {
 
2451
                                if($name=='') {
 
2452
                                        $name='doc.pdf';
 
2453
                                        $dest='I';
 
2454
                                } else {
 
2455
                                        $dest='F';
 
2456
                                }
 
2457
                        }
 
2458
                        switch($dest) {
 
2459
                                case 'I': {
 
2460
                                        //Send to standard output
 
2461
                                        if(ob_get_contents()) {
 
2462
                                                $this->Error('Some data has already been output, can\'t send PDF file');
 
2463
                                        }
 
2464
                                        if(php_sapi_name()!='cli') {
 
2465
                                                //We send to a browser
 
2466
                                                header('Content-Type: application/pdf');
 
2467
                                                if(headers_sent()) {
 
2468
                                                        $this->Error('Some data has already been output to browser, can\'t send PDF file');
 
2469
                                                }
 
2470
                                                header('Content-Length: '.strlen($this->buffer));
 
2471
                                                header('Content-disposition: inline; filename="'.$name.'"');
 
2472
                                        }
 
2473
                                        echo $this->buffer;
 
2474
                                        break;
 
2475
                                }
 
2476
                                case 'D': {
 
2477
                                        //Download file
 
2478
                                        if(ob_get_contents()) {
 
2479
                                                $this->Error('Some data has already been output, can\'t send PDF file');
 
2480
                                        }
 
2481
                                        if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) {
 
2482
                                                header('Content-Type: application/force-download');
 
2483
                                        } else {
 
2484
                                                header('Content-Type: application/octet-stream');
 
2485
                                        }
 
2486
                                        if(headers_sent()) {
 
2487
                                                $this->Error('Some data has already been output to browser, can\'t send PDF file');
 
2488
                                        }
 
2489
                                        header('Content-Length: '.strlen($this->buffer));
 
2490
                                        header('Content-disposition: attachment; filename="'.$name.'"');
 
2491
                                        echo $this->buffer;
 
2492
                                        break;
 
2493
                                }
 
2494
                                case 'F': {
 
2495
                                        //Save to local file
 
2496
                                        $f=fopen($name,'wb');
 
2497
                                        if(!$f) {
 
2498
                                                $this->Error('Unable to create output file: '.$name);
 
2499
                                        }
 
2500
                                        fwrite($f,$this->buffer,strlen($this->buffer));
 
2501
                                        fclose($f);
 
2502
                                        break;
 
2503
                                }
 
2504
                                case 'S': {
 
2505
                                        //Return as a string
 
2506
                                        return $this->buffer;
 
2507
                                }
 
2508
                                default: {
 
2509
                                        $this->Error('Incorrect output destination: '.$dest);
 
2510
                                }
 
2511
                        }
 
2512
                        return '';
 
2513
                }
 
2514
 
 
2515
                // var methods
 
2516
 
 
2517
                /**
 
2518
                * Check for locale-related bug
 
2519
                * @access protected
 
2520
                */
 
2521
                function _dochecks() {
 
2522
                        //Check for locale-related bug
 
2523
                        if(1.1==1) {
 
2524
                                $this->Error('Don\'t alter the locale before including class file');
 
2525
                        }
 
2526
                        //Check for decimal separator
 
2527
                        if(sprintf('%.1f',1.0)!='1.0') {
 
2528
                                setlocale(LC_NUMERIC,'C');
 
2529
                        }
 
2530
                }
 
2531
 
 
2532
                /**
 
2533
                * Return fonts path
 
2534
                * @access protected
 
2535
                */
 
2536
                function _getfontpath() {
 
2537
                        if(!defined('FPDF_FONTPATH') AND is_dir(dirname(__FILE__).'/font')) {
 
2538
                                define('FPDF_FONTPATH', dirname(__FILE__).'/font/');
 
2539
                        }
 
2540
                        return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : '';
 
2541
                }
 
2542
 
 
2543
                /**
 
2544
                * Start document
 
2545
                * @access protected
 
2546
                */
 
2547
                function _begindoc() {
 
2548
                        //Start document
 
2549
                        $this->state=1;
 
2550
                        $this->_out('%PDF-1.3');
 
2551
                }
 
2552
 
 
2553
                /**
 
2554
                * _putpages
 
2555
                * @access protected
 
2556
                */
 
2557
                function _putpages() {
 
2558
                        $nb = $this->page;
 
2559
                        if(!empty($this->AliasNbPages)) {
 
2560
                                $nbstr = $this->UTF8ToUTF16BE($nb, false);
 
2561
                                //Replace number of pages
 
2562
                                for($n=1;$n<=$nb;$n++) {
 
2563
                                        $this->pages[$n]=str_replace($this->AliasNbPages, $nbstr, $this->pages[$n]);
 
2564
                                }
 
2565
                        }
 
2566
                        if($this->DefOrientation=='P') {
 
2567
                                $wPt=$this->fwPt;
 
2568
                                $hPt=$this->fhPt;
 
2569
                        }
 
2570
                        else {
 
2571
                                $wPt=$this->fhPt;
 
2572
                                $hPt=$this->fwPt;
 
2573
                        }
 
2574
                        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
 
2575
                        for($n=1;$n<=$nb;$n++) {
 
2576
                                //Page
 
2577
                                $this->_newobj();
 
2578
                                $this->_out('<</Type /Page');
 
2579
                                $this->_out('/Parent 1 0 R');
 
2580
                                if(isset($this->OrientationChanges[$n])) {
 
2581
                                        $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
 
2582
                                }
 
2583
                                $this->_out('/Resources 2 0 R');
 
2584
                                if(isset($this->PageLinks[$n])) {
 
2585
                                        //Links
 
2586
                                        $annots='/Annots [';
 
2587
                                        foreach($this->PageLinks[$n] as $pl) {
 
2588
                                                $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
 
2589
                                                $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
 
2590
                                                if(is_string($pl[4])) {
 
2591
                                                        $annots.='/A <</S /URI /URI ('.$this->_escape($pl[4]).')>>>>';
 
2592
                                                }
 
2593
                                                else {
 
2594
                                                        $l=$this->links[$pl[4]];
 
2595
                                                        $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt;
 
2596
                                                        $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k);
 
2597
                                                }
 
2598
                                        }
 
2599
                                        $this->_out($annots.']');
 
2600
                                }
 
2601
                                $this->_out('/Contents '.($this->n+1).' 0 R>>');
 
2602
                                $this->_out('endobj');
 
2603
                                //Page content
 
2604
                                $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
 
2605
                                $this->_newobj();
 
2606
                                $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
 
2607
                                $this->_putstream($p);
 
2608
                                $this->_out('endobj');
 
2609
                        }
 
2610
                        //Pages root
 
2611
                        $this->offsets[1]=strlen($this->buffer);
 
2612
                        $this->_out('1 0 obj');
 
2613
                        $this->_out('<</Type /Pages');
 
2614
                        $kids='/Kids [';
 
2615
                        for($i=0;$i<$nb;$i++) {
 
2616
                                $kids.=(3+2*$i).' 0 R ';
 
2617
                        }
 
2618
                        $this->_out($kids.']');
 
2619
                        $this->_out('/Count '.$nb);
 
2620
                        $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
 
2621
                        $this->_out('>>');
 
2622
                        $this->_out('endobj');
 
2623
                }
 
2624
 
 
2625
                /**
 
2626
                * Adds fonts
 
2627
                * _putfonts
 
2628
                * @access protected
 
2629
                */
 
2630
                function _putfonts() {
 
2631
                        $nf=$this->n;
 
2632
                        foreach($this->diffs as $diff) {
 
2633
                                //Encodings
 
2634
                                $this->_newobj();
 
2635
                                $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
 
2636
                                $this->_out('endobj');
 
2637
                        }
 
2638
                        $mqr=get_magic_quotes_runtime();
 
2639
                        set_magic_quotes_runtime(0);
 
2640
                        foreach($this->FontFiles as $file=>$info) {
 
2641
                                //Font file embedding
 
2642
                                $this->_newobj();
 
2643
                                $this->FontFiles[$file]['n']=$this->n;
 
2644
                                $font='';
 
2645
                                $f=fopen($this->_getfontpath().$file,'rb',1);
 
2646
                                if(!$f) {
 
2647
                                        $this->Error('Font file not found');
 
2648
                                }
 
2649
                                while(!feof($f)) {
 
2650
                                        $font .= fread($f, 8192);
 
2651
                                }
 
2652
                                fclose($f);
 
2653
                                $compressed=(substr($file,-2)=='.z');
 
2654
                                if(!$compressed && isset($info['length2'])) {
 
2655
                                        $header=(ord($font{0})==128);
 
2656
                                        if($header) {
 
2657
                                                //Strip first binary header
 
2658
                                                $font=substr($font,6);
 
2659
                                        }
 
2660
                                        if($header && ord($font{$info['length1']})==128) {
 
2661
                                                //Strip second binary header
 
2662
                                                $font=substr($font,0,$info['length1']).substr($font,$info['length1']+6);
 
2663
                                        }
 
2664
                                }
 
2665
                                $this->_out('<</Length '.strlen($font));
 
2666
                                if($compressed) {
 
2667
                                        $this->_out('/Filter /FlateDecode');
 
2668
                                }
 
2669
                                $this->_out('/Length1 '.$info['length1']);
 
2670
                                if(isset($info['length2'])) {
 
2671
                                        $this->_out('/Length2 '.$info['length2'].' /Length3 0');
 
2672
                                }
 
2673
                                $this->_out('>>');
 
2674
                                $this->_putstream($font);
 
2675
                                $this->_out('endobj');
 
2676
                        }
 
2677
                        set_magic_quotes_runtime($mqr);
 
2678
                        foreach($this->fonts as $k=>$font) {
 
2679
                                //Font objects
 
2680
                                $this->fonts[$k]['n']=$this->n+1;
 
2681
                                $type=$font['type'];
 
2682
                                $name=$font['name'];
 
2683
                                if($type=='core') {
 
2684
                                        //Standard font
 
2685
                                        $this->_newobj();
 
2686
                                        $this->_out('<</Type /Font');
 
2687
                                        $this->_out('/BaseFont /'.$name);
 
2688
                                        $this->_out('/Subtype /Type1');
 
2689
                                        if($name!='Symbol' && $name!='ZapfDingbats') {
 
2690
                                                $this->_out('/Encoding /WinAnsiEncoding');
 
2691
                                        }
 
2692
                                        $this->_out('>>');
 
2693
                                        $this->_out('endobj');
 
2694
                                } elseif($type=='Type1' || $type=='TrueType') {
 
2695
                                        //Additional Type1 or TrueType font
 
2696
                                        $this->_newobj();
 
2697
                                        $this->_out('<</Type /Font');
 
2698
                                        $this->_out('/BaseFont /'.$name);
 
2699
                                        $this->_out('/Subtype /'.$type);
 
2700
                                        $this->_out('/FirstChar 32 /LastChar 255');
 
2701
                                        $this->_out('/Widths '.($this->n+1).' 0 R');
 
2702
                                        $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
 
2703
                                        if($font['enc']) {
 
2704
                                                if(isset($font['diff'])) {
 
2705
                                                        $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
 
2706
                                                } else {
 
2707
                                                        $this->_out('/Encoding /WinAnsiEncoding');
 
2708
                                                }
 
2709
                                        }
 
2710
                                        $this->_out('>>');
 
2711
                                        $this->_out('endobj');
 
2712
                                        //Widths
 
2713
                                        $this->_newobj();
 
2714
                                        $cw=&$font['cw'];
 
2715
                                        $s='[';
 
2716
                                        for($i=32;$i<=255;$i++) {
 
2717
                                                $s.=$cw[chr($i)].' ';
 
2718
                                        }
 
2719
                                        $this->_out($s.']');
 
2720
                                        $this->_out('endobj');
 
2721
                                        //Descriptor
 
2722
                                        $this->_newobj();
 
2723
                                        $s='<</Type /FontDescriptor /FontName /'.$name;
 
2724
                                        foreach($font['desc'] as $k=>$v) {
 
2725
                                                $s.=' /'.$k.' '.$v;
 
2726
                                        }
 
2727
                                        $file = $font['file'];
 
2728
                                        if($file) {
 
2729
                                                $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
 
2730
                                        }
 
2731
                                        $this->_out($s.'>>');
 
2732
                                        $this->_out('endobj');
 
2733
                                } else {
 
2734
                                        //Allow for additional types
 
2735
                                        $mtd='_put'.strtolower($type);
 
2736
                                        if(!method_exists($this, $mtd)) {
 
2737
                                                $this->Error('Unsupported font type: '.$type);
 
2738
                                        }
 
2739
                                        $this->$mtd($font);
 
2740
                                }
 
2741
                        }
 
2742
                }
 
2743
 
 
2744
                /**
 
2745
                * _putimages
 
2746
                * @access protected
 
2747
                */
 
2748
                function _putimages() {
 
2749
                        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
 
2750
                        reset($this->images);
 
2751
                        while(list($file,$info)=each($this->images)) {
 
2752
                                $this->_newobj();
 
2753
                                $this->images[$file]['n']=$this->n;
 
2754
                                $this->_out('<</Type /XObject');
 
2755
                                $this->_out('/Subtype /Image');
 
2756
                                $this->_out('/Width '.$info['w']);
 
2757
                                $this->_out('/Height '.$info['h']);
 
2758
                                if($info['cs']=='Indexed') {
 
2759
                                        $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
 
2760
                                }
 
2761
                                else {
 
2762
                                        $this->_out('/ColorSpace /'.$info['cs']);
 
2763
                                        if($info['cs']=='DeviceCMYK') {
 
2764
                                                $this->_out('/Decode [1 0 1 0 1 0 1 0]');
 
2765
                                        }
 
2766
                                }
 
2767
                                $this->_out('/BitsPerComponent '.$info['bpc']);
 
2768
                                if(isset($info['f'])) {
 
2769
                                        $this->_out('/Filter /'.$info['f']);
 
2770
                                }
 
2771
                                if(isset($info['parms'])) {
 
2772
                                        $this->_out($info['parms']);
 
2773
                                }
 
2774
                                if(isset($info['trns']) and is_array($info['trns'])) {
 
2775
                                        $trns='';
 
2776
                                        for($i=0;$i<count($info['trns']);$i++) {
 
2777
                                                $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
 
2778
                                        }
 
2779
                                        $this->_out('/Mask ['.$trns.']');
 
2780
                                }
 
2781
                                $this->_out('/Length '.strlen($info['data']).'>>');
 
2782
                                $this->_putstream($info['data']);
 
2783
                                unset($this->images[$file]['data']);
 
2784
                                $this->_out('endobj');
 
2785
                                //Palette
 
2786
                                if($info['cs']=='Indexed') {
 
2787
                                        $this->_newobj();
 
2788
                                        $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
 
2789
                                        $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
 
2790
                                        $this->_putstream($pal);
 
2791
                                        $this->_out('endobj');
 
2792
                                }
 
2793
                        }
 
2794
                }
 
2795
 
 
2796
                /**
 
2797
                * _putxobjectdict
 
2798
                * @access protected
 
2799
                */
 
2800
                function _putxobjectdict() {
 
2801
                        foreach($this->images as $image) {
 
2802
                                $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
 
2803
                        }
 
2804
                }
 
2805
 
 
2806
                /**
 
2807
                * _putresourcedict
 
2808
                * @access protected
 
2809
                */
 
2810
                function _putresourcedict(){
 
2811
                        $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
 
2812
                        $this->_out('/Font <<');
 
2813
                        foreach($this->fonts as $font) {
 
2814
                                $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
 
2815
                        }
 
2816
                        $this->_out('>>');
 
2817
                        $this->_out('/XObject <<');
 
2818
                        $this->_putxobjectdict();
 
2819
                        $this->_out('>>');
 
2820
                }
 
2821
 
 
2822
                /**
 
2823
                * _putresources
 
2824
                * @access protected
 
2825
                */
 
2826
                function _putresources() {
 
2827
                        $this->_putfonts();
 
2828
                        $this->_putimages();
 
2829
                        //Resource dictionary
 
2830
                        $this->offsets[2]=strlen($this->buffer);
 
2831
                        $this->_out('2 0 obj');
 
2832
                        $this->_out('<<');
 
2833
                        $this->_putresourcedict();
 
2834
                        $this->_out('>>');
 
2835
                        $this->_out('endobj');
 
2836
                }
 
2837
                
 
2838
                /**
 
2839
                * _putinfo
 
2840
                * @access protected
 
2841
                */
 
2842
                function _putinfo() {
 
2843
                        $this->_out('/Producer '.$this->_textstring(PDF_PRODUCER));
 
2844
                        if(!empty($this->title)) {
 
2845
                                $this->_out('/Title '.$this->_textstring($this->title));
 
2846
                        }
 
2847
                        if(!empty($this->subject)) {
 
2848
                                $this->_out('/Subject '.$this->_textstring($this->subject));
 
2849
                        }
 
2850
                        if(!empty($this->author)) {
 
2851
                                $this->_out('/Author '.$this->_textstring($this->author));
 
2852
                        }
 
2853
                        if(!empty($this->keywords)) {
 
2854
                                $this->_out('/Keywords '.$this->_textstring($this->keywords));
 
2855
                        }
 
2856
                        if(!empty($this->creator)) {
 
2857
                                $this->_out('/Creator '.$this->_textstring($this->creator));
 
2858
                        }
 
2859
                        $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
 
2860
                }
 
2861
 
 
2862
                /**
 
2863
                * _putcatalog
 
2864
                * @access protected
 
2865
                */
 
2866
                function _putcatalog() {
 
2867
                        $this->_out('/Type /Catalog');
 
2868
                        $this->_out('/Pages 1 0 R');
 
2869
                        if($this->ZoomMode=='fullpage') {
 
2870
                                $this->_out('/OpenAction [3 0 R /Fit]');
 
2871
                        }
 
2872
                        elseif($this->ZoomMode=='fullwidth') {
 
2873
                                $this->_out('/OpenAction [3 0 R /FitH null]');
 
2874
                        }
 
2875
                        elseif($this->ZoomMode=='real') {
 
2876
                                $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
 
2877
                        }
 
2878
                        elseif(!is_string($this->ZoomMode)) {
 
2879
                                $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
 
2880
                        }
 
2881
                        if($this->LayoutMode=='single') {
 
2882
                                $this->_out('/PageLayout /SinglePage');
 
2883
                        }
 
2884
                        elseif($this->LayoutMode=='continuous') {
 
2885
                                $this->_out('/PageLayout /OneColumn');
 
2886
                        }
 
2887
                        elseif($this->LayoutMode=='two') {
 
2888
                                $this->_out('/PageLayout /TwoColumnLeft');
 
2889
                        }
 
2890
                }
 
2891
 
 
2892
                /**
 
2893
                * _puttrailer
 
2894
                * @access protected
 
2895
                */
 
2896
                function _puttrailer() {
 
2897
                        $this->_out('/Size '.($this->n+1));
 
2898
                        $this->_out('/Root '.$this->n.' 0 R');
 
2899
                        $this->_out('/Info '.($this->n-1).' 0 R');
 
2900
                }
 
2901
 
 
2902
                /**
 
2903
                * _putheader
 
2904
                * @access protected
 
2905
                */
 
2906
                function _putheader() {
 
2907
                        $this->_out('%PDF-'.$this->PDFVersion);
 
2908
                }
 
2909
 
 
2910
                /**
 
2911
                * _enddoc
 
2912
                * @access protected
 
2913
                */
 
2914
                function _enddoc() {
 
2915
                        $this->_putheader();
 
2916
                        $this->_putpages();
 
2917
                        $this->_putresources();
 
2918
                        //Info
 
2919
                        $this->_newobj();
 
2920
                        $this->_out('<<');
 
2921
                        $this->_putinfo();
 
2922
                        $this->_out('>>');
 
2923
                        $this->_out('endobj');
 
2924
                        //Catalog
 
2925
                        $this->_newobj();
 
2926
                        $this->_out('<<');
 
2927
                        $this->_putcatalog();
 
2928
                        $this->_out('>>');
 
2929
                        $this->_out('endobj');
 
2930
                        //Cross-ref
 
2931
                        $o=strlen($this->buffer);
 
2932
                        $this->_out('xref');
 
2933
                        $this->_out('0 '.($this->n+1));
 
2934
                        $this->_out('0000000000 65535 f ');
 
2935
                        for($i=1;$i<=$this->n;$i++) {
 
2936
                                $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
 
2937
                        }
 
2938
                        //Trailer
 
2939
                        $this->_out('trailer');
 
2940
                        $this->_out('<<');
 
2941
                        $this->_puttrailer();
 
2942
                        $this->_out('>>');
 
2943
                        $this->_out('startxref');
 
2944
                        $this->_out($o);
 
2945
                        $this->_out('%%EOF');
 
2946
                        $this->state=3;
 
2947
                }
 
2948
 
 
2949
                /**
 
2950
                * _beginpage
 
2951
                * @access protected
 
2952
                */
 
2953
                function _beginpage($orientation) {
 
2954
                        $this->page++;
 
2955
                        $this->pages[$this->page]='';
 
2956
                        $this->state=2;
 
2957
                        $this->x=$this->lMargin;
 
2958
                        $this->y=$this->tMargin;
 
2959
                        $this->FontFamily='';
 
2960
                        //Page orientation
 
2961
                        if(empty($orientation)) {
 
2962
                                $orientation=$this->DefOrientation;
 
2963
                        }
 
2964
                        else {
 
2965
                                $orientation=strtoupper($orientation{0});
 
2966
                                if($orientation!=$this->DefOrientation) {
 
2967
                                        $this->OrientationChanges[$this->page]=true;
 
2968
                                }
 
2969
                        }
 
2970
                        if($orientation!=$this->CurOrientation) {
 
2971
                                //Change orientation
 
2972
                                if($orientation=='P') {
 
2973
                                        $this->wPt=$this->fwPt;
 
2974
                                        $this->hPt=$this->fhPt;
 
2975
                                        $this->w=$this->fw;
 
2976
                                        $this->h=$this->fh;
 
2977
                                }
 
2978
                                else {
 
2979
                                        $this->wPt=$this->fhPt;
 
2980
                                        $this->hPt=$this->fwPt;
 
2981
                                        $this->w=$this->fh;
 
2982
                                        $this->h=$this->fw;
 
2983
                                }
 
2984
                                $this->PageBreakTrigger=$this->h-$this->bMargin;
 
2985
                                $this->CurOrientation=$orientation;
 
2986
                        }
 
2987
                }
 
2988
 
 
2989
                /**
 
2990
                * End of page contents
 
2991
                * @access protected
 
2992
                */
 
2993
                function _endpage() {
 
2994
                        $this->state=1;
 
2995
                }
 
2996
 
 
2997
                /**
 
2998
                * Begin a new object
 
2999
                * @access protected
 
3000
                */
 
3001
                function _newobj() {
 
3002
                        $this->n++;
 
3003
                        $this->offsets[$this->n]=strlen($this->buffer);
 
3004
                        $this->_out($this->n.' 0 obj');
 
3005
                }
 
3006
 
 
3007
                /**
 
3008
                * Underline text
 
3009
                * @access protected
 
3010
                */
 
3011
                function _dounderline($x,$y,$txt) {
 
3012
                        $up = $this->CurrentFont['up'];
 
3013
                        $ut = $this->CurrentFont['ut'];
 
3014
                        $w = $this->GetStringWidth($txt) + $this->ws * substr_count($txt,' ');
 
3015
                        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);
 
3016
                }
 
3017
 
 
3018
                /**
 
3019
                * Extract info from a JPEG file
 
3020
                * @access protected
 
3021
                */
 
3022
                function _parsejpg($file) {
 
3023
                        $a=GetImageSize($file);
 
3024
                        if(empty($a)) {
 
3025
                                $this->Error('Missing or incorrect image file: '.$file);
 
3026
                        }
 
3027
                        if($a[2]!=2) {
 
3028
                                $this->Error('Not a JPEG file: '.$file);
 
3029
                        }
 
3030
                        if(!isset($a['channels']) or $a['channels']==3) {
 
3031
                                $colspace='DeviceRGB';
 
3032
                        }
 
3033
                        elseif($a['channels']==4) {
 
3034
                                $colspace='DeviceCMYK';
 
3035
                        }
 
3036
                        else {
 
3037
                                $colspace='DeviceGray';
 
3038
                        }
 
3039
                        $bpc=isset($a['bits']) ? $a['bits'] : 8;
 
3040
                        //Read whole file
 
3041
                        $f=fopen($file,'rb');
 
3042
                        $data='';
 
3043
                        while(!feof($f)) {
 
3044
                                $data.=fread($f,4096);
 
3045
                        }
 
3046
                        fclose($f);
 
3047
                        return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
 
3048
                }
 
3049
 
 
3050
                /**
 
3051
                * Extract info from a PNG file
 
3052
                * @access protected
 
3053
                */
 
3054
                function _parsepng($file) {
 
3055
                        $f=fopen($file,'rb');
 
3056
                        if(empty($f)) {
 
3057
                                $this->Error('Can\'t open image file: '.$file);
 
3058
                        }
 
3059
                        //Check signature
 
3060
                        if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
 
3061
                                $this->Error('Not a PNG file: '.$file);
 
3062
                        }
 
3063
                        //Read header chunk
 
3064
                        fread($f,4);
 
3065
                        if(fread($f,4)!='IHDR') {
 
3066
                                $this->Error('Incorrect PNG file: '.$file);
 
3067
                        }
 
3068
                        $w=$this->_freadint($f);
 
3069
                        $h=$this->_freadint($f);
 
3070
                        $bpc=ord(fread($f,1));
 
3071
                        if($bpc>8) {
 
3072
                                $this->Error('16-bit depth not supported: '.$file);
 
3073
                        }
 
3074
                        $ct=ord(fread($f,1));
 
3075
                        if($ct==0) {
 
3076
                                $colspace='DeviceGray';
 
3077
                        }
 
3078
                        elseif($ct==2) {
 
3079
                                $colspace='DeviceRGB';
 
3080
                        }
 
3081
                        elseif($ct==3) {
 
3082
                                $colspace='Indexed';
 
3083
                        }
 
3084
                        else {
 
3085
                                $this->Error('Alpha channel not supported: '.$file);
 
3086
                        }
 
3087
                        if(ord(fread($f,1))!=0) {
 
3088
                                $this->Error('Unknown compression method: '.$file);
 
3089
                        }
 
3090
                        if(ord(fread($f,1))!=0) {
 
3091
                                $this->Error('Unknown filter method: '.$file);
 
3092
                        }
 
3093
                        if(ord(fread($f,1))!=0) {
 
3094
                                $this->Error('Interlacing not supported: '.$file);
 
3095
                        }
 
3096
                        fread($f,4);
 
3097
                        $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
 
3098
                        //Scan chunks looking for palette, transparency and image data
 
3099
                        $pal='';
 
3100
                        $trns='';
 
3101
                        $data='';
 
3102
                        do {
 
3103
                                $n=$this->_freadint($f);
 
3104
                                $type=fread($f,4);
 
3105
                                if($type=='PLTE') {
 
3106
                                        //Read palette
 
3107
                                        $pal=fread($f,$n);
 
3108
                                        fread($f,4);
 
3109
                                }
 
3110
                                elseif($type=='tRNS') {
 
3111
                                        //Read transparency info
 
3112
                                        $t=fread($f,$n);
 
3113
                                        if($ct==0) {
 
3114
                                                $trns=array(ord(substr($t,1,1)));
 
3115
                                        }
 
3116
                                        elseif($ct==2) {
 
3117
                                                $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
 
3118
                                        }
 
3119
                                        else {
 
3120
                                                $pos=strpos($t,chr(0));
 
3121
                                                if($pos!==false) {
 
3122
                                                        $trns=array($pos);
 
3123
                                                }
 
3124
                                        }
 
3125
                                        fread($f,4);
 
3126
                                }
 
3127
                                elseif($type=='IDAT') {
 
3128
                                        //Read image data block
 
3129
                                        $data.=fread($f,$n);
 
3130
                                        fread($f,4);
 
3131
                                }
 
3132
                                elseif($type=='IEND') {
 
3133
                                        break;
 
3134
                                }
 
3135
                                else {
 
3136
                                        fread($f,$n+4);
 
3137
                                }
 
3138
                        }
 
3139
                        while($n);
 
3140
                        if($colspace=='Indexed' and empty($pal)) {
 
3141
                                $this->Error('Missing palette in '.$file);
 
3142
                        }
 
3143
                        fclose($f);
 
3144
                        return array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'parms'=>$parms, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
 
3145
                }
 
3146
 
 
3147
                /**
 
3148
                * Read a 4-byte integer from file
 
3149
                * @access protected
 
3150
                */
 
3151
                function _freadint($f) {
 
3152
                        //Read a 4-byte integer from file
 
3153
                        $a=unpack('Ni',fread($f,4));
 
3154
                        return $a['i'];
 
3155
                }
 
3156
 
 
3157
                /**
 
3158
                * Format a text string
 
3159
                * @access protected
 
3160
                */
 
3161
                function _textstring($s) {
 
3162
                        if($this->isunicode) {
 
3163
                                //Convert string to UTF-16BE
 
3164
                                $s = $this->UTF8ToUTF16BE($s, true);
 
3165
                        }
 
3166
                        return '('. $this->_escape($s).')';
 
3167
                }
 
3168
 
 
3169
                /**
 
3170
                * Format a text string
 
3171
                * @access protected
 
3172
                */
 
3173
                function _escapetext($s) {
 
3174
                        if($this->isunicode) {
 
3175
                                //Convert string to UTF-16BE
 
3176
                                $s = $this->UTF8ToUTF16BE($s, false);
 
3177
                        }
 
3178
                        return $this->_escape($s);
 
3179
                }
 
3180
 
 
3181
                /**
 
3182
                * Add \ before \, ( and )
 
3183
                * @access protected
 
3184
                */
 
3185
                function _escape($s) {
 
3186
                        // the chr(13) substitution fixes the Bugs item #1421290.
 
3187
                        return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
 
3188
                }
 
3189
 
 
3190
                /**
 
3191
                *
 
3192
                * @access protected
 
3193
                */
 
3194
                function _putstream($s) {
 
3195
                        $this->_out('stream');
 
3196
                        $this->_out($s);
 
3197
                        $this->_out('endstream');
 
3198
                }
 
3199
 
 
3200
                /**
 
3201
                * Add a line to the document
 
3202
                * @access protected
 
3203
                */
 
3204
                function _out($s) {
 
3205
                        if($this->state==2) {
 
3206
                                $this->pages[$this->page] .= $s."\n";
 
3207
                        }
 
3208
                        else {
 
3209
                                $this->buffer .= $s."\n";
 
3210
                        }
 
3211
                }
 
3212
 
 
3213
                /**
 
3214
                * Adds unicode fonts.<br>
 
3215
                * Based on PDF Reference 1.3 (section 5)
 
3216
                * @access protected
 
3217
                * @author Nicola Asuni
 
3218
                * @since 1.52.0.TC005 (2005-01-05)
 
3219
                */
 
3220
                function _puttruetypeunicode($font) {
 
3221
                        // Type0 Font
 
3222
                        // A composite font—a font composed of other fonts, organized hierarchically
 
3223
                        $this->_newobj();
 
3224
                        $this->_out('<</Type /Font');
 
3225
                        $this->_out('/Subtype /Type0');
 
3226
                        $this->_out('/BaseFont /'.$font['name'].'');
 
3227
                        $this->_out('/Encoding /Identity-H'); //The horizontal identity mapping for 2-byte CIDs; may be used with CIDFonts using any Registry, Ordering, and Supplement values.
 
3228
                        $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
 
3229
                        $this->_out('>>');
 
3230
                        $this->_out('endobj');
 
3231
                        
 
3232
                        // CIDFontType2
 
3233
                        // A CIDFont whose glyph descriptions are based on TrueType font technology
 
3234
                        $this->_newobj();
 
3235
                        $this->_out('<</Type /Font');
 
3236
                        $this->_out('/Subtype /CIDFontType2');
 
3237
                        $this->_out('/BaseFont /'.$font['name'].'');
 
3238
                        $this->_out('/CIDSystemInfo '.($this->n + 1).' 0 R'); 
 
3239
                        $this->_out('/FontDescriptor '.($this->n + 2).' 0 R');
 
3240
                        if (isset($font['desc']['MissingWidth'])){
 
3241
                                $this->_out('/DW '.$font['desc']['MissingWidth'].''); // The default width for glyphs in the CIDFont MissingWidth
 
3242
                        }
 
3243
                        $w = "";
 
3244
                        foreach ($font['cw'] as $cid => $width) {
 
3245
                                $w .= ''.$cid.' ['.$width.'] '; // define a specific width for each individual CID
 
3246
                        }
 
3247
                        $this->_out('/W ['.$w.']'); // A description of the widths for the glyphs in the CIDFont
 
3248
                        $this->_out('/CIDToGIDMap '.($this->n + 3).' 0 R');
 
3249
                        $this->_out('>>');
 
3250
                        $this->_out('endobj');
 
3251
                        
 
3252
                        // CIDSystemInfo dictionary
 
3253
                        // A dictionary containing entries that define the character collection of the CIDFont.
 
3254
                        $this->_newobj();
 
3255
                        $this->_out('<</Registry (Adobe)'); // A string identifying an issuer of character collections
 
3256
                        $this->_out('/Ordering (UCS)'); // A string that uniquely names a character collection issued by a specific registry
 
3257
                        $this->_out('/Supplement 0'); // The supplement number of the character collection.
 
3258
                        $this->_out('>>');
 
3259
                        $this->_out('endobj');
 
3260
                        
 
3261
                        // Font descriptor
 
3262
                        // A font descriptor describing the CIDFont’s default metrics other than its glyph widths
 
3263
                        $this->_newobj();
 
3264
                        $this->_out('<</Type /FontDescriptor');
 
3265
                        $this->_out('/FontName /'.$font['name']);
 
3266
                        foreach ($font['desc'] as $key => $value) {
 
3267
                                $this->_out('/'.$key.' '.$value);
 
3268
                        }
 
3269
                        if ($font['file']) {
 
3270
                                // A stream containing a TrueType font program
 
3271
                                $this->_out('/FontFile2 '.$this->FontFiles[$font['file']]['n'].' 0 R');
 
3272
                        }
 
3273
                        $this->_out('>>');
 
3274
                        $this->_out('endobj');
 
3275
 
 
3276
                        // Embed CIDToGIDMap
 
3277
                        // A specification of the mapping from CIDs to glyph indices
 
3278
                        $this->_newobj();
 
3279
                        $ctgfile = $this->_getfontpath().$font['ctg'];
 
3280
                        if(!file_exists($ctgfile)) {
 
3281
                                $this->Error('Font file not found: '.$ctgfile);
 
3282
                        }
 
3283
                        $size = filesize($ctgfile);
 
3284
                        $this->_out('<</Length '.$size.'');
 
3285
                        if(substr($ctgfile, -2) == '.z') { // check file extension
 
3286
                                /* Decompresses data encoded using the public-domain 
 
3287
                                zlib/deflate compression method, reproducing the 
 
3288
                                original text or binary data */
 
3289
                                $this->_out('/Filter /FlateDecode');
 
3290
                        }
 
3291
                        $this->_out('>>');
 
3292
                        $this->_putstream(file_get_contents($ctgfile));
 
3293
                        $this->_out('endobj');
 
3294
                }
 
3295
 
 
3296
                 /**
 
3297
                 * Converts UTF-8 strings to codepoints array.<br>
 
3298
                 * Invalid byte sequences will be replaced with 0xFFFD (replacement character)<br>
 
3299
                 * Based on: http://www.faqs.org/rfcs/rfc3629.html
 
3300
                 * <pre>
 
3301
                 *        Char. number range  |        UTF-8 octet sequence
 
3302
                 *       (hexadecimal)    |              (binary)
 
3303
                 *    --------------------+-----------------------------------------------
 
3304
                 *    0000 0000-0000 007F | 0xxxxxxx
 
3305
                 *    0000 0080-0000 07FF | 110xxxxx 10xxxxxx
 
3306
                 *    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
 
3307
                 *    0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 
3308
                 *    ---------------------------------------------------------------------
 
3309
                 *
 
3310
                 *   ABFN notation:
 
3311
                 *   ---------------------------------------------------------------------
 
3312
                 *   UTF8-octets = *( UTF8-char )
 
3313
                 *   UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
 
3314
                 *   UTF8-1      = %x00-7F
 
3315
                 *   UTF8-2      = %xC2-DF UTF8-tail
 
3316
                 *
 
3317
                 *   UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
 
3318
                 *                 %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
 
3319
                 *   UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
 
3320
                 *                 %xF4 %x80-8F 2( UTF8-tail )
 
3321
                 *   UTF8-tail   = %x80-BF
 
3322
                 *   ---------------------------------------------------------------------
 
3323
                 * </pre>
 
3324
                 * @param string $str string to process.
 
3325
                 * @return array containing codepoints (UTF-8 characters values)
 
3326
                 * @access protected
 
3327
                 * @author Nicola Asuni
 
3328
                 * @since 1.53.0.TC005 (2005-01-05)
 
3329
                 */
 
3330
                function UTF8StringToArray($str) {
 
3331
                        if(!$this->isunicode) {
 
3332
                                return $str; // string is not in unicode
 
3333
                        }
 
3334
                        $unicode = array(); // array containing unicode values
 
3335
                        $bytes  = array(); // array containing single character byte sequences
 
3336
                        $numbytes  = 1; // number of octetc needed to represent the UTF-8 character
 
3337
                        
 
3338
                        $str .= ""; // force $str to be a string
 
3339
                        $length = strlen($str);
 
3340
                        
 
3341
                        for($i = 0; $i < $length; $i++) {
 
3342
                                $char = ord($str{$i}); // get one string character at time
 
3343
                                if(count($bytes) == 0) { // get starting octect
 
3344
                                        if ($char <= 0x7F) {
 
3345
                                                $unicode[] = $char; // use the character "as is" because is ASCII
 
3346
                                                $numbytes = 1;
 
3347
                                        } elseif (($char >> 0x05) == 0x06) { // 2 bytes character (0x06 = 110 BIN)
 
3348
                                                $bytes[] = ($char - 0xC0) << 0x06; 
 
3349
                                                $numbytes = 2;
 
3350
                                        } elseif (($char >> 0x04) == 0x0E) { // 3 bytes character (0x0E = 1110 BIN)
 
3351
                                                $bytes[] = ($char - 0xE0) << 0x0C; 
 
3352
                                                $numbytes = 3;
 
3353
                                        } elseif (($char >> 0x03) == 0x1E) { // 4 bytes character (0x1E = 11110 BIN)
 
3354
                                                $bytes[] = ($char - 0xF0) << 0x12; 
 
3355
                                                $numbytes = 4;
 
3356
                                        } else {
 
3357
                                                // use replacement character for other invalid sequences
 
3358
                                                $unicode[] = 0xFFFD;
 
3359
                                                $bytes = array();
 
3360
                                                $numbytes = 1;
 
3361
                                        }
 
3362
                                } elseif (($char >> 0x06) == 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN
 
3363
                                        $bytes[] = $char - 0x80;
 
3364
                                        if (count($bytes) == $numbytes) {
 
3365
                                                // compose UTF-8 bytes to a single unicode value
 
3366
                                                $char = $bytes[0];
 
3367
                                                for($j = 1; $j < $numbytes; $j++) {
 
3368
                                                        $char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06));
 
3369
                                                }
 
3370
                                                if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) {
 
3371
                                                        /* The definition of UTF-8 prohibits encoding character numbers between
 
3372
                                                        U+D800 and U+DFFF, which are reserved for use with the UTF-16
 
3373
                                                        encoding form (as surrogate pairs) and do not directly represent
 
3374
                                                        characters. */
 
3375
                                                        $unicode[] = 0xFFFD; // use replacement character
 
3376
                                                }
 
3377
                                                else {
 
3378
                                                        $unicode[] = $char; // add char to array
 
3379
                                                }
 
3380
                                                // reset data for next char
 
3381
                                                $bytes = array(); 
 
3382
                                                $numbytes = 1;
 
3383
                                        }
 
3384
                                } else {
 
3385
                                        // use replacement character for other invalid sequences
 
3386
                                        $unicode[] = 0xFFFD;
 
3387
                                        $bytes = array();
 
3388
                                        $numbytes = 1;
 
3389
                                }
 
3390
                        }
 
3391
                        return $unicode;
 
3392
                }
 
3393
                
 
3394
                /**
 
3395
                 * Converts UTF-8 strings to UTF16-BE.<br>
 
3396
                 * Based on: http://www.faqs.org/rfcs/rfc2781.html
 
3397
                 * <pre>
 
3398
                 *   Encoding UTF-16:
 
3399
                 * 
 
3400
                 *   Encoding of a single character from an ISO 10646 character value to
 
3401
                 *    UTF-16 proceeds as follows. Let U be the character number, no greater
 
3402
                 *    than 0x10FFFF.
 
3403
                 * 
 
3404
                 *    1) If U < 0x10000, encode U as a 16-bit unsigned integer and
 
3405
                 *       terminate.
 
3406
                 * 
 
3407
                 *    2) Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
 
3408
                 *       U' must be less than or equal to 0xFFFFF. That is, U' can be
 
3409
                 *       represented in 20 bits.
 
3410
                 * 
 
3411
                 *    3) Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
 
3412
                 *       0xDC00, respectively. These integers each have 10 bits free to
 
3413
                 *       encode the character value, for a total of 20 bits.
 
3414
                 * 
 
3415
                 *    4) Assign the 10 high-order bits of the 20-bit U' to the 10 low-order
 
3416
                 *       bits of W1 and the 10 low-order bits of U' to the 10 low-order
 
3417
                 *       bits of W2. Terminate.
 
3418
                 * 
 
3419
                 *    Graphically, steps 2 through 4 look like:
 
3420
                 *    U' = yyyyyyyyyyxxxxxxxxxx
 
3421
                 *    W1 = 110110yyyyyyyyyy
 
3422
                 *    W2 = 110111xxxxxxxxxx
 
3423
                 * </pre>
 
3424
                 * @param string $str string to process.
 
3425
                 * @param boolean $setbom if true set the Byte Order Mark (BOM = 0xFEFF)
 
3426
                 * @return string
 
3427
                 * @access protected
 
3428
                 * @author Nicola Asuni
 
3429
                 * @since 1.53.0.TC005 (2005-01-05)
 
3430
                 * @uses UTF8StringToArray
 
3431
                 */
 
3432
                function UTF8ToUTF16BE($str, $setbom=true) {
 
3433
                        if(!$this->isunicode) {
 
3434
                                return $str; // string is not in unicode
 
3435
                        }
 
3436
                        $outstr = ""; // string to be returned
 
3437
                        $unicode = $this->UTF8StringToArray($str); // array containing UTF-8 unicode values
 
3438
                        $numitems = count($unicode);
 
3439
                        
 
3440
                        if ($setbom) {
 
3441
                                $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
 
3442
                        }
 
3443
                        foreach($unicode as $char) {
 
3444
                                if($char == 0xFFFD) {
 
3445
                                        $outstr .= "\xFF\xFD"; // replacement character
 
3446
                                } elseif ($char < 0x10000) {
 
3447
                                        $outstr .= chr($char >> 0x08);
 
3448
                                        $outstr .= chr($char & 0xFF);
 
3449
                                } else {
 
3450
                                        $char -= 0x10000;
 
3451
                                        $w1 = 0xD800 | ($char >> 0x10);
 
3452
                                        $w2 = 0xDC00 | ($char & 0x3FF); 
 
3453
                                        $outstr .= chr($w1 >> 0x08);
 
3454
                                        $outstr .= chr($w1 & 0xFF);
 
3455
                                        $outstr .= chr($w2 >> 0x08);
 
3456
                                        $outstr .= chr($w2 & 0xFF);
 
3457
                                }
 
3458
                        }
 
3459
                        return $outstr;
 
3460
                }
 
3461
                
 
3462
                // ====================================================
 
3463
                
 
3464
                /**
 
3465
                 * Set header font.
 
3466
                 * @param array $font font
 
3467
                 * @since 1.1
 
3468
                 */
 
3469
                function setHeaderFont($font) {
 
3470
                        $this->header_font = $font;
 
3471
                }
 
3472
                
 
3473
                /**
 
3474
                 * Set footer font.
 
3475
                 * @param array $font font
 
3476
                 * @since 1.1
 
3477
                 */
 
3478
                function setFooterFont($font) {
 
3479
                        $this->footer_font = $font;
 
3480
                }
 
3481
                
 
3482
                /**
 
3483
                 * Set language array.
 
3484
                 * @param array $language
 
3485
                 * @since 1.1
 
3486
                 */
 
3487
                function setLanguageArray($language) {
 
3488
                        $this->l = $language;
 
3489
                }
 
3490
                
 
3491
                /**
 
3492
                 * Set document barcode.
 
3493
                 * @param string $bc barcode
 
3494
                 */
 
3495
                function setBarcode($bc="") {
 
3496
                        $this->barcode = $bc;
 
3497
                }
 
3498
                
 
3499
                /**
 
3500
                 * Print Barcode.
 
3501
                 * @param int $x x position in user units
 
3502
                 * @param int $y y position in user units
 
3503
                 * @param int $w width in user units
 
3504
                 * @param int $h height position in user units
 
3505
                 * @param string $type type of barcode (I25, C128A, C128B, C128C, C39)
 
3506
                 * @param string $style barcode style
 
3507
                 * @param string $font font for text
 
3508
                 * @param int $xres x resolution
 
3509
                 * @param string $code code to print
 
3510
                 */
 
3511
                function writeBarcode($x, $y, $w, $h, $type, $style, $font, $xres, $code) {
 
3512
                        require_once(dirname(__FILE__)."/barcode/barcode.php");
 
3513
                        require_once(dirname(__FILE__)."/barcode/i25object.php");
 
3514
                        require_once(dirname(__FILE__)."/barcode/c39object.php");
 
3515
                        require_once(dirname(__FILE__)."/barcode/c128aobject.php");
 
3516
                        require_once(dirname(__FILE__)."/barcode/c128bobject.php");
 
3517
                        require_once(dirname(__FILE__)."/barcode/c128cobject.php");
 
3518
                        
 
3519
                        if (empty($code)) {
 
3520
                                return;
 
3521
                        }
 
3522
                        
 
3523
                        if (empty($style)) {
 
3524
                                $style  = BCS_ALIGN_LEFT;
 
3525
                                $style |= BCS_IMAGE_PNG;
 
3526
                                $style |= BCS_TRANSPARENT;
 
3527
                                //$style |= BCS_BORDER;
 
3528
                                //$style |= BCS_DRAW_TEXT;
 
3529
                                //$style |= BCS_STRETCH_TEXT;
 
3530
                                //$style |= BCS_REVERSE_COLOR;
 
3531
                        }
 
3532
                        if (empty($font)) {$font = BCD_DEFAULT_FONT;}
 
3533
                        if (empty($xres)) {$xres = BCD_DEFAULT_XRES;}
 
3534
                        
 
3535
                        $scale_factor = 1.5 * $xres * $this->k;
 
3536
                        $bc_w = round($w * $scale_factor); //width in points
 
3537
                        $bc_h = round($h * $scale_factor); //height in points
 
3538
                        
 
3539
                        switch (strtoupper($type)) {
 
3540
                                case "I25": {
 
3541
                                        $obj = new I25Object($bc_w, $bc_h, $style, $code);
 
3542
                                        break;
 
3543
                                }
 
3544
                                case "C128A": {
 
3545
                                        $obj = new C128AObject($bc_w, $bc_h, $style, $code);
 
3546
                                        break;
 
3547
                                }
 
3548
                                default:
 
3549
                                case "C128B": {
 
3550
                                        $obj = new C128BObject($bc_w, $bc_h, $style, $code);
 
3551
                                        break;
 
3552
                                }
 
3553
                                case "C128C": {
 
3554
                                        $obj = new C128CObject($bc_w, $bc_h, $style, $code);
 
3555
                                        break;
 
3556
                                }
 
3557
                                case "C39": {
 
3558
                                        $obj = new C39Object($bc_w, $bc_h, $style, $code);
 
3559
                                        break;
 
3560
                                }
 
3561
                        }
 
3562
                        
 
3563
                        $obj->SetFont($font);   
 
3564
                        $obj->DrawObject($xres);
 
3565
                        
 
3566
                        //use a temporary file....
 
3567
                        $tmpName = tempnam(K_PATH_CACHE,'img');
 
3568
                        imagepng($obj->getImage(), $tmpName);
 
3569
                        $this->Image($tmpName, $x, $y, $w, $h, 'png');
 
3570
                        $obj->DestroyObject();
 
3571
                        unset($obj);
 
3572
                        unlink($tmpName);
 
3573
                }
 
3574
                
 
3575
                /**
 
3576
                 * Returns the PDF data.
 
3577
                 */
 
3578
                function getPDFData() {
 
3579
                        if($this->state < 3) {
 
3580
                                $this->Close();
 
3581
                        }
 
3582
                        return $this->buffer;
 
3583
                }
 
3584
                
 
3585
                // --- HTML PARSER FUNCTIONS ---
 
3586
                
 
3587
                /**
 
3588
                 * Allows to preserve some HTML formatting.<br />
 
3589
                 * Supports: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small
 
3590
                 * @param string $html text to display
 
3591
                 * @param boolean $ln if true add a new line after text (default = true)
 
3592
                 * @param int $fill Indicates if the background must be painted (1) or transparent (0). Default value: 0.
 
3593
                 */
 
3594
                function writeHTML($html, $ln=true, $fill=0) {
 
3595
                                                
 
3596
                        // store some variables
 
3597
                        $html=strip_tags($html,"<h1><h2><h3><h4><h5><h6><b><u><i><a><img><p><br><br/><strong><em><font><blockquote><li><ul><ol><hr><td><th><tr><table><sup><sub><small>"); //remove all unsupported tags
 
3598
                        //replace carriage returns, newlines and tabs
 
3599
                        $repTable = array("\t" => " ", "\n" => " ", "\r" => " ", "\0" => " ", "\x0B" => " "); 
 
3600
                        $html = strtr($html, $repTable);
 
3601
                        $pattern = '/(<[^>]+>)/Uu';
 
3602
                        $a = preg_split($pattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); //explodes the string
 
3603
                        
 
3604
                        if (empty($this->lasth)) {
 
3605
                                //set row height
 
3606
                                $this->lasth = $this->FontSize * K_CELL_HEIGHT_RATIO; 
 
3607
                        }
 
3608
                        
 
3609
                        foreach($a as $key=>$element) {
 
3610
                                if (!preg_match($pattern, $element)) {
 
3611
                                        //Text
 
3612
                                        if($this->HREF) {
 
3613
                                                $this->addHtmlLink($this->HREF, $element, $fill);
 
3614
                                        }
 
3615
                                        elseif($this->tdbegin) {
 
3616
                                                if((strlen(trim($element)) > 0) AND ($element != "&nbsp;")) {
 
3617
                                                        $this->Cell($this->tdwidth, $this->tdheight, $this->unhtmlentities($element), $this->tableborder, '', $this->tdalign, $this->tdbgcolor);
 
3618
                                                }
 
3619
                                                elseif($element == "&nbsp;") {
 
3620
                                                        $this->Cell($this->tdwidth, $this->tdheight, '', $this->tableborder, '', $this->tdalign, $this->tdbgcolor);
 
3621
                                                }
 
3622
                                        }
 
3623
                                        else {
 
3624
                                                $this->Write($this->lasth, stripslashes($this->unhtmlentities($element)), '', $fill);
 
3625
                                        }
 
3626
                                }
 
3627
                                else {
 
3628
                                        $element = substr($element, 1, -1);
 
3629
                                        //Tag
 
3630
                                        if($element{0}=='/') {
 
3631
                                                $this->closedHTMLTagHandler(strtolower(substr($element, 1)));
 
3632
                                        }
 
3633
                                        else {
 
3634
                                                //Extract attributes
 
3635
                                                // get tag name
 
3636
                                                preg_match('/([a-zA-Z0-9]*)/', $element, $tag);
 
3637
                                                $tag = strtolower($tag[0]);
 
3638
                                                // get attributes
 
3639
                                                preg_match_all('/([^=\s]*)=["\']?([^"\']*)["\']?/', $element, $attr_array, PREG_PATTERN_ORDER);
 
3640
                                                $attr = array(); // reset attribute array
 
3641
                                                while(list($id,$name)=each($attr_array[1])) {
 
3642
                                                        $attr[strtolower($name)] = $attr_array[2][$id];
 
3643
                                                }
 
3644
                                                $this->openHTMLTagHandler($tag, $attr, $fill);
 
3645
                                        }
 
3646
                                }
 
3647
                        }
 
3648
                        if ($ln) {
 
3649
                                $this->Ln($this->lasth);
 
3650
                        }
 
3651
                }
 
3652
                
 
3653
                /**
 
3654
                 * Prints a cell (rectangular area) with optional borders, background color and html text string. The upper-left corner of the cell corresponds to the current position. After the call, the current position moves to the right or to the next line.<br />
 
3655
                 * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
 
3656
                 * @param float $w Cell width. If 0, the cell extends up to the right margin.
 
3657
                 * @param float $h Cell minimum height. The cell extends automatically if needed.
 
3658
                 * @param float $x upper-left corner X coordinate
 
3659
                 * @param float $y upper-left corner Y coordinate
 
3660
                 * @param string $html html text to print. Default value: empty string.
 
3661
                 * @param mixed $border Indicates if borders must be drawn around the cell. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
 
3662
                 * @param int $ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
 
3663
        Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
 
3664
                 * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
 
3665
                 * @see Cell()
 
3666
                 */
 
3667
                function writeHTMLCell($w, $h, $x, $y, $html='', $border=0, $ln=0, $fill=0) {
 
3668
                        
 
3669
                        if (empty($this->lasth)) {
 
3670
                                //set row height
 
3671
                                $this->lasth = $this->FontSize * K_CELL_HEIGHT_RATIO; 
 
3672
                        }
 
3673
                        
 
3674
                        if (empty($x)) {
 
3675
                                $x = $this->GetX();
 
3676
                        }
 
3677
                        if (empty($y)) {
 
3678
                                $y = $this->GetY();
 
3679
                        }
 
3680
                        
 
3681
                        // get current page number
 
3682
                        $pagenum = $this->page;
 
3683
                        
 
3684
                        $this->SetX($x);
 
3685
                        $this->SetY($y);
 
3686
                                        
 
3687
                        if(empty($w)) {
 
3688
                                $w = $this->fw - $x - $this->rMargin;
 
3689
                        }
 
3690
                        
 
3691
                        // store original margin values
 
3692
                        $lMargin = $this->lMargin;
 
3693
                        $rMargin = $this->rMargin;
 
3694
                        
 
3695
                        // set new margin values
 
3696
                        $this->SetLeftMargin($x);
 
3697
                        $this->SetRightMargin($this->fw - $x - $w);
 
3698
                                        
 
3699
                        // calculate remaining vertical space on page
 
3700
                        $restspace = $this->getPageHeight() - $this->GetY() - $this->getBreakMargin();
 
3701
                        
 
3702
                        $this->writeHTML($html, true, $fill); // write html text
 
3703
                        
 
3704
                        $currentY =  $this->GetY();
 
3705
                        
 
3706
                        // check if a new page has been created
 
3707
                        if ($this->page > $pagenum) {
 
3708
                                // design a cell around the text on first page
 
3709
                                $currentpage = $this->page;
 
3710
                                $this->page = $pagenum;
 
3711
                                $this->SetY($this->getPageHeight() - $restspace - $this->getBreakMargin());
 
3712
                                $h = $restspace - 1;
 
3713
                                $this->Cell($w, $h, "", $border, $ln, 'L', 0);
 
3714
                                // design a cell around the text on last page
 
3715
                                $this->page = $currentpage;
 
3716
                                $h = $currentY - $this->tMargin;
 
3717
                                $this->SetY($this->tMargin); // put cursor at the beginning of text
 
3718
                                $this->Cell($w, $h, "", $border, $ln, 'L', 0);
 
3719
                        } else {
 
3720
                                $h = max($h, ($currentY - $y));
 
3721
                                $this->SetY($y); // put cursor at the beginning of text
 
3722
                                // design a cell around the text
 
3723
                                $this->Cell($w, $h, "", $border, $ln, 'L', 0);
 
3724
                        }
 
3725
                        
 
3726
                        // restore original margin values
 
3727
                        $this->SetLeftMargin($lMargin);
 
3728
                        $this->SetRightMargin($rMargin);
 
3729
                        
 
3730
                        if ($ln) {
 
3731
                                $this->Ln(0);
 
3732
                        }
 
3733
                }
 
3734
                
 
3735
                /**
 
3736
                 * Process opening tags.
 
3737
                 * @param string $tag tag name (in uppercase)
 
3738
                 * @param string $attr tag attribute (in uppercase)
 
3739
                 * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
 
3740
                 * @access private
 
3741
                 */
 
3742
                function openHTMLTagHandler($tag, $attr, $fill=0) {
 
3743
                        //Opening tag
 
3744
                        switch($tag) {
 
3745
                                case 'table': {
 
3746
                                        if ((isset($attr['border'])) AND ($attr['border'] != '')) {
 
3747
                                                $this->tableborder = $attr['border'];
 
3748
                                        }
 
3749
                                        else {
 
3750
                                                $this->tableborder = 0;
 
3751
                                        }
 
3752
                                        break;
 
3753
                                }
 
3754
                                case 'tr': {
 
3755
                                        break;
 
3756
                                }
 
3757
                                case 'td':
 
3758
                                case 'th': {
 
3759
                                        if ((isset($attr['width'])) AND ($attr['width'] != '')) {
 
3760
                                                $this->tdwidth = ($attr['width']/4);
 
3761
                                        }
 
3762
                                        else {
 
3763
                                                $this->tdwidth = (($this->w - $this->lMargin - $this->rMargin) / $this->default_table_columns);
 
3764
                                        }
 
3765
                                        if ((isset($attr['height'])) AND ($attr['height'] != '')) {
 
3766
                                                $this->tdheight=($attr['height'] / $this->k);
 
3767
                                        }
 
3768
                                        else {
 
3769
                                                $this->tdheight = $this->lasth;
 
3770
                                        }
 
3771
                                        if ((isset($attr['align'])) AND ($attr['align'] != '')) {
 
3772
                                                switch ($attr['align']) {
 
3773
                                                        case 'center': {
 
3774
                                                                $this->tdalign = "C";
 
3775
                                                                break;
 
3776
                                                        }
 
3777
                                                        case 'right': {
 
3778
                                                                $this->tdalign = "R";
 
3779
                                                                break;
 
3780
                                                        }
 
3781
                                                        default:
 
3782
                                                        case 'left': {
 
3783
                                                                $this->tdalign = "L";
 
3784
                                                                break;
 
3785
                                                        }
 
3786
                                                }
 
3787
                                        }
 
3788
                                        if ((isset($attr['bgcolor'])) AND ($attr['bgcolor'] != '')) {
 
3789
                                                $coul = $this->convertColorHexToDec($attr['bgcolor']);
 
3790
                                                $this->SetFillColor($coul['R'], $coul['G'], $coul['B']);
 
3791
                                                $this->tdbgcolor=true;
 
3792
                                        }
 
3793
                                        $this->tdbegin=true;
 
3794
                                        break;
 
3795
                                }
 
3796
                                case 'hr': {
 
3797
                                        $this->Ln();
 
3798
                                        if ((isset($attr['width'])) AND ($attr['width'] != '')) {
 
3799
                                                $hrWidth = $attr['width'];
 
3800
                                        }
 
3801
                                        else {
 
3802
                                                $hrWidth = $this->w - $this->lMargin - $this->rMargin;
 
3803
                                        }
 
3804
                                        $x = $this->GetX();
 
3805
                                        $y = $this->GetY();
 
3806
                                        $this->SetLineWidth(0.2);
 
3807
                                        $this->Line($x, $y, $x + $hrWidth, $y);
 
3808
                                        $this->SetLineWidth(0.2);
 
3809
                                        $this->Ln();
 
3810
                                        break;
 
3811
                                }
 
3812
                                case 'strong': {
 
3813
                                        $this->setStyle('b', true);
 
3814
                                        break;
 
3815
                                }
 
3816
                                case 'em': {
 
3817
                                        $this->setStyle('i', true);
 
3818
                                        break;
 
3819
                                }
 
3820
                                case 'b':
 
3821
                                case 'i':
 
3822
                                case 'u': {
 
3823
                                        $this->setStyle($tag, true);
 
3824
                                        break;
 
3825
                                }
 
3826
                                case 'a': {
 
3827
                                        $this->HREF = $attr['href'];
 
3828
                                        break;
 
3829
                                }
 
3830
                                case 'img': {
 
3831
                                        if(isset($attr['src'])) {
 
3832
                                                // replace relative path with real server path
 
3833
                                                $attr['src'] = str_replace(K_PATH_URL_CACHE, K_PATH_CACHE, $attr['src']);
 
3834
                                                if(!isset($attr['width'])) {
 
3835
                                                        $attr['width'] = 0;
 
3836
                                                }
 
3837
                                                if(!isset($attr['height'])) {
 
3838
                                                        $attr['height'] = 0;
 
3839
                                                }
 
3840
                                                
 
3841
                                                $this->Image($attr['src'], $this->GetX(),$this->GetY(), $this->pixelsToMillimeters($attr['width']), $this->pixelsToMillimeters($attr['height']));
 
3842
                                                //$this->SetX($this->img_rb_x);
 
3843
                                                $this->SetY($this->img_rb_y);
 
3844
                                                
 
3845
                                        }
 
3846
                                        break;
 
3847
                                }
 
3848
                                case 'ul': {
 
3849
                                        $this->listordered = false;
 
3850
                                        $this->listcount = 0;
 
3851
                                        break;
 
3852
                                }
 
3853
                                case 'ol': {
 
3854
                                        $this->listordered = true;
 
3855
                                        $this->listcount = 0;
 
3856
                                        break;
 
3857
                                }
 
3858
                                case 'li': {
 
3859
                                        $this->Ln();
 
3860
                                        if ($this->listordered) {
 
3861
                                                $this->lispacer = "    ".(++$this->listcount).". ";
 
3862
                                        }
 
3863
                                        else {
 
3864
                                                //unordered list simbol
 
3865
                                                $this->lispacer = "    -  ";
 
3866
                                        }
 
3867
                                        $this->Write($this->lasth, $this->lispacer, '', $fill);
 
3868
                                        break;
 
3869
                                }
 
3870
                                case 'blockquote':
 
3871
                                case 'br': {
 
3872
                                        $this->Ln();
 
3873
                                        if(strlen($this->lispacer) > 0) {
 
3874
                                                $this->x += $this->GetStringWidth($this->lispacer);
 
3875
                                        }
 
3876
                                        break;
 
3877
                                }
 
3878
                                case 'p': {
 
3879
                                        $this->Ln();
 
3880
                                        $this->Ln();
 
3881
                                        break;
 
3882
                                }
 
3883
                                case 'sup': {
 
3884
                                        $currentFontSize = $this->FontSize;
 
3885
                                        $this->tempfontsize = $this->FontSizePt;
 
3886
                                        $this->SetFontSize($this->FontSizePt * K_SMALL_RATIO);
 
3887
                                        $this->SetXY($this->GetX(), $this->GetY() - (($currentFontSize - $this->FontSize)*(K_SMALL_RATIO)));
 
3888
                                        break;
 
3889
                                }
 
3890
                                case 'sub': {
 
3891
                                        $currentFontSize = $this->FontSize;
 
3892
                                        $this->tempfontsize = $this->FontSizePt;
 
3893
                                        $this->SetFontSize($this->FontSizePt * K_SMALL_RATIO);
 
3894
                                        $this->SetXY($this->GetX(), $this->GetY() + (($currentFontSize - $this->FontSize)*(K_SMALL_RATIO)));
 
3895
                                        break;
 
3896
                                }
 
3897
                                case 'small': {
 
3898
                                        $currentFontSize = $this->FontSize;
 
3899
                                        $this->tempfontsize = $this->FontSizePt;
 
3900
                                        $this->SetFontSize($this->FontSizePt * K_SMALL_RATIO);
 
3901
                                        $this->SetXY($this->GetX(), $this->GetY() + (($currentFontSize - $this->FontSize)/3));
 
3902
                                        break;
 
3903
                                }
 
3904
                                case 'font': {
 
3905
                                        if (isset($attr['color']) AND $attr['color']!='') {
 
3906
                                                $coul = $this->convertColorHexToDec($attr['color']);
 
3907
                                                $this->SetTextColor($coul['R'],$coul['G'],$coul['B']);
 
3908
                                                $this->issetcolor=true;
 
3909
                                        }
 
3910
                                        if (isset($attr['face']) and in_array(strtolower($attr['face']), $this->fontlist)) {
 
3911
                                                $this->SetFont(strtolower($attr['FACE']));
 
3912
                                                $this->issetfont=true;
 
3913
                                        }
 
3914
                                        if (isset($attr['size'])) {
 
3915
                                                $headsize = intval($attr['size']);
 
3916
                                        } else {
 
3917
                                                $headsize = 0;
 
3918
                                        }
 
3919
                                        $currentFontSize = $this->FontSize;
 
3920
                                        $this->tempfontsize = $this->FontSizePt;
 
3921
                                        $this->SetFontSize($this->FontSizePt + $headsize);
 
3922
                                        $this->lasth = $this->FontSize * K_CELL_HEIGHT_RATIO;
 
3923
                                        break;
 
3924
                                }
 
3925
                                case 'h1': 
 
3926
                                case 'h2': 
 
3927
                                case 'h3': 
 
3928
                                case 'h4': 
 
3929
                                case 'h5': 
 
3930
                                case 'h6': {
 
3931
                                        $headsize = (4 - substr($tag, 1)) * 2;
 
3932
                                        $currentFontSize = $this->FontSize;
 
3933
                                        $this->tempfontsize = $this->FontSizePt;
 
3934
                                        $this->SetFontSize($this->FontSizePt + $headsize);
 
3935
                                        $this->setStyle('b', true);
 
3936
                                        $this->lasth = $this->FontSize * K_CELL_HEIGHT_RATIO;
 
3937
                                        break;
 
3938
                                }
 
3939
                        }
 
3940
                }
 
3941
                
 
3942
                /**
 
3943
                 * Process closing tags.
 
3944
                 * @param string $tag tag name (in uppercase)
 
3945
                 * @access private
 
3946
                 */
 
3947
                function closedHTMLTagHandler($tag) {
 
3948
                        //Closing tag
 
3949
                        switch($tag) {
 
3950
                                case 'td':
 
3951
                                case 'th': {
 
3952
                                        $this->tdbegin = false;
 
3953
                                        $this->tdwidth = 0;
 
3954
                                        $this->tdheight = 0;
 
3955
                                        $this->tdalign = "L";
 
3956
                                        $this->tdbgcolor = false;
 
3957
                                        $this->SetFillColor($this->prevFillColor[0], $this->prevFillColor[1], $this->prevFillColor[2]);
 
3958
                                        break;
 
3959
                                }
 
3960
                                case 'tr': {
 
3961
                                        $this->Ln();
 
3962
                                        break;
 
3963
                                }
 
3964
                                case 'table': {
 
3965
                                        $this->tableborder=0;
 
3966
                                        break;
 
3967
                                }
 
3968
                                case 'strong': {
 
3969
                                        $this->setStyle('b', false);
 
3970
                                        break;
 
3971
                                }
 
3972
                                case 'em': {
 
3973
                                        $this->setStyle('i', false);
 
3974
                                        break;
 
3975
                                }
 
3976
                                case 'b':
 
3977
                                case 'i':
 
3978
                                case 'u': {
 
3979
                                        $this->setStyle($tag, false);
 
3980
                                        break;
 
3981
                                }
 
3982
                                case 'a': {
 
3983
                                        $this->HREF = '';
 
3984
                                        break;
 
3985
                                }
 
3986
                                case 'sup': {
 
3987
                                        $currentFontSize = $this->FontSize;
 
3988
                                        $this->SetFontSize($this->tempfontsize);
 
3989
                                        $this->tempfontsize = $this->FontSizePt;
 
3990
                                        $this->SetXY($this->GetX(), $this->GetY() - (($currentFontSize - $this->FontSize)*(K_SMALL_RATIO)));
 
3991
                                        break;
 
3992
                                }
 
3993
                                case 'sub': {
 
3994
                                        $currentFontSize = $this->FontSize;
 
3995
                                        $this->SetFontSize($this->tempfontsize);
 
3996
                                        $this->tempfontsize = $this->FontSizePt;
 
3997
                                        $this->SetXY($this->GetX(), $this->GetY() + (($currentFontSize - $this->FontSize)*(K_SMALL_RATIO)));
 
3998
                                        break;
 
3999
                                }
 
4000
                                case 'small': {
 
4001
                                        $currentFontSize = $this->FontSize;
 
4002
                                        $this->SetFontSize($this->tempfontsize);
 
4003
                                        $this->tempfontsize = $this->FontSizePt;
 
4004
                                        $this->SetXY($this->GetX(), $this->GetY() - (($this->FontSize - $currentFontSize)/3));
 
4005
                                        break;
 
4006
                                }
 
4007
                                case 'font': {
 
4008
                                        if ($this->issetcolor == true) {
 
4009
                                                $this->SetTextColor($this->prevTextColor[0], $this->prevTextColor[1], $this->prevTextColor[2]);
 
4010
                                        }
 
4011
                                        if ($this->issetfont) {
 
4012
                                                $this->FontFamily = $this->prevFontFamily;
 
4013
                                                $this->FontStyle = $this->prevFontStyle;
 
4014
                                                $this->SetFont($this->FontFamily);
 
4015
                                                $this->issetfont = false;
 
4016
                                        }
 
4017
                                        $currentFontSize = $this->FontSize;
 
4018
                                        $this->SetFontSize($this->tempfontsize);
 
4019
                                        $this->tempfontsize = $this->FontSizePt;
 
4020
                                        //$this->TextColor = $this->prevTextColor;
 
4021
                                        $this->lasth = $this->FontSize * K_CELL_HEIGHT_RATIO;
 
4022
                                        break;
 
4023
                                }
 
4024
                                case 'ul': {
 
4025
                                        $this->Ln();
 
4026
                                        break;
 
4027
                                }
 
4028
                                case 'ol': {
 
4029
                                        $this->Ln();
 
4030
                                        break;
 
4031
                                }
 
4032
                                case 'li': {
 
4033
                                        $this->lispacer = "";
 
4034
                                        break;
 
4035
                                }
 
4036
                                case 'h1': 
 
4037
                                case 'h2': 
 
4038
                                case 'h3': 
 
4039
                                case 'h4': 
 
4040
                                case 'h5': 
 
4041
                                case 'h6': {
 
4042
                                        $currentFontSize = $this->FontSize;
 
4043
                                        $this->SetFontSize($this->tempfontsize);
 
4044
                                        $this->tempfontsize = $this->FontSizePt;
 
4045
                                        $this->setStyle('b', false);
 
4046
                                        $this->Ln();
 
4047
                                        $this->lasth = $this->FontSize * K_CELL_HEIGHT_RATIO;
 
4048
                                        break;
 
4049
                                }
 
4050
                                default : {
 
4051
                                        break;
 
4052
                                }
 
4053
                        }
 
4054
                }
 
4055
                
 
4056
                /**
 
4057
                 * Sets font style.
 
4058
                 * @param string $tag tag name (in lowercase)
 
4059
                 * @param boolean $enable
 
4060
                 * @access private
 
4061
                 */
 
4062
                function setStyle($tag, $enable) {
 
4063
                        //Modify style and select corresponding font
 
4064
                        $this->$tag += ($enable ? 1 : -1);
 
4065
                        $style='';
 
4066
                        foreach(array('b', 'i', 'u') as $s) {
 
4067
                                if($this->$s > 0) {
 
4068
                                        $style .= $s;
 
4069
                                }
 
4070
                        }
 
4071
                        $this->SetFont('', $style);
 
4072
                }
 
4073
                
 
4074
                /**
 
4075
                 * Output anchor link.
 
4076
                 * @param string $url link URL
 
4077
                 * @param string $name link name
 
4078
                 * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
 
4079
                 * @access public
 
4080
                 */
 
4081
                function addHtmlLink($url, $name, $fill=0) {
 
4082
                        //Put a hyperlink
 
4083
                        $this->SetTextColor(0, 0, 255);
 
4084
                        $this->setStyle('u', true);
 
4085
                        $this->Write($this->lasth, $name, $url, $fill);
 
4086
                        $this->setStyle('u', false);
 
4087
                        $this->SetTextColor(0);
 
4088
                }
 
4089
                
 
4090
                /**
 
4091
                 * Returns an associative array (keys: R,G,B) from 
 
4092
                 * a hex html code (e.g. #3FE5AA).
 
4093
                 * @param string $color hexadecimal html color [#rrggbb]
 
4094
                 * @return array
 
4095
                 * @access private
 
4096
                 */
 
4097
                function convertColorHexToDec($color = "#000000"){
 
4098
                        $tbl_color = array();
 
4099
                        $tbl_color['R'] = hexdec(substr($color, 1, 2));
 
4100
                        $tbl_color['G'] = hexdec(substr($color, 3, 2));
 
4101
                        $tbl_color['B'] = hexdec(substr($color, 5, 2));
 
4102
                        return $tbl_color;
 
4103
                }
 
4104
                
 
4105
                /**
 
4106
                 * Converts pixels to millimeters in 72 dpi.
 
4107
                 * @param int $px pixels
 
4108
                 * @return float millimeters
 
4109
                 * @access private
 
4110
                 */
 
4111
                function pixelsToMillimeters($px){
 
4112
                        return $px * 25.4 / 72;
 
4113
                }
 
4114
                        
 
4115
                /**
 
4116
                 * Reverse function for htmlentities.
 
4117
                 * Convert entities in UTF-8.
 
4118
                 *
 
4119
                 * @param $text_to_convert Text to convert.
 
4120
                 * @return string converted
 
4121
                 */
 
4122
                function unhtmlentities($text_to_convert) {
 
4123
                        require_once(dirname(__FILE__).'/html_entity_decode_php4.php');
 
4124
                        return html_entity_decode_php4($text_to_convert);
 
4125
                }
 
4126
        } // END OF CLASS
 
4127
 
 
4128
        //Handle special IE contype request
 
4129
        if(isset($_SERVER['HTTP_USER_AGENT']) AND ($_SERVER['HTTP_USER_AGENT']=='contype')) {
 
4130
                header('Content-Type: application/pdf');
 
4131
                exit;
 
4132
        }
 
4133
        
 
4134
}
 
4135
//============================================================+
 
4136
// END OF FILE
 
4137
//============================================================+
 
4138
?>