11define(
'tFPDF_VERSION',
'1.24');
79public function __construct($orientation=
'P', $unit=
'mm', $size=
'A4')
87 $this->pages =
array();
88 $this->PageSizes =
array();
90 $this->fonts =
array();
91 $this->FontFiles =
array();
92 $this->diffs =
array();
93 $this->images =
array();
94 $this->links =
array();
95 $this->InHeader =
false;
96 $this->InFooter =
false;
98 $this->FontFamily =
'';
99 $this->FontStyle =
'';
100 $this->FontSizePt = 12;
101 $this->underline =
false;
102 $this->DrawColor =
'0 G';
103 $this->FillColor =
'0 g';
104 $this->TextColor =
'0 g';
105 $this->ColorFlag =
false;
108 if(defined(
'FPDF_FONTPATH'))
111 if(mb_substr($this->fontpath,-1,mb_strlen($this->fontpath,
'8bit'),
'8bit')!=
'/' && mb_substr($this->fontpath,-1,mb_strlen($this->fontpath,
'8bit'),
'8bit')!=
'\\')
112 $this->fontpath .=
'/';
114 elseif(is_dir(__DIR__.
'/font'))
115 $this->fontpath = __DIR__.'/font/';
117 $this->fontpath = '';
119 $this->CoreFonts =
array('courier', 'helvetica', 'times', 'symbol', 'zapfdingbats');
130 $this->Error('Incorrect unit: '.$unit);
132 $this->StdPageSizes =
array('a3'=>
array(841.89,1190.55), 'a4'=>
array(595.28,841.89), 'a5'=>
array(420.94,595.28),
133 'letter'=>
array(612,792), 'legal'=>
array(612,1008));
134 $size = $this->_getpagesize($size);
135 $this->DefPageSize = $size;
136 $this->CurPageSize = $size;
138 $orientation = mb_strtolower($orientation);
139 if($orientation==
'p' || $orientation=='portrait')
141 $this->DefOrientation =
'P';
145 elseif($orientation==
'l' || $orientation==
'landscape')
147 $this->DefOrientation =
'L';
152 $this->
Error(
'Incorrect orientation: '.$orientation);
153 $this->CurOrientation = $this->DefOrientation;
164 $this->SetAutoPageBreak(
true,2*
$margin);
166 $this->SetDisplayMode(
'default');
168 $this->SetCompression(
true);
170 $this->PDFVersion =
'1.3';
173function SetMargins($left, $top,
$right=
null)
176 $this->lMargin = $left;
177 $this->tMargin = $top;
187 if($this->page>0 && $this->x<
$margin)
197function SetRightMargin(
$margin)
203function SetAutoPageBreak($auto,
$margin=0)
206 $this->AutoPageBreak = $auto;
208 $this->PageBreakTrigger = $this->h-
$margin;
211function SetDisplayMode($zoom, $layout=
'default')
214 if($zoom==
'fullpage' || $zoom==
'fullwidth' || $zoom==
'real' || $zoom==
'default' || !is_string($zoom))
215 $this->ZoomMode = $zoom;
217 $this->
Error(
'Incorrect zoom display mode: '.$zoom);
218 if($layout==
'single' || $layout==
'continuous' || $layout==
'two' || $layout==
'default')
221 $this->
Error(
'Incorrect layout display mode: '.$layout);
224function SetCompression($compress)
227 if(function_exists(
'gzcompress'))
228 $this->compress = $compress;
230 $this->compress =
false;
233function SetTitle(
$title, $isUTF8=
false)
241function SetSubject($subject, $isUTF8=
false)
245 $subject = $this->_UTF8toUTF16($subject);
246 $this->subject = $subject;
249function SetAuthor($author, $isUTF8=
false)
253 $author = $this->_UTF8toUTF16($author);
254 $this->author = $author;
257function SetKeywords($keywords, $isUTF8=
false)
261 $keywords = $this->_UTF8toUTF16($keywords);
262 $this->keywords = $keywords;
265function SetCreator($creator, $isUTF8=
false)
269 $creator = $this->_UTF8toUTF16($creator);
270 $this->creator = $creator;
273function AliasNbPages($alias=
'{nb}')
276 $this->AliasNbPages = $alias;
282 throw new Exception($msg, E_USER_ERROR);
299 $this->InFooter =
true;
301 $this->InFooter =
false;
308function AddPage($orientation=
'', $size=
'')
313 $family = $this->FontFamily;
314 $style = $this->FontStyle.($this->underline ?
'U' :
'');
315 $fontsize = $this->FontSizePt;
316 $lw = $this->LineWidth;
317 $dc = $this->DrawColor;
318 $fc = $this->FillColor;
319 $tc = $this->TextColor;
320 $cf = $this->ColorFlag;
324 $this->InFooter =
true;
326 $this->InFooter =
false;
331 $this->_beginpage($orientation,$size);
335 $this->LineWidth = $lw;
336 $this->_out(sprintf(
'%.2F w',$lw*$this->k));
339 $this->SetFont($family,$style,$fontsize);
341 $this->DrawColor = $dc;
344 $this->FillColor = $fc;
347 $this->TextColor = $tc;
348 $this->ColorFlag = $cf;
350 $this->InHeader =
true;
352 $this->InHeader =
false;
354 if($this->LineWidth!=$lw)
356 $this->LineWidth = $lw;
357 $this->_out(sprintf(
'%.2F w',$lw*$this->k));
361 $this->SetFont($family,$style,$fontsize);
363 if($this->DrawColor!=$dc)
365 $this->DrawColor = $dc;
368 if($this->FillColor!=$fc)
370 $this->FillColor = $fc;
373 $this->TextColor = $tc;
374 $this->ColorFlag = $cf;
393function SetDrawColor($r, $g=
null, $b=
null)
396 if(($r==0 && $g==0 && $b==0) || $g===
null)
397 $this->DrawColor = sprintf(
'%.3F G',$r/255);
399 $this->DrawColor = sprintf(
'%.3F %.3F %.3F RG',$r/255,$g/255,$b/255);
401 $this->_out($this->DrawColor);
404function SetFillColor($r, $g=
null, $b=
null)
407 if(($r==0 && $g==0 && $b==0) || $g===
null)
408 $this->FillColor = sprintf(
'%.3F g',$r/255);
410 $this->FillColor = sprintf(
'%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
411 $this->ColorFlag = ($this->FillColor!=$this->TextColor);
413 $this->_out($this->FillColor);
416function SetTextColor($r, $g=
null, $b=
null)
419 if(($r==0 && $g==0 && $b==0) || $g===
null)
420 $this->TextColor = sprintf(
'%.3F g',$r/255);
422 $this->TextColor = sprintf(
'%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
423 $this->ColorFlag = ($this->FillColor!=$this->TextColor);
426function GetStringWidth($s)
430 $cw = &$this->CurrentFont[
'cw'];
432 if ($this->unifontSubset) {
433 $unicode = $this->UTF8StringToArray($s);
434 foreach($unicode as $char) {
435 if (isset($cw[$char])) { $w += (ord($cw[2*$char])<<8) + ord($cw[2*$char+1]); }
436 else if($char>0 && $char<128 && isset($cw[chr($char)])) { $w += $cw[chr($char)]; }
437 else if(isset($this->CurrentFont[
'desc'][
'MissingWidth'])) { $w += $this->CurrentFont[
'desc'][
'MissingWidth']; }
438 else if(isset($this->CurrentFont[
'MissingWidth'])) { $w += $this->CurrentFont[
'MissingWidth']; }
443 $l = mb_strlen($s,
'8bit');
447 return $w*$this->FontSize/1000;
450function SetLineWidth(
$width)
453 $this->LineWidth =
$width;
455 $this->_out(sprintf(
'%.2F w',
$width*$this->k));
461 $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));
464function Rect($x, $y, $w, $h, $style=
'')
469 elseif($style==
'FD' || $style==
'DF')
473 $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
476function AddFont($family, $style='', $file='', $uni=
false)
479 $family = mb_strtolower($family);
480 $style = mb_strtoupper($style);
485 $file = str_replace(
' ',
'',$family).mb_strtolower($style).
'.ttf';
488 $file = str_replace(
' ',
'',$family).mb_strtolower($style).
'.php';
491 $fontkey = $family.$style;
492 if(isset($this->fonts[$fontkey]))
496 if (defined(
"_SYSTEM_TTFONTS") && file_exists(_SYSTEM_TTFONTS.$file )) { $ttffilename = _SYSTEM_TTFONTS.$file ; }
497 else { $ttffilename = $this->_getfontpath().
'/'.$file ; }
498 $unifilename = $this->_getfontpath().
'/'.mb_strtolower(mb_substr($file,0,(mb_strpos($file,
'.',0,
'8bit')),
'8bit'));
501 $ttfstat = stat($ttffilename);
502 if (file_exists($unifilename.
'.mtx.php')) {
503 include($unifilename.
'.mtx.php');
505 if (!isset(
$type) || !isset(
$name) || $originalsize != $ttfstat[
'size']) {
506 $ttffile = $ttffilename;
507 require_once(__DIR__.
'/ttfonts.php');
508 $ttf =
new TTFontFile();
509 $ttf->getMetrics($ttffile);
510 $cw = $ttf->charWidths;
511 $name = preg_replace(
'/[ ()]/',
'',$ttf->fullName);
514 'Descent'=>round($ttf->descent),
515 'CapHeight'=>round($ttf->capHeight),
516 'Flags'=>$ttf->flags,
517 'FontBBox'=>
'['.round($ttf->bbox[0]).
" ".round($ttf->bbox[1]).
" ".round($ttf->bbox[2]).
" ".round($ttf->bbox[3]).
']',
518 'ItalicAngle'=>$ttf->italicAngle,
519 'StemV'=>round($ttf->stemV),
520 'MissingWidth'=>round($ttf->defaultWidth));
521 $up = round($ttf->underlinePosition);
522 $ut = round($ttf->underlineThickness);
523 $originalsize = $ttfstat[
'size']+0;
527 $s.=
'$name=\''.$name.
"';\n";
528 $s.=
'$type=\''.$type.
"';\n";
529 $s.=
'$desc='.var_export(
$desc,
true).
";\n";
530 $s.=
'$up='.$up.
";\n";
531 $s.=
'$ut='.$ut.
";\n";
532 $s.=
'$ttffile=dirname(__FILE__).\'/'.$file.
"';\n";
533 $s.=
'$originalsize='.$originalsize.
";\n";
534 $s.=
'$fontkey=\''.$fontkey.
"';\n";
536 if (is_writable(dirname($this->_getfontpath().
'/'.
'x'))) {
537 $fh = fopen($unifilename.
'.mtx.php',
"w");
538 fwrite($fh,$s,mb_strlen($s,
'8bit'));
540 $fh = fopen($unifilename.
'.cw.dat',
"wb");
541 fwrite($fh,$cw,mb_strlen($cw,
'8bit'));
543 @unlink($unifilename.
'.cw127.php');
548 $cw = @file_get_contents($unifilename.
'.cw.dat');
551 if(!empty($this->AliasNbPages))
552 $sbarr = range(0,57);
554 $sbarr = range(0,32);
555 $this->fonts[$fontkey] =
array(
'i'=>
$i,
'type'=>
$type,
'name'=>
$name,
'desc'=>
$desc,
'up'=>$up,
'ut'=>$ut,
'cw'=>$cw,
'ttffile'=>$ttffile,
'fontkey'=>$fontkey,
'subset'=>$sbarr,
'unifilename'=>$unifilename);
557 $this->FontFiles[$fontkey]=
array(
'length1'=>$originalsize,
'type'=>
"TTF",
'ttffile'=>$ttffile);
558 $this->FontFiles[$file]=
array(
'type'=>
"TTF");
562 $info = $this->_loadfont($file);
564 if(!empty(
$info[
'diff']))
567 $n = array_search(
$info[
'diff'],$this->diffs);
571 $this->diffs[
$n] =
$info[
'diff'];
575 if(!empty(
$info[
'file']))
578 if(
$info[
'type']==
'TrueType')
579 $this->FontFiles[
$info[
'file']] =
array(
'length1'=>
$info[
'originalsize']);
583 $this->fonts[$fontkey] =
$info;
587function SetFont($family, $style=
'', $size=0)
591 $family = $this->FontFamily;
593 $family = mb_strtolower($family);
594 $style = mb_strtoupper($style);
595 if(mb_strpos($style,
'U',0,
'8bit')!==
false)
597 $this->underline =
true;
598 $style = str_replace(
'U',
'',$style);
601 $this->underline =
false;
605 $size = $this->FontSizePt;
607 if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size)
610 $fontkey = $family.$style;
611 if(!isset($this->fonts[$fontkey]))
615 $family =
'helvetica';
616 if(in_array($family,$this->CoreFonts))
618 if($family==
'symbol' || $family==
'zapfdingbats')
620 $fontkey = $family.$style;
621 if(!isset($this->fonts[$fontkey]))
622 $this->AddFont($family,$style);
625 $this->
Error(
'Undefined font: '.$family.
' '.$style);
628 $this->FontFamily = $family;
629 $this->FontStyle = $style;
630 $this->FontSizePt = $size;
632 $this->CurrentFont = &$this->fonts[$fontkey];
633 if ($this->fonts[$fontkey][
'type']==
'TTF') { $this->unifontSubset =
true; }
634 else { $this->unifontSubset =
false; }
636 $this->_out(sprintf(
'BT /F%d %.2F Tf ET',$this->CurrentFont[
'i'],$this->FontSizePt));
639function SetFontSize($size)
642 if($this->FontSizePt==$size)
644 $this->FontSizePt = $size;
647 $this->_out(sprintf(
'BT /F%d %.2F Tf ET',$this->CurrentFont[
'i'],$this->FontSizePt));
654 $this->links[
$n] =
array(0, 0);
658function SetLink($link, $y=0,
$page=-1)
668function Link($x, $y, $w, $h, $link)
671 $this->PageLinks[
$this->page][] =
array($x*$this->k, $this->hPt-$y*$this->k, $w*$this->k, $h*$this->k, $link);
674function Text($x, $y, $txt)
677 if ($this->unifontSubset)
679 $txt2 =
'('.$this->_escape($this->UTF8ToUTF16BE($txt,
false)).
')';
680 foreach($this->UTF8StringToArray($txt) as $uni)
681 $this->CurrentFont[
'subset'][$uni] = $uni;
684 $txt2 =
'('.$this->_escape($txt).
')';
685 $s = sprintf(
'BT %.2F %.2F Td %s Tj ET',$x*$this->k,($this->h-$y)*$this->k,$txt2);
686 if($this->underline && $txt!=
'')
687 $s .=
' '.$this->_dounderline($x,$y,$txt);
689 $s =
'q '.$this->TextColor.
' '.$s.
' Q';
693function AcceptPageBreak()
696 return $this->AutoPageBreak;
699function Cell($w, $h=0, $txt=
'', $border=0, $ln=0, $align=
'', $fill=
false, $link=
'')
703 if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
713 $this->AddPage($this->CurOrientation,$this->CurPageSize);
718 $this->_out(sprintf(
'%.3F Tw',$ws*
$k));
722 $w = $this->w-$this->rMargin-$this->x;
724 if($fill || $border==1)
727 $op = ($border==1) ?
'B' :
'f';
730 $s = sprintf(
'%.2F %.2F %.2F %.2F re %s ',$this->x*
$k,($this->h-$this->y)*
$k,$w*
$k,-$h*
$k,$op);
732 if(is_string($border))
736 if(mb_strpos($border,
'L',0,
'8bit')!==
false)
737 $s .= sprintf(
'%.2F %.2F m %.2F %.2F l S ',$x*
$k,($this->h-$y)*
$k,$x*
$k,($this->h-($y+$h))*
$k);
738 if(mb_strpos($border,
'T',0,
'8bit')!==
false)
739 $s .= sprintf(
'%.2F %.2F m %.2F %.2F l S ',$x*
$k,($this->h-$y)*
$k,($x+$w)*
$k,($this->h-$y)*
$k);
740 if(mb_strpos($border,
'R',0,
'8bit')!==
false)
741 $s .= sprintf(
'%.2F %.2F m %.2F %.2F l S ',($x+$w)*
$k,($this->h-$y)*
$k,($x+$w)*
$k,($this->h-($y+$h))*
$k);
742 if(mb_strpos($border,
'B',0,
'8bit')!==
false)
743 $s .= sprintf(
'%.2F %.2F m %.2F %.2F l S ',$x*
$k,($this->h-($y+$h))*
$k,($x+$w)*
$k,($this->h-($y+$h))*
$k);
748 $dx = $w-$this->cMargin-$this->GetStringWidth($txt);
750 $dx = ($w-$this->GetStringWidth($txt))/2;
752 $dx = $this->cMargin;
754 $s .= 'q '.$this->TextColor.
' ';
757 if ($this->ws && $this->unifontSubset) {
758 foreach($this->UTF8StringToArray($txt) as $uni)
759 $this->CurrentFont[
'subset'][$uni] = $uni;
760 $space = $this->_escape($this->UTF8ToUTF16BE(
' ',
false));
761 $s .= sprintf(
'BT 0 Tw %.2F %.2F Td [',($this->x+$dx)*
$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*
$k);
762 $t = explode(
' ',$txt);
766 $tx =
'('.$this->_escape($this->UTF8ToUTF16BE($tx,
false)).
')';
767 $s .= sprintf(
'%s ',$tx);
769 $adj = -($this->ws*
$this->k)*1000/$this->FontSizePt;
770 $s .= sprintf(
'%d(%s) ',$adj,$space);
777 if ($this->unifontSubset)
779 $txt2 =
'('.$this->_escape($this->UTF8ToUTF16BE($txt,
false)).
')';
780 foreach($this->UTF8StringToArray($txt) as $uni)
781 $this->CurrentFont[
'subset'][$uni] = $uni;
784 $txt2=
'('.str_replace(
')',
'\\)',str_replace(
'(',
'\\(',str_replace(
'\\',
'\\\\',$txt))).
')';
785 $s .= sprintf(
'BT %.2F %.2F Td %s Tj ET',($this->x+$dx)*
$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*
$k,$txt2);
788 $s .=
' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
792 $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
802 $this->x = $this->lMargin;
808function MultiCell($w, $h, $txt, $border=0, $align=
'J', $fill=
false)
811 $cw = &$this->CurrentFont[
'cw'];
813 $w = $this->w-$this->rMargin-$this->x;
814 $wmax = ($w-2*$this->cMargin);
815 $s = str_replace(
"\r",
'',$txt);
816 if ($this->unifontSubset) {
817 $nb=mb_strlen($s,
'utf-8');
818 while($nb>0 && mb_substr($s,$nb-1,1,
'utf-8')==
"\n") $nb--;
821 $nb = mb_strlen($s,
'8bit');
822 if($nb>0 && $s[$nb-1]==
"\n")
837 if(mb_strpos($border,
'L',0,
'8bit')!==
false)
839 if(mb_strpos($border,
'R',0,
'8bit')!==
false)
841 $b = (mb_strpos($border,
'T',0,
'8bit')!==
false) ? $b2.
'T' : $b2;
853 if ($this->unifontSubset) {
854 $c = mb_substr($s,
$i,1,
'UTF-8');
867 if ($this->unifontSubset) {
868 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'UTF-8'),$b,2,$align,$fill);
871 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'8bit'),$b,2,$align,$fill);
879 if($border && $nl==2)
890 if ($this->unifontSubset) {
$l += $this->GetStringWidth($c); }
891 else {
$l += $cw[$c]*$this->FontSize/1000; }
905 if ($this->unifontSubset) {
906 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'UTF-8'),$b,2,$align,$fill);
909 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'8bit'),$b,2,$align,$fill);
916 $this->ws = ($ns>1) ? ($wmax-$ls)/($ns-1) : 0;
917 $this->_out(sprintf(
'%.3F Tw',$this->ws*$this->k));
919 if ($this->unifontSubset) {
920 $this->Cell($w,$h,mb_substr($s,$j,$sep-$j,
'UTF-8'),$b,2,$align,$fill);
923 $this->Cell($w,$h,mb_substr($s,$j,$sep-$j,
'8bit'),$b,2,$align,$fill);
932 if($border && $nl==2)
944 if($border && mb_strpos($border,
'B',0,
'8bit')!==
false)
946 if ($this->unifontSubset) {
947 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'UTF-8'),$b,2,$align,$fill);
950 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'8bit'),$b,2,$align,$fill);
952 $this->x = $this->lMargin;
955function Write($h, $txt, $link=
'')
958 $cw = &$this->CurrentFont[
'cw'];
959 $w = $this->w-$this->rMargin-$this->x;
961 $wmax = ($w-2*$this->cMargin);
962 $s = str_replace(
"\r",
'',$txt);
963 if ($this->unifontSubset) {
964 $nb = mb_strlen($s,
'UTF-8');
965 if($nb==1 && $s==
" ") {
966 $this->x += $this->GetStringWidth($s);
971 $nb = mb_strlen($s,
'8bit');
981 if ($this->unifontSubset) {
982 $c = mb_substr($s,
$i,1,
'UTF-8');
990 if ($this->unifontSubset) {
991 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'UTF-8'),0,2,
'',0,$link);
994 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'8bit'),0,2,
'',0,$link);
1002 $this->x = $this->lMargin;
1003 $w = $this->w-$this->rMargin-$this->x;
1004 $wmax = ($w-2*$this->cMargin);
1012 if ($this->unifontSubset) {
$l += $this->GetStringWidth($c); }
1013 else {
$l += $cw[$c]*$this->FontSize/1000; }
1020 if($this->x>$this->lMargin)
1023 $this->x = $this->lMargin;
1025 $w = $this->w-$this->rMargin-$this->x;
1026 $wmax = ($w-2*$this->cMargin);
1033 if ($this->unifontSubset) {
1034 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'UTF-8'),0,2,
'',0,$link);
1037 $this->Cell($w,$h,mb_substr($s,$j,
$i-$j,
'8bit'),0,2,
'',0,$link);
1042 if ($this->unifontSubset) {
1043 $this->Cell($w,$h,mb_substr($s,$j,$sep-$j,
'UTF-8'),0,2,
'',0,$link);
1046 $this->Cell($w,$h,mb_substr($s,$j,$sep-$j,
'8bit'),0,2,
'',0,$link);
1055 $this->x = $this->lMargin;
1056 $w = $this->w-$this->rMargin-$this->x;
1057 $wmax = ($w-2*$this->cMargin);
1066 if ($this->unifontSubset) {
1067 $this->Cell(
$l,$h,mb_substr($s,$j,
$i-$j,
'UTF-8'),0,0,
'',0,$link);
1070 $this->Cell(
$l,$h,mb_substr($s,$j,mb_strlen($s,
'8bit'),
'8bit'),0,0,
'',0,$link);
1081 if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
1089 $this->_out(
'0 Tw');
1091 $this->AddPage($this->CurOrientation,$this->CurPageSize);
1096 $this->_out(sprintf(
'%.3F Tw',$ws*
$k));
1101 $this->x = $this->lMargin;
1105function Image($file, $x=
null, $y=
null, $w=0, $h=0,
$type=
'', $link=
'')
1108 if(!isset($this->images[$file]))
1113 $pos = mb_strrpos($file,
'.',0,
'8bit');
1115 $this->
Error(
'Image file has no extension and no type was specified: '.$file);
1116 $type = mb_substr($file,$pos+1,mb_strlen($file,
'8bit'),
'8bit');
1121 $mtd =
'_parse'.$type;
1122 if(!method_exists($this,$mtd))
1123 $this->
Error(
'Unsupported image type: '.
$type);
1124 $info = $this->$mtd($file);
1126 $this->images[$file] =
$info;
1129 $info = $this->images[$file];
1150 if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
1154 $this->AddPage($this->CurOrientation,$this->CurPageSize);
1163 $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']));
1165 $this->Link($x,$y,$w,$h,$link);
1180 $this->x = $this->w+$x;
1192 $this->x = $this->lMargin;
1196 $this->y = $this->h+$y;
1199function SetXY($x, $y)
1206function Output(
$name=
'',
$dest=
'', $utfName =
'')
1226 $this->_checkoutput();
1230 header(
'Content-Type: application/pdf');
1231 if (is_string($utfName) && !empty($utfName))
1234 header(
"Content-Disposition: attachment; filename=\"".
$name.
"\"; filename*=utf-8''".$utfName);
1238 header(
'Content-Disposition: inline; filename="'.
$name.
'"');
1240 header(
'Cache-Control: private, max-age=0, must-revalidate');
1241 header(
'Pragma: public');
1247 $this->_checkoutput();
1248 header(
'Content-Type: application/octet-stream');
1249 if (is_string($utfName) && !empty($utfName))
1252 header(
"Content-Disposition: attachment; filename=\"".
$name.
"\"; filename*=utf-8''".$utfName);
1256 header(
'Content-Disposition: inline; filename="'.
$name.
'"');
1258 header(
'Cache-Control: private, max-age=0, must-revalidate');
1259 header(
'Pragma: public');
1266 $this->
Error(
'Unable to create output file: '.
$name);
1274 $this->
Error(
'Incorrect output destination: '.
$dest);
1287 if(sprintf(
'%.1F',1.0)!=
'1.0')
1288 $this->
Error(
'This version of PHP is not supported');
1290 if(!function_exists(
'mb_strlen'))
1291 $this->
Error(
'mbstring extension is not available');
1300function _getfontpath()
1302 return $this->fontpath;
1305function _checkoutput()
1309 if(headers_sent($file,$line))
1310 $this->
Error(
"Some data has already been output, can't send PDF file (output started at $file:$line)");
1315 if(preg_match(
'/^(\xEF\xBB\xBF)?\s*$/',ob_get_contents()))
1321 $this->
Error(
"Some data has already been output, can't send PDF file");
1325function _getpagesize($size)
1327 if(is_string($size))
1329 $size = mb_strtolower($size);
1330 if(!isset($this->StdPageSizes[$size]))
1331 $this->
Error(
'Unknown page size: '.$size);
1332 $a = $this->StdPageSizes[$size];
1333 return array(
$a[0]/$this->k,
$a[1]/$this->k);
1337 if($size[0]>$size[1])
1338 return array($size[1], $size[0]);
1344function _beginpage($orientation, $size)
1349 $this->x = $this->lMargin;
1350 $this->y = $this->tMargin;
1351 $this->FontFamily =
'';
1353 if($orientation==
'')
1354 $orientation = $this->DefOrientation;
1356 $orientation = mb_strtoupper($orientation[0]);
1358 $size = $this->DefPageSize;
1360 $size = $this->_getpagesize($size);
1361 if($orientation!=$this->CurOrientation || $size[0]!=$this->CurPageSize[0] || $size[1]!=$this->CurPageSize[1])
1364 if($orientation==
'P')
1366 $this->w = $size[0];
1367 $this->h = $size[1];
1371 $this->w = $size[1];
1372 $this->h = $size[0];
1376 $this->PageBreakTrigger = $this->h-$this->bMargin;
1377 $this->CurOrientation = $orientation;
1378 $this->CurPageSize = $size;
1380 if($orientation!=$this->DefOrientation || $size[0]!=$this->DefPageSize[0] || $size[1]!=$this->DefPageSize[1])
1389function _loadfont($font)
1392 include($this->fontpath.$font);
1393 $a = get_defined_vars();
1394 if(!isset(
$a[
'name']))
1395 $this->
Error(
'Could not include font definition file');
1402 $s = str_replace(
'\\',
'\\\\',$s);
1403 $s = str_replace(
'(',
'\\(',$s);
1404 $s = str_replace(
')',
'\\)',$s);
1405 $s = str_replace(
"\r",
'\\r',$s);
1409function _textstring($s)
1412 return '('.$this->_escape($s).
')';
1415function _UTF8toUTF16($s)
1419 $nb = mb_strlen($s,
'8bit');
1423 $c1 = ord($s[
$i++]);
1427 $c2 = ord($s[
$i++]);
1428 $c3 = ord($s[
$i++]);
1429 $res .= chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2));
1430 $res .= chr((($c2 & 0x03)<<6) + ($c3 & 0x3F));
1435 $c2 = ord($s[
$i++]);
1436 $res .= chr(($c1 & 0x1C)>>2);
1437 $res .= chr((($c1 & 0x03)<<6) + ($c2 & 0x3F));
1442 $res .=
"\0".chr($c1);
1448function _dounderline($x, $y, $txt)
1451 $up = $this->CurrentFont[
'up'];
1452 $ut = $this->CurrentFont[
'ut'];
1453 $w = $this->GetStringWidth($txt)+$this->ws*mb_substr_count($txt,
' ',
'8bit');
1454 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);
1457function _parsejpg($file)
1460 $a = getimagesize($file);
1462 $this->
Error(
'Missing or incorrect image file: '.$file);
1464 $this->
Error(
'Not a JPEG file: '.$file);
1465 if(!isset(
$a[
'channels']) ||
$a[
'channels']==3)
1466 $colspace =
'DeviceRGB';
1468 $colspace = 'DeviceCMYK';
1470 $colspace = 'DeviceGray';
1471 $bpc = isset(
$a['bits']) ?
$a['bits'] : 8;
1472 $data = file_get_contents($file);
1473 return array(
'w'=>
$a[0],
'h'=>
$a[1], 'cs'=>$colspace, 'bpc'=>$bpc,
'f'=>'DCTDecode', 'data'=>
$data);
1476function _parsepng($file)
1479 $f = fopen($file,
'rb');
1481 $this->
Error(
'Can\'t open image file: '.$file);
1482 $info = $this->_parsepngstream(
$f,$file);
1487function _parsepngstream(
$f, $file)
1490 if($this->_readstream(
$f,8)!=chr(137).
'PNG'.chr(13).chr(10).chr(26).chr(10))
1491 $this->
Error(
'Not a PNG file: '.$file);
1494 $this->_readstream(
$f,4);
1495 if($this->_readstream(
$f,4)!=
'IHDR')
1496 $this->
Error(
'Incorrect PNG file: '.$file);
1497 $w = $this->_readint(
$f);
1498 $h = $this->_readint(
$f);
1499 $bpc = ord($this->_readstream(
$f,1));
1501 $this->
Error(
'16-bit depth not supported: '.$file);
1502 $ct = ord($this->_readstream(
$f,1));
1503 if($ct==0 || $ct==4)
1504 $colspace =
'DeviceGray';
1506 $colspace = 'DeviceRGB';
1508 $colspace = 'Indexed';
1510 $this->Error('Unknown
color type: '.$file);
1511 if(ord($this->_readstream(
$f,1))!=0)
1512 $this->Error('Unknown compression method: '.$file);
1513 if(ord($this->_readstream(
$f,1))!=0)
1514 $this->Error('Unknown filter method: '.$file);
1515 if(ord($this->_readstream(
$f,1))!=0)
1516 $this->Error('Interlacing not supported: '.$file);
1517 $this->_readstream(
$f,4);
1518 $dp = '/Predictor 15 /Colors '.($colspace=='DeviceRGB' ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w;
1526 $n = $this->_readint(
$f);
1527 $type = $this->_readstream(
$f,4);
1531 $pal = $this->_readstream(
$f,
$n);
1532 $this->_readstream(
$f,4);
1537 $t = $this->_readstream(
$f,
$n);
1539 $trns =
array(ord(mb_substr($t,1,1,
'8bit')));
1541 $trns =
array(ord(mb_substr($t,1,1,'8bit')), ord(mb_substr($t,3,1,'8bit')), ord(mb_substr($t,5,1,'8bit')));
1544 $pos = mb_strpos($t,chr(0),0,
'8bit');
1546 $trns =
array($pos);
1548 $this->_readstream(
$f,4);
1554 $this->_readstream(
$f,4);
1559 $this->_readstream(
$f,
$n+4);
1563 if($colspace=='Indexed' && empty($pal))
1564 $this->Error('Missing palette in '.$file);
1565 $info =
array(
'w'=>$w,
'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc,
'f'=>'FlateDecode', 'dp'=>$dp, 'pal'=>$pal, 'trns'=>$trns);
1569 if(!function_exists(
'gzuncompress'))
1570 $this->
Error(
'Zlib not available, can\'t handle alpha channel: '.$file);
1581 $color .=
$data[$pos];
1582 $alpha .=
$data[$pos];
1583 $line = mb_substr(
$data,$pos+1,$len,
'8bit');
1584 $color .= preg_replace(
'/(.)./s',
'$1',$line);
1585 $alpha .= preg_replace(
'/.(.)/s',
'$1',$line);
1595 $color .=
$data[$pos];
1596 $alpha .=
$data[$pos];
1597 $line = mb_substr(
$data,$pos+1,$len,
'8bit');
1598 $color .= preg_replace(
'/(.{3})./s',
'$1',$line);
1599 $alpha .= preg_replace(
'/.{3}(.)/s',
'$1',$line);
1603 $data = gzcompress($color);
1604 $info[
'smask'] = gzcompress($alpha);
1605 if($this->PDFVersion<
'1.4')
1606 $this->PDFVersion =
'1.4';
1612function _readstream(
$f,
$n)
1616 while(
$n>0 && !feof(
$f))
1620 $this->
Error(
'Error while reading stream');
1621 $n -= mb_strlen($s,
'8bit');
1625 $this->
Error(
'Unexpected end of stream');
1629function _readint(
$f)
1632 $a = unpack(
'Ni',$this->_readstream(
$f,4));
1636function _parsegif($file)
1639 if(!function_exists(
'imagepng'))
1640 $this->
Error(
'GD extension is required for GIF support');
1641 if(!function_exists(
'imagecreatefromgif'))
1642 $this->
Error(
'GD has no GIF read support');
1643 $im = imagecreatefromgif($file);
1645 $this->
Error(
'Missing or incorrect image file: '.$file);
1646 imageinterlace($im,0);
1647 $f = @fopen(
'php://temp',
'rb+');
1653 $data = ob_get_clean();
1657 $info = $this->_parsepngstream(
$f,$file);
1663 $tmp = tempnam(
'.',
'gif');
1665 $this->
Error(
'Unable to create a temporary file');
1666 if(!imagepng($im,
$tmp))
1667 $this->
Error(
'Error while saving to temporary file');
1680 $this->_out($this->n.
' 0 obj');
1683function _putstream($s)
1685 $this->_out(
'stream');
1687 $this->_out(
'endstream');
1696 $this->
buffer .= $s.
"\n";
1702 if(!empty($this->AliasNbPages))
1705 $alias = $this->UTF8ToUTF16BE($this->AliasNbPages,
false);
1706 $r = $this->UTF8ToUTF16BE(
"$nb",
false);
1708 $this->pages[
$n] = str_replace($alias,$r,$this->pages[
$n]);
1711 $this->pages[
$n] = str_replace($this->AliasNbPages,$nb,$this->pages[
$n]);
1713 if($this->DefOrientation==
'P')
1715 $wPt = $this->DefPageSize[0]*
$this->k;
1716 $hPt = $this->DefPageSize[1]*
$this->k;
1720 $wPt = $this->DefPageSize[1]*
$this->k;
1721 $hPt = $this->DefPageSize[0]*
$this->k;
1723 $filter = ($this->compress) ?
'/Filter /FlateDecode ' :
'';
1728 $this->_out(
'<</Type /Page');
1729 $this->_out(
'/Parent 1 0 R');
1730 if(isset($this->PageSizes[
$n]))
1731 $this->_out(sprintf(
'/MediaBox [0 0 %.2F %.2F]',$this->PageSizes[
$n][0],$this->PageSizes[
$n][1]));
1732 $this->_out(
'/Resources 2 0 R');
1733 if(isset($this->PageLinks[
$n]))
1736 $annots =
'/Annots [';
1737 foreach($this->PageLinks[
$n] as $pl)
1739 $rect = sprintf(
'%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
1740 $annots .=
'<</Type /Annot /Subtype /Link /Rect ['.$rect.
'] /Border [0 0 0] ';
1741 if(is_string($pl[4]))
1742 $annots .=
'/A <</S /URI /URI '.$this->_textstring($pl[4]).
'>>>>';
1745 $l = $this->links[$pl[4]];
1746 $h = isset($this->PageSizes[
$l[0]]) ? $this->PageSizes[
$l[0]][1] : $hPt;
1747 $annots .= sprintf(
'/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*
$l[0],$h-
$l[1]*$this->k);
1750 $this->_out($annots.
']');
1752 if($this->PDFVersion>
'1.3')
1753 $this->_out(
'/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>');
1754 $this->_out(
'/Contents '.($this->n+1).
' 0 R>>');
1755 $this->_out(
'endobj');
1757 $p = ($this->compress) ? gzcompress($this->pages[
$n]) : $this->pages[
$n];
1759 $this->_out(
'<<'.
$filter.
'/Length '.mb_strlen(
$p,
'8bit').
'>>');
1760 $this->_putstream(
$p);
1761 $this->_out(
'endobj');
1764 $this->offsets[1] = mb_strlen($this->
buffer,
'8bit');
1765 $this->_out(
'1 0 obj');
1766 $this->_out(
'<</Type /Pages');
1769 $kids .= (3+2*
$i).
' 0 R ';
1770 $this->_out($kids.
']');
1771 $this->_out(
'/Count '.$nb);
1772 $this->_out(sprintf(
'/MediaBox [0 0 %.2F %.2F]',$wPt,$hPt));
1774 $this->_out(
'endobj');
1780 foreach($this->diffs as $diff)
1784 $this->_out(
'<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.
']>>');
1785 $this->_out(
'endobj');
1787 foreach($this->FontFiles as $file=>
$info)
1789 if (!isset(
$info[
'type']) ||
$info[
'type']!=
'TTF') {
1792 $this->FontFiles[$file][
'n']=
$this->n;
1794 $f=fopen($this->_getfontpath().$file,
'rb',1);
1796 $this->
Error(
'Font file not found');
1798 $font.=fread(
$f,8192);
1800 $compressed=(mb_substr($file,-2,mb_strlen($file,
'8bit'),
'8bit')==
'.z');
1801 if(!$compressed && isset(
$info[
'length2']))
1803 $header=(ord($font[0])==128);
1807 $font=mb_substr($font,6,mb_strlen($font,
'8bit'),
'8bit');
1809 if($header && ord($font[
$info[
'length1']])==128)
1812 $font=mb_substr($font,0,
$info[
'length1'],
'8bit').mb_substr($font,
$info[
'length1']+6,mb_strlen($font,
'8bit'),
'8bit');
1815 $this->_out(
'<</Length '.mb_strlen($font,
'8bit'));
1817 $this->_out(
'/Filter /FlateDecode');
1818 $this->_out(
'/Length1 '.
$info[
'length1']);
1819 if(isset(
$info[
'length2']))
1820 $this->_out(
'/Length2 '.
$info[
'length2'].
' /Length3 0');
1822 $this->_putstream($font);
1823 $this->_out(
'endobj');
1826 foreach($this->fonts as
$k=>$font)
1830 $type = $font[
'type'];
1831 $name = $font[
'name'];
1835 $this->fonts[
$k][
'n']=$this->n+1;
1837 $this->_out(
'<</Type /Font');
1838 $this->_out(
'/BaseFont /'.
$name);
1839 $this->_out(
'/Subtype /Type1');
1841 $this->_out(
'/Encoding /WinAnsiEncoding');
1843 $this->_out(
'endobj');
1848 $this->fonts[
$k][
'n']=$this->n+1;
1850 $this->_out(
'<</Type /Font');
1851 $this->_out(
'/BaseFont /'.
$name);
1852 $this->_out(
'/Subtype /'.
$type);
1853 $this->_out(
'/FirstChar 32 /LastChar 255');
1854 $this->_out(
'/Widths '.($this->n+1).
' 0 R');
1855 $this->_out(
'/FontDescriptor '.($this->n+2).
' 0 R');
1858 if(isset($font[
'diff']))
1859 $this->_out(
'/Encoding '.($nf+$font[
'diff']).
' 0 R');
1861 $this->_out(
'/Encoding /WinAnsiEncoding');
1864 $this->_out(
'endobj');
1870 $s.=$cw[chr(
$i)].
' ';
1871 $this->_out($s.
']');
1872 $this->_out(
'endobj');
1875 $s=
'<</Type /FontDescriptor /FontName /'.$name;
1876 foreach($font[
'desc'] as
$k=>$v)
1878 $file=$font[
'file'];
1880 $s.=
' /FontFile'.($type==
'Type1' ?
'' :
'2').
' '.$this->FontFiles[$file][
'n'].
' 0 R';
1881 $this->_out($s.
'>>');
1882 $this->_out(
'endobj');
1885 else if (
$type==
'TTF') {
1886 $this->fonts[
$k][
'n']=$this->n+1;
1887 require_once(__DIR__.
'/ttfonts.php');
1888 $ttf =
new TTFontFile();
1889 $fontname =
'MPDFAA'.
'+'.$font[
'name'];
1890 $subset = $font[
'subset'];
1892 $ttfontstream = $ttf->makeSubset($font[
'ttffile'], $subset);
1893 $ttfontsize = mb_strlen($ttfontstream,
'8bit');
1894 $fontstream = gzcompress($ttfontstream);
1895 $codeToGlyph = $ttf->codeToGlyph;
1896 unset($codeToGlyph[0]);
1901 $this->_out(
'<</Type /Font');
1902 $this->_out(
'/Subtype /Type0');
1903 $this->_out(
'/BaseFont /'.$fontname.
'');
1904 $this->_out(
'/Encoding /Identity-H');
1905 $this->_out(
'/DescendantFonts ['.($this->n + 1).
' 0 R]');
1906 $this->_out(
'/ToUnicode '.($this->n + 2).
' 0 R');
1908 $this->_out(
'endobj');
1913 $this->_out(
'<</Type /Font');
1914 $this->_out(
'/Subtype /CIDFontType2');
1915 $this->_out(
'/BaseFont /'.$fontname.
'');
1916 $this->_out(
'/CIDSystemInfo '.($this->n + 2).
' 0 R');
1917 $this->_out(
'/FontDescriptor '.($this->n + 3).
' 0 R');
1918 if (isset($font[
'desc'][
'MissingWidth'])){
1919 $this->_out(
'/DW '.$font[
'desc'][
'MissingWidth'].
'');
1922 $this->_putTTfontwidths($font, $ttf->maxUni);
1924 $this->_out(
'/CIDToGIDMap '.($this->n + 4).
' 0 R');
1926 $this->_out(
'endobj');
1930 $toUni =
"/CIDInit /ProcSet findresource begin\n";
1931 $toUni .=
"12 dict begin\n";
1932 $toUni .=
"begincmap\n";
1933 $toUni .=
"/CIDSystemInfo\n";
1934 $toUni .=
"<</Registry (Adobe)\n";
1935 $toUni .=
"/Ordering (UCS)\n";
1936 $toUni .=
"/Supplement 0\n";
1937 $toUni .=
">> def\n";
1938 $toUni .=
"/CMapName /Adobe-Identity-UCS def\n";
1939 $toUni .=
"/CMapType 2 def\n";
1940 $toUni .=
"1 begincodespacerange\n";
1941 $toUni .=
"<0000> <FFFF>\n";
1942 $toUni .=
"endcodespacerange\n";
1943 $toUni .=
"1 beginbfrange\n";
1944 $toUni .=
"<0000> <FFFF> <0000>\n";
1945 $toUni .=
"endbfrange\n";
1946 $toUni .=
"endcmap\n";
1947 $toUni .=
"CMapName currentdict /CMap defineresource pop\n";
1950 $this->_out(
'<</Length '.(mb_strlen($toUni,
'8bit')).
'>>');
1951 $this->_putstream($toUni);
1952 $this->_out(
'endobj');
1956 $this->_out(
'<</Registry (Adobe)');
1957 $this->_out(
'/Ordering (UCS)');
1958 $this->_out(
'/Supplement 0');
1960 $this->_out(
'endobj');
1964 $this->_out(
'<</Type /FontDescriptor');
1965 $this->_out(
'/FontName /'.$fontname);
1966 foreach($font[
'desc'] as $kd=>$v) {
1967 if ($kd ==
'Flags') { $v = $v | 4; $v = $v & ~32; }
1968 $this->_out(
' /'.$kd.
' '.$v);
1970 $this->_out(
'/FontFile2 '.($this->n + 2).
' 0 R');
1972 $this->_out(
'endobj');
1977 $cidtogidmap = str_pad(
'', 256*256*2,
"\x00");
1978 foreach($codeToGlyph as $cc=>$glyph) {
1979 $cidtogidmap[$cc*2] = chr($glyph >> 8);
1980 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
1982 $cidtogidmap = gzcompress($cidtogidmap);
1984 $this->_out(
'<</Length '.mb_strlen($cidtogidmap,
'8bit').
'');
1985 $this->_out(
'/Filter /FlateDecode');
1987 $this->_putstream($cidtogidmap);
1988 $this->_out(
'endobj');
1992 $this->_out(
'<</Length '.mb_strlen($fontstream,
'8bit'));
1993 $this->_out(
'/Filter /FlateDecode');
1994 $this->_out(
'/Length1 '.$ttfontsize);
1996 $this->_putstream($fontstream);
1997 $this->_out(
'endobj');
2003 $this->fonts[
$k][
'n'] = $this->n+1;
2004 $mtd=
'_put'.mb_strtolower(
$type);
2005 if(!method_exists($this,$mtd))
2006 $this->
Error(
'Unsupported font type: '.
$type);
2012function _putTTfontwidths(&$font, $maxUni) {
2013 if (file_exists($font[
'unifilename'].
'.cw127.php')) {
2014 include($font[
'unifilename'].
'.cw127.php') ;
2025 $cwlen = $maxUni + 1;
2028 for ($cid=$startcid; $cid<$cwlen; $cid++) {
2029 if ($cid==128 && (!file_exists($font[
'unifilename'].
'.cw127.php'))) {
2030 if (is_writable(dirname($this->_getfontpath().
'/x'))) {
2031 $fh = fopen($font[
'unifilename'].
'.cw127.php',
"wb");
2032 $cw127=
'<?php'.
"\n";
2033 $cw127.=
'$rangeid='.$rangeid.
";\n";
2034 $cw127.=
'$prevcid='.$prevcid.
";\n";
2035 $cw127.=
'$prevwidth='.$prevwidth.
";\n";
2036 if ($interval) { $cw127.=
'$interval=true'.
";\n"; }
2037 else { $cw127.=
'$interval=false'.
";\n"; }
2038 $cw127.=
'$range='.var_export($range,
true).
";\n";
2040 fwrite($fh,$cw127,mb_strlen($cw127,
'8bit'));
2044 if ($font[
'cw'][$cid*2] ==
"\00" && $font[
'cw'][$cid*2+1] ==
"\00") {
continue; }
2045 $width = (ord($font[
'cw'][$cid*2]) << 8) + ord($font[
'cw'][$cid*2+1]);
2047 if ($cid > 255 && (!isset($font[
'subset'][$cid]) || !$font[
'subset'][$cid])) {
continue; }
2048 if (!isset($font[
'dw']) || (isset($font[
'dw']) &&
$width != $font[
'dw'])) {
2049 if ($cid == ($prevcid + 1)) {
2050 if (
$width == $prevwidth) {
2051 if (
$width == $range[$rangeid][0]) {
2052 $range[$rangeid][] =
$width;
2055 array_pop($range[$rangeid]);
2057 $rangeid = $prevcid;
2058 $range[$rangeid] =
array();
2059 $range[$rangeid][] = $prevwidth;
2060 $range[$rangeid][] =
$width;
2063 $range[$rangeid][
'interval'] =
true;
2068 $range[$rangeid] =
array();
2069 $range[$rangeid][] =
$width;
2071 else { $range[$rangeid][] =
$width; }
2076 $range[$rangeid] =
array();
2077 $range[$rangeid][] =
$width;
2087 foreach ($range as
$k => $ws) {
2089 if ((
$k == $nextk) AND (!$prevint) AND ((!isset($ws[
'interval'])) OR ($cws < 4))) {
2090 if (isset($range[
$k][
'interval'])) { unset($range[
$k][
'interval']); }
2091 $range[$prevk] = array_merge($range[$prevk], $range[
$k]);
2094 else { $prevk =
$k; }
2096 if (isset($ws[
'interval'])) {
2097 if ($cws > 3) { $prevint =
true; }
2098 else { $prevint =
false; }
2099 unset($range[
$k][
'interval']);
2102 else { $prevint =
false; }
2105 foreach ($range as
$k => $ws) {
2106 if (
count(array_count_values($ws)) == 1) { $w .=
' '.$k.
' '.(
$k +
count($ws) - 1).
' '.$ws[0]; }
2107 else { $w .=
' '.$k.
' [ '.implode(
' ', $ws).
' ]' .
"\n"; }
2109 $this->_out(
'/W ['.$w.
' ]');
2112function _putimages()
2114 foreach(array_keys($this->images) as $file)
2116 $this->_putimage($this->images[$file]);
2117 unset($this->images[$file][
'data']);
2118 unset($this->images[$file][
'smask']);
2122function _putimage(&
$info)
2126 $this->_out(
'<</Type /XObject');
2127 $this->_out(
'/Subtype /Image');
2128 $this->_out(
'/Width '.
$info[
'w']);
2129 $this->_out(
'/Height '.
$info[
'h']);
2130 if(
$info[
'cs']==
'Indexed')
2131 $this->_out(
'/ColorSpace [/Indexed /DeviceRGB '.(mb_strlen(
$info[
'pal'],
'8bit')/3-1).
' '.($this->n+1).
' 0 R]');
2134 $this->_out(
'/ColorSpace /'.
$info[
'cs']);
2135 if(
$info[
'cs']==
'DeviceCMYK')
2136 $this->_out(
'/Decode [1 0 1 0 1 0 1 0]');
2138 $this->_out(
'/BitsPerComponent '.
$info[
'bpc']);
2139 if(isset(
$info[
'f']))
2140 $this->_out(
'/Filter /'.
$info[
'f']);
2141 if(isset(
$info[
'dp']))
2142 $this->_out(
'/DecodeParms <<'.
$info[
'dp'].
'>>');
2143 if(isset(
$info[
'trns']) && is_array(
$info[
'trns']))
2148 $this->_out(
'/Mask ['.$trns.
']');
2150 if(isset(
$info[
'smask']))
2151 $this->_out(
'/SMask '.($this->n+1).
' 0 R');
2152 $this->_out(
'/Length '.mb_strlen(
$info[
'data'],
'8bit').
'>>');
2153 $this->_putstream(
$info[
'data']);
2154 $this->_out(
'endobj');
2156 if(isset(
$info[
'smask']))
2158 $dp =
'/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns '.$info[
'w'];
2159 $smask =
array(
'w'=>
$info[
'w'],
'h'=>
$info[
'h'],
'cs'=>
'DeviceGray',
'bpc'=>8,
'f'=>
$info[
'f'],
'dp'=>$dp,
'data'=>
$info[
'smask']);
2160 $this->_putimage($smask);
2163 if(
$info[
'cs']==
'Indexed')
2165 $filter = ($this->compress) ?
'/Filter /FlateDecode ' :
'';
2166 $pal = ($this->compress) ? gzcompress(
$info[
'pal']) :
$info[
'pal'];
2168 $this->_out(
'<<'.
$filter.
'/Length '.mb_strlen($pal,
'8bit').
'>>');
2169 $this->_putstream($pal);
2170 $this->_out(
'endobj');
2174function _putxobjectdict()
2176 foreach($this->images as $image)
2177 $this->_out(
'/I'.$image[
'i'].
' '.$image[
'n'].
' 0 R');
2180function _putresourcedict()
2182 $this->_out(
'/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
2183 $this->_out(
'/Font <<');
2184 foreach($this->fonts as $font) {
2185 $this->_out(
'/F'.$font[
'i'].
' '.$font[
'n'].
' 0 R');
2188 $this->_out(
'/XObject <<');
2189 $this->_putxobjectdict();
2193function _putresources()
2196 $this->_putimages();
2198 $this->offsets[2] = mb_strlen($this->
buffer,
'8bit');
2199 $this->_out(
'2 0 obj');
2201 $this->_putresourcedict();
2203 $this->_out(
'endobj');
2208 $this->_out(
'/Producer '.$this->_textstring(
'tFPDF '.
tFPDF_VERSION));
2209 if(!empty($this->
title))
2210 $this->_out(
'/Title '.$this->_textstring($this->
title));
2211 if(!empty($this->subject))
2212 $this->_out(
'/Subject '.$this->_textstring($this->subject));
2213 if(!empty($this->author))
2214 $this->_out(
'/Author '.$this->_textstring($this->author));
2215 if(!empty($this->keywords))
2216 $this->_out(
'/Keywords '.$this->_textstring($this->keywords));
2217 if(!empty($this->creator))
2218 $this->_out(
'/Creator '.$this->_textstring($this->creator));
2219 $this->_out(
'/CreationDate '.$this->_textstring(
'D:'.@date(
'YmdHis')));
2222function _putcatalog()
2224 $this->_out(
'/Type /Catalog');
2225 $this->_out(
'/Pages 1 0 R');
2226 if($this->ZoomMode==
'fullpage')
2227 $this->_out(
'/OpenAction [3 0 R /Fit]');
2228 elseif($this->ZoomMode==
'fullwidth')
2229 $this->_out('/OpenAction [3 0 R /FitH null]');
2230 elseif($this->ZoomMode=='real')
2231 $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
2232 elseif(!is_string($this->ZoomMode))
2233 $this->_out('/OpenAction [3 0 R /XYZ null null '.sprintf('%.2F',$this->ZoomMode/100).
']');
2234 if($this->LayoutMode=='single')
2235 $this->_out('/PageLayout /SinglePage');
2236 elseif($this->LayoutMode=='continuous')
2237 $this->_out('/PageLayout /OneColumn');
2238 elseif($this->LayoutMode=='two')
2239 $this->_out('/PageLayout /TwoColumnLeft');
2242function _putheader()
2244 $this->_out(
'%PDF-'.$this->PDFVersion);
2247function _puttrailer()
2249 $this->_out(
'/Size '.($this->n+1));
2250 $this->_out(
'/Root '.$this->n.
' 0 R');
2251 $this->_out(
'/Info '.($this->n-1).
' 0 R');
2256 $this->_putheader();
2258 $this->_putresources();
2264 $this->_out(
'endobj');
2268 $this->_putcatalog();
2270 $this->_out(
'endobj');
2272 $o = mb_strlen($this->
buffer,
'8bit');
2273 $this->_out(
'xref');
2274 $this->_out(
'0 '.($this->n+1));
2275 $this->_out(
'0000000000 65535 f ');
2277 $this->_out(sprintf(
'%010d 00000 n ',$this->offsets[
$i]));
2279 $this->_out(
'trailer');
2281 $this->_puttrailer();
2283 $this->_out(
'startxref');
2285 $this->_out(
'%%EOF');
2291function UTF8ToUTF16BE(
$str, $setbom=
true) {
2294 $outstr .=
"\xFE\xFF";
2296 $outstr .= mb_convert_encoding(
$str,
'UTF-16BE',
'UTF-8');
2301function UTF8StringToArray(
$str) {
2303 $len = mb_strlen(
$str,
'8bit');
2304 for (
$i = 0;
$i < $len;
$i++) {
2310 if ( ($h <= 0xDF) && (
$i < $len -1) )
2311 $uni = ($h & 0x1F) << 6 | (ord(
$str[++
$i]) & 0x3F);
2312 elseif ( ($h <= 0xEF) && (
$i < $len -2) )
2313 $uni = ($h & 0x0F) << 12 | (ord(
$str[++
$i]) & 0x3F) << 6
2314 | (ord(
$str[++
$i]) & 0x3F);
2315 elseif ( ($h <= 0xF4) && (
$i < $len -3) )
2316 $uni = ($h & 0x0F) << 18 | (ord(
$str[++
$i]) & 0x3F) << 12
2317 | (ord(
$str[++
$i]) & 0x3F) << 6
2318 | (ord(
$str[++
$i]) & 0x3F);
2332if(isset(
$_SERVER[
'HTTP_USER_AGENT']) &&
$_SERVER[
'HTTP_USER_AGENT']==
'contype')
2334 header(
'Content-Type: application/pdf');
return[Dependency::CONTAINER=> Container::class, Dependency::IBLOCK_INFO=> IblockInfo::class, Dependency::PRODUCT_CONVERTER=> ProductConverter::class, Dependency::REPOSITORY_FACADE=> Repository::class, Dependency::PRODUCT_FACTORY=> ProductFactory::class, Dependency::PRODUCT_REPOSITORY=> ProductRepository::class, ProductFactory::PRODUCT=> Product::class, Dependency::SECTION_FACTORY=> SectionFactory::class, Dependency::SECTION_REPOSITORY=> SectionRepository::class, SectionFactory::SECTION=> Section::class, SectionFactory::SECTION_COLLECTION=> SectionCollection::class, Dependency::SKU_FACTORY=> SkuFactory::class, Dependency::SKU_REPOSITORY=> SkuRepository::class, SkuFactory::SIMPLE_SKU=> SimpleSku::class, SkuFactory::SKU=> Sku::class, SkuFactory::SKU_COLLECTION=> SkuCollection::class, Dependency::PROPERTY_FACTORY=> PropertyFactory::class, Dependency::PROPERTY_REPOSITORY=> PropertyRepository::class, PropertyFactory::PROPERTY=> Property::class, PropertyFactory::PROPERTY_COLLECTION=> PropertyCollection::class, Dependency::PROPERTY_VALUE_FACTORY=> PropertyValueFactory::class, PropertyValueFactory::PROPERTY_VALUE=> PropertyValue::class, PropertyValueFactory::PROPERTY_VALUE_COLLECTION=> PropertyValueCollection::class, Dependency::PROPERTY_FEATURE_FACTORY=> PropertyFeatureFactory::class, Dependency::PROPERTY_FEATURE_REPOSITORY=> PropertyFeatureRepository::class, PropertyFeatureFactory::PROPERTY_FEATURE=> PropertyFeature::class, PropertyFeatureFactory::PROPERTY_FEATURE_COLLECTION=> PropertyFeatureCollection::class, Dependency::PRICE_FACTORY=> PriceFactory::class, Dependency::PRICE_REPOSITORY=> PriceRepository::class, PriceFactory::SIMPLE_PRICE=> SimplePrice::class, PriceFactory::QUANTITY_DEPENDENT_PRICE=> QuantityDependentPrice::class, PriceFactory::PRICE_COLLECTION=> PriceCollection::class, Dependency::IMAGE_FACTORY=> ImageFactory::class, Dependency::IMAGE_REPOSITORY=> ImageRepository::class, ImageFactory::DETAIL_IMAGE=> DetailImage::class, ImageFactory::PREVIEW_IMAGE=> PreviewImage::class, ImageFactory::MORE_PHOTO_IMAGE=> MorePhotoImage::class, ImageFactory::IMAGE_COLLECTION=> ImageCollection::class, Dependency::MEASURE_RATIO_FACTORY=> MeasureRatioFactory::class, Dependency::MEASURE_RATIO_REPOSITORY=> MeasureRatioRepository::class, MeasureRatioFactory::SIMPLE_MEASURE_RATIO=> SimpleMeasureRatio::class, MeasureRatioFactory::MEASURE_RATIO_COLLECTION=> MeasureRatioCollection::class, Dependency::BARCODE_FACTORY=> BarcodeFactory::class, Dependency::BARCODE_REPOSITORY=> BarcodeRepository::class, BarcodeFactory::BARCODE=> Barcode::class, BarcodeFactory::BARCODE_COLLECTION=> BarcodeCollection::class, Dependency::STORE_PRODUCT_FACTORY=> StoreProductFactory::class, Dependency::STORE_PRODUCT_REPOSITORY=> StoreProductRepository::class, StoreProductFactory::STORE_PRODUCT=> StoreProduct::class, StoreProductFactory::STORE_PRODUCT_COLLECTION=> StoreProductCollection::class, 'sku.tree'=> SkuTree::class, 'integration.seo.facebook.facade'=> FacebookFacade::class, 'integration.seo.facebook.product.processor'=> FacebookProductProcessor::class, 'integration.seo.facebook.product.repository'=> FacebookProductRepository::class,]
static urnEncode($str, $charset=false)
while( $arBasket=$dbBasket->Fetch())
if(!is_array($prop["VALUES"])) $tmp
if(!defined("ADMIN_AJAX_MODE") &&(($_REQUEST["mode"] ?? '') !='excel')) $buffer
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
$_SERVER["DOCUMENT_ROOT"]
if(preg_match('/^ else[a-z0-9_]{2}$/i', $siteID)===1)
if( $adminSidePanelHelper->isSidePanel())
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
if(mb_strlen($order)< 6) $desc
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
<? endif;?> window document title
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if(CSalePaySystemAction::GetParamValue('BACKGROUND', false)) $margin
if(!empty($sellerData)) $dest