4 $r = sprintf($fmt, $value);
5 return str_replace(
',',
'.', $r);
216 function Cpdf($pageSize = array(0, 0, 612, 792))
218 self::__construct($pageSize);
254 $o = &$this->objects[
$id];
260 $this->objects[
$id] = array
262 't' =>
'destination',
269 switch ($options[
'type'])
272 case 'FitR': $tmp =
' ' . $options[
'p3'] . $tmp;
277 case 'FitBV': $tmp =
' ' . $options[
'p1'] .
' ' . $options[
'p2'] . $tmp;
281 $tmp = $options[
'type'] . $tmp;
283 $this->objects[
$id][
'info'][
'string'] = $tmp;
284 $this->objects[
$id][
'info'][
'page'] = $options[
'page'];
292 $res =
"\n" .
$id .
" 0 obj\n" .
'[' . $tmp[
'page'] .
' 0 R /' . $tmp[
'string'] .
"]\nendobj\n";
305 $o = &$this->objects[
$id];
311 $this->objects[
$id] = array
313 't' =>
'viewerPreferences',
321 foreach ($options as $k => $v)
330 case 'NonFullScreenPageMode':
341 $res =
"\n" .
$id .
" 0 obj\n" .
'<< ';
343 foreach ($o[
'info'] as $k => $v)
345 $res .=
"\n/" . $k .
' ' . $v;
361 $o = &$this->objects[
$id];
367 $this->objects[
$id] = array
374 $this->catalogId =
$id;
380 $o[
'info'][
$action] = $options;
384 case 'viewerPreferences':
385 if (!isset($o[
'info'][
'viewerPreferences']))
389 $o[
'info'][
'viewerPreferences'] = $this->numObj;
392 $vp = $o[
'info'][
'viewerPreferences'];
397 $res =
"\n" .
$id .
" 0 obj\n" .
'<< /Type /Catalog';
399 foreach ($o[
'info'] as $k => $v)
404 $res .=
"\n" .
'/Outlines ' . $v .
' 0 R';
409 $res .=
"\n" .
'/Pages ' . $v .
' 0 R';
413 case 'viewerPreferences':
414 $res .=
"\n" .
'/ViewerPreferences ' . $o[
'info'][
'viewerPreferences'] .
' 0 R';
419 $res .=
"\n" .
'/OpenAction ' . $o[
'info'][
'openHere'] .
' 0 R';
425 $res .=
" >>\nendobj";
438 $o = &$this->objects[
$id];
444 $this->objects[
$id] = array
455 if (!is_array($options))
458 $o[
'info'][
'pages'][] = $options;
464 if (isset($options[
'id']) && isset($options[
'rid']) && isset($options[
'pos']))
466 $i = array_search($options[
'rid'], $o[
'info'][
'pages']);
468 if (isset($o[
'info'][
'pages'][$i]) && $o[
'info'][
'pages'][$i] == $options[
'rid'])
472 switch ($options[
'pos'])
492 for ($j = count($o[
'info'][
'pages']) - 1; $j >= $k; $j--)
494 $o[
'info'][
'pages'][$j + 1] = $o[
'info'][
'pages'][$j];
497 $o[
'info'][
'pages'][$k] = $options[
'id'];
506 $o[
'info'][
'procset'] = $options;
511 $o[
'info'][
'mediaBox'] = $options;
516 $o[
'info'][
'fonts'][] = array
518 'objNum' => $options[
'objNum'],
519 'fontNum' => $options[
'fontNum']
525 $o[
'info'][
'xObjects'][] = array
527 'objNum' => $options[
'objNum'],
528 'label' => $options[
'label']
534 if (count($o[
'info'][
'pages']))
536 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Pages\n/Kids [";
538 foreach ($o[
'info'][
'pages'] as $k => $v)
540 $res .= $v .
" 0 R\n";
543 $res .=
"]\n/Count " . count($this->objects[
$id][
'info'][
'pages']);
545 if ((isset($o[
'info'][
'fonts']) && count($o[
'info'][
'fonts'])) || isset($o[
'info'][
'procset']))
547 $res .=
"\n/Resources <<";
549 if (isset($o[
'info'][
'procset']))
551 $res .=
"\n/ProcSet " . $o[
'info'][
'procset'] .
" 0 R";
554 if (isset($o[
'info'][
'fonts']) && count($o[
'info'][
'fonts']))
556 $res .=
"\n/Font << ";
558 foreach ($o[
'info'][
'fonts'] as $finfo)
560 $res .=
"\n/F" . $finfo[
'fontNum'] .
" " . $finfo[
'objNum'] .
" 0 R";
566 if (isset($o[
'info'][
'xObjects']) && count($o[
'info'][
'xObjects']))
568 $res .=
"\n/XObject << ";
570 foreach ($o[
'info'][
'xObjects'] as $finfo)
572 $res .=
"\n/" . $finfo[
'label'] .
" " . $finfo[
'objNum'] .
" 0 R";
580 if (isset($o[
'info'][
'mediaBox']))
582 $tmp = $o[
'info'][
'mediaBox'];
583 $res .=
"\n/MediaBox [" .
__sprintf(
'%.3f',
590 $res .=
"\n >>\nendobj";
594 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Pages\n/Count 0\n>>\nendobj";
609 $o = &$this->objects[
$id];
615 $this->objects[
$id] = array
618 'info' => array(
'outlines' => array(
626 $o[
'info'][
'outlines'][] = $options;
631 if (count($o[
'info'][
'outlines']))
633 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Outlines /Kids [";
635 foreach ($o[
'info'][
'outlines'] as $k => $v)
637 $res .= $v .
" 0 R ";
640 $res .=
"] /Count " . count($o[
'info'][
'outlines']) .
" >>\nendobj";
644 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Outlines /Count 0 >>\nendobj";
659 $o = &$this->objects[
$id];
665 $this->objects[
$id] = array
668 'info' => array(
'name' => $options[
'name'],
'SubType' =>
'Type1')
671 $fontNum = $this->numFonts;
672 $this->objects[
$id][
'info'][
'fontNum'] = $fontNum;
675 if (isset($options[
'differences']))
680 $this->objects[
$id][
'info'][
'encodingDictionary'] = $this->numObj;
682 else if (isset($options[
'encoding']))
685 switch ($options[
'encoding'])
687 case 'WinAnsiEncoding':
688 case 'MacRomanEncoding':
689 case 'MacExpertEncoding':
690 $this->objects[
$id][
'info'][
'encoding'] = $options[
'encoding'];
697 $this->objects[
$id][
'info'][
'encoding'] =
'WinAnsiEncoding';
704 $this->objects[
$id][
'info'][
'encoding'] =
'WinAnsiEncoding';
708 $this->
o_pages($this->currentNode,
'font', array(
'fontNum' => $fontNum,
'objNum' =>
$id));
712 foreach ($options as $k => $v)
717 $o[
'info'][
'name'] = $v;
724 case 'FontDescriptor':
726 $this->
addMessage(
'o_font ' . $k .
" : " . $v);
736 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Font\n/Subtype /" . $o[
'info'][
'SubType'] .
"\n";
738 $res .=
"/Name /F" . $o[
'info'][
'fontNum'] .
"\n";
739 $res .=
"/BaseFont /" . $o[
'info'][
'name'] .
"\n";
741 if (isset($o[
'info'][
'encodingDictionary']))
744 $res .=
"/Encoding " . $o[
'info'][
'encodingDictionary'] .
" 0 R\n";
746 else if (isset($o[
'info'][
'encoding']))
749 $res .=
"/Encoding /" . $o[
'info'][
'encoding'] .
"\n";
752 if (isset($o[
'info'][
'FirstChar']))
754 $res .=
"/FirstChar " . $o[
'info'][
'FirstChar'] .
"\n";
757 if (isset($o[
'info'][
'LastChar']))
759 $res .=
"/LastChar " . $o[
'info'][
'LastChar'] .
"\n";
762 if (isset($o[
'info'][
'Widths']))
764 $res .=
"/Widths " . $o[
'info'][
'Widths'] .
" 0 R\n";
767 if (isset($o[
'info'][
'FontDescriptor']))
769 $res .=
"/FontDescriptor " . $o[
'info'][
'FontDescriptor'] .
" 0 R\n";
772 $res .=
">>\nendobj";
785 $o = &$this->objects[
$id];
791 $this->objects[
$id] = array
793 't' =>
'fontDescriptor',
800 $res =
"\n" .
$id .
" 0 obj\n<< /Type /FontDescriptor\n";
802 foreach ($o[
'info'] as $label => $value)
821 $res .=
'/' . $label .
' ' . $value .
"\n";
829 $res .=
'/' . $label .
' ' . $value .
" 0 R\n";
835 .=
'/' . $label .
' [' . $value[0] .
' ' . $value[1] .
' ' . $value[2] .
' ' . $value[3]
841 $res .=
'/' . $label .
' /' . $value .
"\n";
847 $res .=
">>\nendobj";
860 $o = &$this->objects[
$id];
867 $this->objects[
$id] = array
869 't' =>
'fontEncoding',
876 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Encoding\n";
878 if (!isset($o[
'info'][
'encoding']))
880 $o[
'info'][
'encoding'] =
'WinAnsiEncoding';
883 if ($o[
'info'][
'encoding'] !=
'none')
885 $res .=
"/BaseEncoding /" . $o[
'info'][
'encoding'] .
"\n";
888 $res .=
"/Differences \n[";
891 foreach ($o[
'info'][
'differences'] as $num => $label)
893 if ($num != $onum + 1)
896 $res .=
"\n" . $num .
" /" . $label;
900 $res .=
" /" . $label;
906 $res .=
"\n]\n>>\nendobj";
919 $o = &$this->objects[
$id];
925 $this->objects[
$id] = array
928 'info' => array(
'PDF' => 1,
'Text' => 1)
931 $this->
o_pages($this->currentNode,
'procset',
$id);
932 $this->procsetObjectId =
$id;
943 $o[
'info'][$options] = 1;
951 $res =
"\n" .
$id .
" 0 obj\n[";
953 foreach ($o[
'info'] as $label => $val)
955 $res .=
'/' . $label .
' ';
971 $o = &$this->objects[
$id];
977 $this->infoObject =
$id;
979 $date =
'D:' . date(
'Ymd');
980 $this->objects[
$id] = array
984 array(
'Creator' =>
'R and OS php pdf writer, http://www.ros.co.nz',
'CreationDate' => $date)
998 $o[
'info'][
$action] = $options;
1003 if ($this->encrypted)
1008 $res =
"\n" .
$id .
" 0 obj\n<<\n";
1010 foreach ($o[
'info'] as $k => $v)
1012 $res .=
'/' . $k .
' (';
1014 if ($this->encrypted)
1026 $res .=
">>\nendobj";
1039 $o = &$this->objects[
$id];
1045 if (is_array($options))
1047 $this->objects[
$id] = array
1051 'type' => $options[
'type']
1057 $this->objects[
$id] = array
1068 if ($this->encrypted)
1073 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Action";
1079 $res .=
"\n/S /GoTo\n/D " . $this->destinations[(string)$o[
'info'][
'label']] .
" 0 R";
1084 $res .=
"\n/S /URI\n/URI (";
1086 if ($this->encrypted)
1099 $res .=
"\n>>\nendobj";
1113 $o = &$this->objects[
$id];
1120 $pageId = $this->currentPage;
1125 switch ($options[
'type'])
1128 $this->objects[
$id] = array
1130 't' =>
'annotation',
1135 $this->
o_action($this->numObj,
'new', $options[
'url']);
1136 $this->objects[
$id][
'info'][
'actionId'] = $this->numObj;
1141 $label = $options[
'label'];
1143 $this->objects[
$id] = array
1145 't' =>
'annotation',
1150 $this->
o_action($this->numObj,
'new', array(
'type' =>
'ilink',
'label' => $label));
1151 $this->objects[
$id][
'info'][
'actionId'] = $this->numObj;
1158 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Annot";
1160 switch ($o[
'info'][
'type'])
1164 $res .=
"\n/Subtype /Link";
1169 $res .=
"\n/A " . $o[
'info'][
'actionId'] .
" 0 R";
1170 $res .=
"\n/Border [0 0 0]";
1172 $res .=
"\n/Rect [ ";
1174 foreach ($o[
'info'][
'rect'] as $v)
1180 $res .=
"\n>>\nendobj";
1193 $o = &$this->objects[
$id];
1201 $this->objects[
$id] = array
1204 'info' => array(
'parent' => $this->currentNode,
'pageNum' => $this->numPages)
1207 if (is_array($options))
1210 $options[
'id'] =
$id;
1211 $this->
o_pages($this->currentNode,
'page', $options);
1215 $this->
o_pages($this->currentNode,
'page',
$id);
1218 $this->currentPage =
$id;
1222 $this->currentContents = $this->numObj;
1223 $this->objects[
$id][
'info'][
'contents'] = array(
1226 $this->objects[
$id][
'info'][
'contents'][] = $this->numObj;
1227 $match = ($this->numPages % 2 ?
'odd' :
'even');
1229 foreach ($this->addLooseObjects as $oId => $target)
1231 if ($target ==
'all' || $match == $target)
1233 $this->objects[
$id][
'info'][
'contents'][] = $oId;
1240 $o[
'info'][
'contents'][] = $options;
1246 if (!isset($o[
'info'][
'annot']))
1248 $o[
'info'][
'annot'] = array(
1253 $o[
'info'][
'annot'][] = $options;
1257 $res =
"\n" .
$id .
" 0 obj\n<< /Type /Page";
1259 $res .=
"\n/Parent " . $o[
'info'][
'parent'] .
" 0 R";
1261 if (isset($o[
'info'][
'annot']))
1263 $res .=
"\n/Annots [";
1265 foreach ($o[
'info'][
'annot'] as $aId)
1267 $res .=
" " . $aId .
" 0 R";
1273 $count = count($o[
'info'][
'contents']);
1277 $res .=
"\n/Contents " . $o[
'info'][
'contents'][0] .
" 0 R";
1279 else if ($count > 1)
1281 $res .=
"\n/Contents [\n";
1283 foreach ($o[
'info'][
'contents'] as $cId)
1285 $res .= $cId .
" 0 R\n";
1291 $res .=
"\n>>\nendobj";
1304 $o = &$this->objects[
$id];
1310 $this->objects[
$id] = array
1318 if (strlen($options) && intval($options))
1321 $this->objects[
$id][
'onPage'] = $options;
1323 else if ($options ==
'raw')
1326 $this->objects[
$id][
'raw'] = 1;
1333 foreach ($options as $k => $v)
1335 $o[
'info'][$k] = $v;
1341 $res =
"\n" .
$id .
" 0 obj\n";
1343 if (isset($this->objects[
$id][
'raw']))
1351 if (function_exists(
'gzcompress') && $this->options[
'compression'])
1354 $res .=
" /Filter /FlateDecode";
1355 $tmp = gzcompress($tmp);
1358 if ($this->encrypted)
1361 $tmp = $this->
ARC4($tmp);
1364 foreach ($o[
'info'] as $k => $v)
1366 $res .=
"\n/" . $k .
' ' . $v;
1369 $res .=
"\n/Length " . strlen($tmp) .
" >>\nstream\n" . $tmp .
"\nendstream";
1372 $res .=
"\nendobj\n";
1385 $o = &$this->objects[
$id];
1392 $this->objects[
$id] = array
1395 'data' => $options[
'data'],
1400 $this->objects[
$id][
'info'][
'Type'] =
'/XObject';
1401 $this->objects[
$id][
'info'][
'Subtype'] =
'/Image';
1402 $this->objects[
$id][
'info'][
'Width'] = $options[
'iw'];
1403 $this->objects[
$id][
'info'][
'Height'] = $options[
'ih'];
1405 if (!isset($options[
'type']) || $options[
'type'] ==
'jpg')
1407 if (!isset($options[
'channels']))
1409 $options[
'channels'] = 3;
1412 switch ($options[
'channels'])
1415 $this->objects[
$id][
'info'][
'ColorSpace'] =
'/DeviceGray';
1420 $this->objects[
$id][
'info'][
'ColorSpace'] =
'/DeviceRGB';
1425 $this->objects[
$id][
'info'][
'Filter'] =
'/DCTDecode';
1426 $this->objects[
$id][
'info'][
'BitsPerComponent'] = 8;
1428 else if ($options[
'type'] ==
'png')
1430 $this->objects[
$id][
'info'][
'Filter'] =
'/FlateDecode';
1431 $this->objects[
$id][
'info'][
'DecodeParms']
1432 =
'<< /Predictor 15 /Colors ' . $options[
'ncolor'] .
' /Columns ' . $options[
'iw']
1433 .
' /BitsPerComponent ' . $options[
'bitsPerComponent'] .
'>>';
1435 if (strlen($options[
'pdata']))
1437 $tmp =
' [ /Indexed /DeviceRGB ' . (strlen($options[
'pdata']) / 3 - 1) .
' ';
1440 $this->objects[$this->numObj][
'c'] = $options[
'pdata'];
1441 $tmp .= $this->numObj .
' 0 R';
1443 $this->objects[
$id][
'info'][
'ColorSpace'] = $tmp;
1445 if (isset($options[
'transparency']))
1447 switch ($options[
'transparency'][
'type'])
1450 $tmp =
' [ ' . $options[
'transparency'][
'data'] .
' '
1451 . $options[
'transparency'][
'data'] .
'] ';
1453 $this->objects[
$id][
'info'][
'Mask'] = $tmp;
1460 $this->objects[
$id][
'info'][
'ColorSpace'] =
'/' . $options[
'color'];
1463 $this->objects[
$id][
'info'][
'BitsPerComponent'] = $options[
'bitsPerComponent'];
1468 $this->
o_pages($this->currentNode,
'xObject', array(
'label' => $options[
'label'],
'objNum' =>
$id));
1470 $this->
o_procset($this->procsetObjectId,
'add',
'ImageC');
1476 $res =
"\n" .
$id .
" 0 obj\n<<";
1478 foreach ($o[
'info'] as $k => $v)
1480 $res .=
"\n/" . $k .
' ' . $v;
1483 if ($this->encrypted)
1486 $tmp = $this->
ARC4($tmp);
1489 $res .=
"\n/Length " . strlen($tmp) .
" >>\nstream\n" . $tmp .
"\nendstream\nendobj\n";
1502 $o = &$this->objects[
$id];
1509 $this->objects[
$id] = array
1511 't' =>
'encryption',
1515 $this->arc4_objnum =
$id;
1517 $pad = chr(0x28) . chr(0xBF) . chr(0x4E) . chr(0x5E) . chr(0x4E) . chr(0x75) . chr(0x8A) . chr(0x41)
1519 . chr(0x00) . chr(0x4E) . chr(0x56) . chr(0xFF) . chr(0xFA) . chr(0x01) . chr(0x08) . chr(
1521 . chr(0x2E) . chr(0x00) . chr(0xB6) . chr(0xD0) . chr(0x68) . chr(0x3E) . chr(0x80) . chr(
1523 . chr(0x0C) . chr(0xA9) . chr(0xFE) . chr(0x64) . chr(0x53) . chr(0x69) . chr(0x7A);
1524 $len = strlen($options[
'owner']);
1528 $owner = substr($options[
'owner'], 0, 32);
1532 $owner = $options[
'owner'] . substr($pad, 0, 32 - $len);
1536 $owner = $options[
'owner'];
1539 $len = strlen($options[
'user']);
1543 $user = substr($options[
'user'], 0, 32);
1547 $user = $options[
'user'] . substr($pad, 0, 32 - $len);
1551 $user = $options[
'user'];
1554 $tmp = $this->
md5_16($owner);
1555 $okey = substr($tmp, 0, 5);
1557 $ovalue = $this->
ARC4($user);
1558 $this->objects[
$id][
'info'][
'O'] = $ovalue;
1560 $tmp = $this->
md5_16($user . $ovalue . chr($options[
'p']) . chr(255) . chr(255) . chr(255)
1561 . $this->fileIdentifier);
1562 $ukey = substr($tmp, 0, 5);
1565 $this->encryptionKey = $ukey;
1566 $this->encrypted = 1;
1567 $uvalue = $this->
ARC4($pad);
1569 $this->objects[
$id][
'info'][
'U'] = $uvalue;
1570 $this->encryptionKey = $ukey;
1576 $res =
"\n" .
$id .
" 0 obj\n<<";
1578 $res .=
"\n/Filter /Standard";
1581 $res .=
"\n/O (" . $this->
filterText($o[
'info'][
'O']) .
')';
1582 $res .=
"\n/U (" . $this->
filterText($o[
'info'][
'U']) .
')';
1584 $o[
'info'][
'p'] = (($o[
'info'][
'p'] ^ 255) + 1) * -1;
1585 $res .=
"\n/P " . ($o[
'info'][
'p']);
1586 $res .=
"\n>>\nendobj\n";
1603 $tmp = md5($string);
1606 for ($i = 0; $i <= 30; $i = $i + 2)
1608 $out .= chr(hexdec(substr($tmp, $i, 2)));
1619 $tmp = $this->encryptionKey;
1622 if (strlen($hex) < 6)
1624 $hex = substr(
'000000', 0, 6 - strlen($hex)) . $hex;
1627 $tmp .= chr(hexdec(substr($hex, 4, 2))) . chr(hexdec(substr($hex, 2, 2))) . chr(hexdec(substr($hex, 0,
1630 $key = $this->
md5_16($tmp);
1642 if (strlen($key) == 0)
1649 while (strlen($k) < 256)
1654 $k = substr($k, 0, 256);
1656 for ($i = 0; $i < 256; $i++)
1658 $this->arc4 .= chr($i);
1663 for ($i = 0; $i < 256; $i++)
1665 $t = $this->arc4[$i];
1666 $j = ($j + ord($t) + ord($k[$i])) % 256;
1667 $this->arc4[$i] = $this->arc4[$j];
1668 $this->arc4[$j] = $t;
1677 $len = strlen($text);
1683 for ($i = 0; $i < $len; $i++)
1685 $a = ($a + 1) % 256;
1687 $b = ($b + ord($t)) % 256;
1690 $k = ord($c[(ord($c[$a]) + ord($c[$b])) % 256]);
1691 $out .= chr(ord($text[$i]) ^ $k);
1711 'rect' => array($x0, $y0, $x1, $y1)
1727 'rect' => array($x0, $y0, $x1, $y1)
1741 $p = bindec(11000000);
1751 foreach ($pc as $k => $v)
1753 if ($v && isset($options[$k]))
1757 else if (isset($options[$v]))
1764 if ($this->arc4_objnum == 0)
1769 if (strlen($ownerPass) == 0)
1771 $ownerPass = $userPass;
1774 $this->
o_encryption($this->numObj,
'new', array(
'user' => $userPass,
'owner' => $ownerPass,
'p' => $p));
1793 $this->options[
'compression'] = 0;
1796 if ($this->arc4_objnum)
1806 $content =
"%PDF-1.3\n%âãÏÓ\n";
1808 $pos = strlen($content);
1810 foreach ($this->objects as $k => $v)
1812 $tmp =
'o_' . $v[
't'];
1813 $cont = $this->$tmp($k,
'out');
1816 $pos += strlen($cont);
1819 $content .=
"\nxref\n0 " . (count($xref) + 1) .
"\n0000000000 65535 f \n";
1821 foreach ($xref as $p)
1823 $content .= substr(
'0000000000', 0, 10 - strlen($p)) . $p .
" 00000 n \n";
1826 $content .=
"\ntrailer\n << /Size " . (count($xref)
1827 + 1) .
"\n /Root 1 0 R\n /Info " . $this->infoObject
1831 if ($this->arc4_objnum > 0)
1833 $content .=
"/Encrypt " . $this->arc4_objnum .
" 0 R\n";
1836 if (strlen($this->fileIdentifier))
1838 $content .=
"/ID[<" . $this->fileIdentifier .
"><" . $this->fileIdentifier .
">]\n";
1841 $content .=
" >>\nstartxref\n" . $pos .
"\n%%EOF\n";
1855 $this->objects = array(
1865 $this->
o_pages($this->numObj,
'new');
1867 $this->
o_pages($this->numObj,
'mediaBox', $pageSize);
1868 $this->currentNode = 3;
1874 $this->
o_info($this->numObj,
'new');
1877 $this->
o_page($this->numObj,
'new');
1881 $this->firstPageId = $this->currentContents;
1896 $pos = strrpos($font,
'/');
1905 $dir = substr($font, 0, $pos + 1);
1906 $name = substr($font, $pos + 1);
1909 if (substr($name, -4) ==
'.afm')
1911 $name = substr($name, 0, strlen($name) - 4);
1914 $this->
addMessage(
'openFont: ' . $font .
' - ' . $name);
1916 if (file_exists($dir .
'php_' . $name .
'.afm'))
1918 $this->
addMessage(
'openFont: php file exists ' . $dir .
'php_' . $name .
'.afm');
1919 $tmp = file($dir .
'php_' . $name .
'.afm');
1920 $this->fonts[$font] = unserialize($tmp[0]);
1922 if (!isset($this->fonts[$font][
'_version_']) || $this->fonts[$font][
'_version_'] < 1)
1925 $this->
addMessage(
'openFont: clear out, make way for new version.');
1926 unset($this->fonts[$font]);
1930 if (!isset($this->fonts[$font]) && file_exists($dir . $name .
'.afm'))
1933 $this->
addMessage(
'openFont: build php file from ' . $dir . $name .
'.afm');
1937 $file = file($dir . $name .
'.afm');
1939 foreach ($file as $rowA)
1942 $pos = strpos($row,
' ');
1947 $key = substr($row, 0, $pos);
1956 case 'IsFixedPitch':
1957 case 'CharacterSet':
1958 case 'UnderlinePosition':
1959 case 'UnderlineThickness':
1961 case 'EncodingScheme':
1968 case 'StartCharMetrics':
1969 $data[$key] = trim(substr($row, $pos));
1974 $data[$key] = explode(
' ', trim(substr($row, $pos)));
1980 $bits = explode(
';', trim($row));
1985 foreach ($bits as $bit)
1987 $bits2 = explode(
' ', trim($bit));
1989 if (strlen($bits2[0]))
1991 if (count($bits2) > 2)
1993 $dtmp[$bits2[0]] = array(
1996 for ($i = 1; $i < count($bits2); $i++)
1998 $dtmp[$bits2[0]][] = $bits2[$i];
2001 else if (count($bits2) == 2)
2003 $dtmp[$bits2[0]] = $bits2[1];
2008 if ($dtmp[
'C'] >= 0)
2010 $data[
'C'][$dtmp[
'C']] = $dtmp;
2011 $data[
'C'][$dtmp[
'N']] = $dtmp;
2015 $data[
'C'][$dtmp[
'N']] = $dtmp;
2022 $bits = explode(
' ', trim($row));
2024 $data[
'KPX'][$bits[1]][$bits[2]] = $bits[3];
2030 $data[
'_version_'] = 1;
2031 $this->fonts[$font] = $data;
2032 $fp = fopen($dir .
'php_' . $name .
'.afm',
'w');
2033 fwrite($fp, serialize($data));
2036 else if (!isset($this->fonts[$font]))
2038 $this->
addMessage(
'openFont: no font file found');
2053 if (strpos($fontName, $this->fonts_path) ===
false)
2054 $fontName = $this->fonts_path .
'/' . $fontName;
2057 if (!isset($this->fonts[$fontName]))
2062 if (isset($this->fonts[$fontName]))
2066 $pos = strrpos($fontName,
'/');
2068 $name = substr($fontName, $pos + 1);
2070 if (substr($name, -4) ==
'.afm')
2072 $name = substr($name, 0, strlen($name) - 4);
2075 $options = array(
'name' => $name);
2077 if (is_array($encoding))
2080 if (isset($encoding[
'encoding']))
2082 $options[
'encoding'] = $encoding[
'encoding'];
2085 if (isset($encoding[
'differences']))
2087 $options[
'differences'] = $encoding[
'differences'];
2090 else if (strlen($encoding))
2093 $options[
'encoding'] = $encoding;
2096 $fontObj = $this->numObj;
2097 $this->
o_font($this->numObj,
'new', $options);
2098 $this->fonts[$fontName][
'fontNum'] = $this->numFonts;
2102 $basefile = substr($fontName, 0, strlen($fontName) - 4);
2104 if (file_exists($basefile .
'.pfb'))
2108 else if (file_exists($basefile .
'.ttf'))
2117 $fbfile = $basefile .
'.' . $fbtype;
2121 $this->
addMessage(
'selectFont: checking for - ' . $fbfile);
2123 if (substr($fontName, -4) ==
'.afm' && strlen($fbtype))
2125 $adobeFontName = $this->fonts[$fontName][
'FontName'];
2127 $this->
addMessage(
'selectFont: adding font file - ' . $fbfile .
' - ' . $adobeFontName);
2134 foreach ($this->fonts[$fontName][
'C'] as $num => $d)
2136 if (intval($num) > 0 || $num ==
'0')
2138 if ($lastChar > 0 && $num > $lastChar + 1)
2140 for ($i = $lastChar + 1; $i < $num; $i++)
2146 $widths[] = $d[
'WX'];
2148 if ($firstChar == -1)
2158 if (isset($options[
'differences']))
2160 foreach ($options[
'differences'] as $charNum => $charName)
2162 if ($charNum > $lastChar)
2164 for ($i = $lastChar + 1; $i <= $charNum; $i++)
2169 $lastChar = $charNum;
2172 if (isset($this->fonts[$fontName][
'C'][$charName]))
2174 $widths[$charNum - $firstChar] = $this->fonts[$fontName][
'C'][$charName][
'WX'];
2179 $this->
addMessage(
'selectFont: FirstChar=' . $firstChar);
2180 $this->
addMessage(
'selectFont: LastChar=' . $lastChar);
2182 $this->
o_contents($this->numObj,
'new',
'raw');
2183 $this->objects[$this->numObj][
'c'] .=
'[';
2185 foreach ($widths as $width)
2187 $this->objects[$this->numObj][
'c'] .=
' ' . $width;
2190 $this->objects[$this->numObj][
'c'] .=
' ]';
2191 $widthid = $this->numObj;
2196 $fp = fopen($fbfile,
'rb');
2197 $data = fread($fp, filesize($fbfile));
2202 $fontDescriptorId = $this->numObj;
2204 $pfbid = $this->numObj;
2208 if ($this->fonts[$fontName][
'ItalicAngle'] != 0)
2210 $flags += pow(2, 6);
2213 if ($this->fonts[$fontName][
'IsFixedPitch'] ==
'true')
2218 $flags += pow(2, 5);
2222 'Ascent' =>
'Ascender',
2223 'CapHeight' =>
'CapHeight',
2224 'Descent' =>
'Descender',
2225 'FontBBox' =>
'FontBBox',
2226 'ItalicAngle' =>
'ItalicAngle'
2232 'FontName' => $adobeFontName,
2236 foreach ($list as $k => $v)
2238 if (isset($this->fonts[$fontName][$v]))
2240 $fdopt[$k] = $this->fonts[$fontName][$v];
2244 if ($fbtype ==
'pfb')
2246 $fdopt[
'FontFile'] = $pfbid;
2248 else if ($fbtype ==
'ttf')
2250 $fdopt[
'FontFile2'] = $pfbid;
2257 $this->objects[$pfbid][
'c'] .= $data;
2260 if ($fbtype ==
'pfb')
2262 $l1 = strpos($data,
'eexec') + 6;
2263 $l2 = strpos($data,
'00000000') - $l1;
2264 $l3 = strlen($data) - $l2 - $l1;
2266 array(
'Length1' => $l1,
'Length2' => $l2,
'Length3' => $l3));
2268 else if ($fbtype ==
'ttf')
2270 $l1 = strlen($data);
2271 $this->
o_contents($this->numObj,
'add', array(
'Length1' => $l1));
2277 'BaseFont' => $adobeFontName,
2278 'Widths' => $widthid,
2279 'FirstChar' => $firstChar,
2280 'LastChar' => $lastChar,
2281 'FontDescriptor' => $fontDescriptorId
2284 if ($fbtype ==
'ttf')
2286 $tmp[
'SubType'] =
'TrueType';
2289 $this->
addMessage(
'adding extra info to font.(' . $fontObj .
')');
2291 foreach ($tmp as $fk => $fv)
2296 $this->
o_font($fontObj,
'add', $tmp);
2301 'selectFont: pfb or ttf file not found, ok if this is one of the 14 standard fonts');
2306 if (isset($options[
'differences']))
2308 $this->fonts[$fontName][
'differences'] = $options[
'differences'];
2313 if ($set && isset($this->fonts[$fontName]))
2316 $this->currentBaseFont = $fontName;
2322 return $this->currentFontNum;
2339 if (strlen($this->currentBaseFont) == 0)
2342 $this->
selectFont($this->fonts_path .
'/Helvetica.afm');
2345 $cf = substr($this->currentBaseFont, strrpos($this->currentBaseFont,
'/') + 1);
2347 if (strlen($this->currentTextState) && isset($this->fontFamilies[$cf]) && isset(
2348 $this->fontFamilies[$cf][$this->currentTextState]))
2353 $nf = substr($this->currentBaseFont, 0,
2354 strrpos($this->currentBaseFont,
'/') + 1) . $this->fontFamilies[$cf][$this->currentTextState];
2356 $this->currentFont = $nf;
2357 $this->currentFontNum = $this->fonts[$nf][
'fontNum'];
2363 $this->currentFont = $this->currentBaseFont;
2364 $this->currentFontNum = $this->fonts[$this->currentFont][
'fontNum'];
2374 return $this->firstPageId;
2384 $this->objects[$this->currentContents][
'c'] .= $content;
2392 if ($r >= 0 && ($force || $r != $this->currentColour[
'r'] || $g != $this->currentColour[
'g']
2393 || $b != $this->currentColour[
'b']))
2395 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2399 $this->currentColour = array
2413 if ($r >= 0 && ($force || $r != $this->currentStrokeColour[
'r'] || $g != $this->currentStrokeColour[
'g']
2414 || $b != $this->currentStrokeColour[
'b']))
2416 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2420 $this->currentStrokeColour = array
2434 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2438 $x2) .
' ' .
__sprintf(
'%.3f', $y2) .
' l S';
2444 function curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3)
2448 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2452 $this->objects[$this->currentContents][
'c'] .=
' ' .
__sprintf(
'%.3f',
2456 $x3) .
' ' .
__sprintf(
'%.3f', $y3) .
' c S';
2462 function partEllipse($x0, $y0, $astart, $afinish, $r1, $r2 = 0, $angle = 0, $nSeg = 8)
2464 $this->
ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, 0);
2470 function filledEllipse($x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360)
2472 return $this->
ellipse($x0, $y0, $r1, $r2 = 0, $angle, $nSeg, $astart, $afinish, 1, 1);
2485 function ellipse($x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360, $close = 1, $fill = 0)
2502 $astart = deg2rad((
float)$astart);
2503 $afinish = deg2rad((
float)$afinish);
2504 $totalAngle = $afinish - $astart;
2506 $dt = $totalAngle / $nSeg;
2511 $a = -1 * deg2rad((
float)$angle);
2515 (-1.0 * sin($a))) .
' ' .
__sprintf(
'%.3f',
2519 $this->objects[$this->currentContents][
'c'] .= $tmp;
2525 $a0 = $x0 + $r1 * cos($t1);
2526 $b0 = $y0 + $r2 * sin($t1);
2527 $c0 = -$r1 * sin($t1);
2528 $d0 = $r2 * cos($t1);
2530 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2531 $a0) .
' ' .
__sprintf(
'%.3f', $b0) .
' m ';
2533 for ($i = 1; $i <= $nSeg; $i++)
2536 $t1 = $i * $dt + $astart;
2537 $a1 = $x0 + $r1 * cos($t1);
2538 $b1 = $y0 + $r2 * sin($t1);
2539 $c1 = -$r1 * sin($t1);
2540 $d1 = $r2 * cos($t1);
2541 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2546 $this->objects[$this->currentContents][
'c'] .=
' ' .
__sprintf(
'%.3f',
2553 $a1) .
' ' .
__sprintf(
'%.3f', $b1) .
' c';
2562 $this->objects[$this->currentContents][
'c'] .=
' f';
2568 $this->objects[$this->currentContents][
'c'] .=
' s';
2572 $this->objects[$this->currentContents][
'c'] .=
' S';
2578 $this->objects[$this->currentContents][
'c'] .=
' Q';
2595 function setLineStyle($width = 1, $cap =
'', $join =
'', $dash =
'', $phase = 0)
2603 $string .= $width .
' w';
2613 if (isset($ca[$cap]))
2615 $string .=
' ' . $ca[$cap] .
' J';
2625 if (isset($ja[$join]))
2627 $string .=
' ' . $ja[$join] .
' j';
2630 if (is_array($dash))
2634 foreach ($dash as $len)
2636 $string .=
' ' . $len;
2639 $string .=
' ] ' . $phase .
' d';
2642 $this->currentLineStyle = $string;
2643 $this->objects[$this->currentContents][
'c'] .=
"\n" . $string;
2651 $this->objects[$this->currentContents][
'c'] .=
"\n";
2652 $this->objects[$this->currentContents][
'c'] .=
__sprintf(
'%.3f',
2653 $p[0]) .
' ' .
__sprintf(
'%.3f', $p[1]) .
' m ';
2655 for ($i = 2; $i < $np * 2; $i = $i + 2)
2657 $this->objects[$this->currentContents][
'c'] .=
__sprintf(
'%.3f',
2659 $p[$i + 1]) .
' l ';
2664 $this->objects[$this->currentContents][
'c'] .=
' f';
2668 $this->objects[$this->currentContents][
'c'] .=
' S';
2678 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2692 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
2710 if ($this->nStateStack)
2712 for ($i = $this->nStateStack; $i >= 1; $i--)
2724 $rid = $this->objects[
$id][
'onPage'];
2731 $this->
o_page($this->numObj,
'new', $opt);
2735 $this->
o_page($this->numObj,
'new');
2739 if ($this->nStateStack)
2741 for ($i = 1; $i <= $this->nStateStack; $i++)
2748 if ($this->currentColour[
'r'] >= 0)
2750 $this->
setColor($this->currentColour[
'r'], $this->currentColour[
'g'], $this->currentColour[
'b'], 1);
2753 if ($this->currentStrokeColour[
'r'] >= 0)
2755 $this->
setStrokeColor($this->currentStrokeColour[
'r'], $this->currentStrokeColour[
'g'],
2756 $this->currentStrokeColour[
'b'], 1);
2760 if (strlen($this->currentLineStyle))
2762 $this->objects[$this->currentContents][
'c'] .=
"\n" . $this->currentLineStyle;
2766 return $this->currentContents;
2783 if (!is_array($options))
2789 if (isset($options[
'compress']) && $options[
'compress'] == 0)
2798 header(
"Content-type: application/pdf");
2799 header(
"Content-Length: " . strlen(ltrim($tmp)));
2800 $fileName = (isset($options[
'Content-Disposition']) ? $options[
'Content-Disposition'] :
'file.pdf');
2801 header(
"Content-Disposition: inline; filename=" . $fileName);
2803 if (isset($options[
'Accept-Ranges']) && $options[
'Accept-Ranges'] == 1)
2805 header(
"Accept-Ranges: " . strlen(ltrim($tmp)));
2816 if (!$this->numFonts)
2818 $this->
selectFont($this->fonts_path .
'/Helvetica');
2822 $h = $this->fonts[$this->currentFont][
'FontBBox'][3] - $this->fonts[$this->currentFont][
'FontBBox'][1];
2823 return $size * $h / 1000;
2834 if (!$this->numFonts)
2836 $this->
selectFont($this->fonts_path .
'/Helvetica');
2839 $h = $this->fonts[$this->currentFont][
'FontBBox'][1];
2840 return $size * $h / 1000;
2851 $text = str_replace(
'\\',
'\\\\', $text);
2852 $text = str_replace(
'(',
'\(', $text);
2853 $text = str_replace(
')',
'\)', $text);
2854 $text = str_replace(
'<',
'<', $text);
2855 $text = str_replace(
'>',
'>', $text);
2856 $text = str_replace(
''',
'\'', $text);
2857 $text = str_replace(
'"',
'"', $text);
2858 $text = str_replace(
'&',
'&', $text);
2874 $words = explode(
' ', $text);
2875 $nspaces = count($words) - 1;
2876 $w += $wa * $nspaces;
2877 $a = deg2rad((
float)$angle);
2878 return array(cos($a) * $w + $x, -sin($a) * $w + $y);
2907 if ($text[$j] ==
'<')
2916 if (strlen($text) <= $j)
2927 if ($text[$j] ==
'>')
2929 $p = strrpos($this->currentTextState, $text[$j - 1]);
2934 $this->currentTextState = substr($this->currentTextState, 0,
2935 $p) . substr($this->currentTextState, $p + 1);
2938 $directive = $j - $i + 1;
2947 $k = strpos($text,
'>', $j);
2949 if ($k !==
false && $text[$j] ==
':')
2952 $directive = $k - $i + 1;
2955 $tmp = substr($text, $j + 1, $k - $j - 1);
2956 $b1 = strpos($tmp,
':');
2960 $func = substr($tmp, 0, $b1);
2961 $parm = substr($tmp, $b1 + 1);
2969 if (!isset($func) || !strlen(trim($func)))
2981 $x, $y, $angle, $size, $wordSpaceAdjust, substr($text, 0, $i));
2989 'nCallback' => $this->nCallback
2994 $ret = $this->$func($info);
2999 foreach ($ret as $rk => $rv)
3016 if ($this->nCallback < 0)
3018 $this->nCallBack = 0;
3033 if ($text[$j] ==
'>')
3035 $this->currentTextState .= $text[$j - 1];
3036 $directive = $j - $i + 1;
3041 case 'C': $noClose = 1;
3047 $k = strpos($text,
'>', $j);
3049 if ($k !==
false && $text[$j] ==
':')
3052 $directive = $k - $i + 1;
3056 $tmp = substr($text, $j + 1, $k - $j - 1);
3057 $b1 = strpos($tmp,
':');
3061 $func = substr($tmp, 0, $b1);
3062 $parm = substr($tmp, $b1 + 1);
3070 if (!isset($func) || !strlen(trim($func)))
3083 substr($text, 0, $i));
3089 'status' =>
'start',
3099 if (!isset($noClose) || !$noClose)
3103 $info[
'nCallback'] = $this->nCallback;
3104 $this->callback[$this->nCallback] = $info;
3107 $ret = $this->$func($info);
3112 foreach ($ret as $rk => $rv)
3138 function addText($x, $y, $size, $text, $angle = 0, $wordSpaceAdjust = 0)
3140 if (!$this->numFonts)
3142 $this->
selectFont($this->fonts_path .
'/Helvetica');
3146 if ($this->nCallback > 0)
3148 for ($i = $this->nCallback; $i > 0; $i--)
3157 'p' => $this->callback[$i][
'p'],
3158 'nCallback' => $this->callback[$i][
'nCallback'],
3159 'height' => $this->callback[$i][
'height'],
3160 'decender' => $this->callback[$i][
'decender']
3163 $func = $this->callback[$i][
'f'];
3164 $this->$func($info);
3170 $this->objects[$this->currentContents][
'c'] .=
"\n" .
'BT ' .
__sprintf(
'%.3f',
3176 $a = deg2rad((
float)$angle);
3177 $tmp =
"\n" .
'BT ';
3180 (-1.0 * sin($a))) .
' ' .
__sprintf(
'%.3f',
3184 $this->objects[$this->currentContents][
'c'] .= $tmp;
3187 if ($wordSpaceAdjust != 0 || $wordSpaceAdjust != $this->wordSpaceAdjust)
3189 $this->wordSpaceAdjust = $wordSpaceAdjust;
3190 $this->objects[$this->currentContents][
'c'] .=
' ' .
__sprintf(
'%.3f', $wordSpaceAdjust) .
' Tw';
3193 $len = strlen($text);
3196 for ($i = 0; $i < $len; $i++)
3206 $part = substr($text, $start, $i - $start);
3207 $this->objects[$this->currentContents][
'c']
3208 .=
' /F' . $this->currentFontNum .
' ' .
__sprintf(
'%.1f', $size) .
' Tf ';
3209 $this->objects[$this->currentContents][
'c'] .=
' (' . $this->
filterText($part) .
') Tj';
3219 $this->objects[$this->currentContents][
'c'] .=
' ET';
3224 $text, $i, $f, 1, $xp, $yp, $size, $angle, $wordSpaceAdjust);
3229 $this->objects[$this->currentContents][
'c'] .=
"\n" .
'BT ' .
__sprintf(
'%.3f',
3235 $a = deg2rad((
float)$angle);
3236 $tmp =
"\n" .
'BT ';
3239 (-1.0 * sin($a))) .
' ' .
__sprintf(
'%.3f',
3243 $this->objects[$this->currentContents][
'c'] .= $tmp;
3246 if ($wordSpaceAdjust != 0 || $wordSpaceAdjust != $this->wordSpaceAdjust)
3248 $this->wordSpaceAdjust = $wordSpaceAdjust;
3249 $this->objects[$this->currentContents][
'c'] .=
' ' .
__sprintf(
'%.3f',
3250 $wordSpaceAdjust) .
' Tw';
3255 $i = $i + $directive - 1;
3262 $part = substr($text, $start);
3263 $this->objects[$this->currentContents][
'c'] .=
' /F' . $this->currentFontNum .
' ' .
__sprintf(
'%.1f',
3266 $this->objects[$this->currentContents][
'c'] .=
' (' . $this->
filterText($part) .
') Tj';
3269 $this->objects[$this->currentContents][
'c'] .=
' ET';
3272 if ($this->nCallback > 0)
3274 for ($i = $this->nCallback; $i > 0; $i--)
3284 'p' => $this->callback[$i][
'p'],
3285 'nCallback' => $this->callback[$i][
'nCallback'],
3286 'height' => $this->callback[$i][
'height'],
3287 'decender' => $this->callback[$i][
'decender']
3290 $func = $this->callback[$i][
'f'];
3291 $this->$func($info);
3305 $store_currentTextState = $this->currentTextState;
3307 if (!$this->numFonts)
3309 $this->
selectFont($this->fonts_path .
'/Helvetica');
3318 $len = strlen($text);
3319 $cf = $this->currentFont;
3321 for ($i = 0; $i < $len; $i++)
3331 $cf = $this->currentFont;
3334 $i = $i + $directive - 1;
3338 $char = ord($text[$i]);
3340 if (isset($this->fonts[$cf][
'differences'][$char]))
3343 $name = $this->fonts[$cf][
'differences'][$char];
3345 if (isset($this->fonts[$cf][
'C'][$name][
'WX']))
3347 $w += $this->fonts[$cf][
'C'][$name][
'WX'];
3350 else if (isset($this->fonts[$cf][
'C'][$char][
'WX']))
3352 $w += $this->fonts[$cf][
'C'][$char][
'WX'];
3357 $this->currentTextState = $store_currentTextState;
3360 return $w * $size / 1000;
3370 switch ($justification)
3378 $x += $width - $actual;
3384 $x += ($width - $actual) / 2;
3390 $words = explode(
' ', $text);
3392 $nspaces = count($words) - 1;
3396 $adjust = ($width - $actual) / $nspaces;
3413 function addTextWrap($x, $y, $width, $size, $text, $justification =
'left', $angle = 0, $test = 0)
3422 $store_currentTextState = $this->currentTextState;
3424 if (!$this->numFonts)
3426 $this->
selectFont($this->fonts_path .
'/Helvetica');
3438 $len = strlen($text);
3439 $cf = $this->currentFont;
3440 $tw = $width / $size * 1000;
3442 for ($i = 0; $i < $len; $i++)
3452 $cf = $this->currentFont;
3455 $i = $i + $directive - 1;
3459 $cOrd = ord($text[$i]);
3461 if (isset($this->fonts[$cf][
'differences'][$cOrd]))
3464 $cOrd2 = $this->fonts[$cf][
'differences'][$cOrd];
3471 if (isset($this->fonts[$cf][
'C'][$cOrd2][
'WX']))
3473 $w += $this->fonts[$cf][
'C'][$cOrd2][
'WX'];
3482 if ($text[$break] ==
' ')
3484 $tmp = substr($text, 0, $break);
3488 $tmp = substr($text, 0, $break + 1);
3495 $this->currentTextState = $store_currentTextState;
3500 $this->
addText($x, $y, $size, $tmp, $angle, $adjust);
3503 return substr($text, $break + 1);
3508 $tmp = substr($text, 0, $i);
3510 $ctmp = ord($text[$i]);
3512 if (isset($this->fonts[$cf][
'differences'][$ctmp]))
3514 $ctmp = $this->fonts[$cf][
'differences'][$ctmp];
3517 $tmpw = ($w - $this->fonts[$cf][
'C'][$ctmp][
'WX']) * $size / 1000;
3520 $this->currentTextState = $store_currentTextState;
3525 $this->
addText($x, $y, $size, $tmp, $angle, $adjust);
3528 return substr($text, $i);
3532 if ($text[$i] ==
'-')
3535 $breakWidth = $w * $size / 1000;
3538 if ($text[$i] ==
' ')
3541 $ctmp = ord($text[$i]);
3543 if (isset($this->fonts[$cf][
'differences'][$ctmp]))
3545 $ctmp = $this->fonts[$cf][
'differences'][$ctmp];
3548 $breakWidth = ($w - $this->fonts[$cf][
'C'][$ctmp][
'WX']) * $size / 1000;
3554 if ($justification ==
'full')
3556 $justification =
'left';
3560 $tmpw = $w * $size / 1000;
3564 $this->currentTextState = $store_currentTextState;
3569 $this->
addText($x, $y, $size, $text, $angle, $adjust, $angle);
3588 $opt = $this->stateStack[$pageEnd];
3589 $this->
setColor($opt[
'col'][
'r'], $opt[
'col'][
'g'], $opt[
'col'][
'b'], 1);
3590 $this->
setStrokeColor($opt[
'str'][
'r'], $opt[
'str'][
'g'], $opt[
'str'][
'b'], 1);
3591 $this->objects[$this->currentContents][
'c'] .=
"\n" . $opt[
'lin'];
3596 $this->nStateStack++;
3597 $this->stateStack[$this->nStateStack] = array
3599 'col' => $this->currentColour,
3600 'str' => $this->currentStrokeColour,
3601 'lin' => $this->currentLineStyle
3605 $this->objects[$this->currentContents][
'c'] .=
"\nq";
3615 $n = $this->nStateStack;
3616 $this->currentColour = $this->stateStack[$n][
'col'];
3617 $this->currentStrokeColour = $this->stateStack[$n][
'str'];
3618 $this->objects[$this->currentContents][
'c'] .=
"\n" . $this->stateStack[$n][
'lin'];
3619 $this->currentLineStyle = $this->stateStack[$n][
'lin'];
3620 unset($this->stateStack[$n]);
3621 $this->nStateStack--;
3624 $this->objects[$this->currentContents][
'c'] .=
"\nQ";
3636 $this->stack[$this->nStack] = array
3638 'c' => $this->currentContents,
3639 'p' => $this->currentPage
3645 $this->currentContents = $this->numObj;
3646 $this->looseObjects[$this->numObj] = 1;
3648 return $this->numObj;
3657 $this->stack[$this->nStack] = array
3659 'c' => $this->currentContents,
3660 'p' => $this->currentPage
3663 $this->currentContents =
$id;
3666 if (isset($this->objects[
$id][
'onPage']))
3668 $this->currentPage = $this->objects[
$id][
'onPage'];
3679 if ($this->nStack > 0)
3681 $this->currentContents = $this->stack[$this->nStack][
'c'];
3682 $this->currentPage = $this->stack[$this->nStack][
'p'];
3696 if (isset($this->addLooseObjects[
$id]))
3698 $this->addLooseObjects[
$id] =
'';
3708 if (isset($this->looseObjects[
$id]) && $this->currentContents !=
$id)
3716 $this->addLooseObjects[
$id] =
'all';
3719 if (isset($this->objects[$this->currentContents][
'onPage']))
3723 $this->
o_page($this->objects[$this->currentContents][
'onPage'],
'content',
$id);
3729 $this->addLooseObjects[
$id] =
'even';
3731 $pageObjectId = $this->objects[$this->currentContents][
'onPage'];
3733 if ($this->objects[$pageObjectId][
'info'][
'pageNum'] % 2 == 0)
3741 $this->addLooseObjects[
$id] =
'odd';
3743 $pageObjectId = $this->objects[$this->currentContents][
'onPage'];
3745 if ($this->objects[$pageObjectId][
'info'][
'pageNum'] % 2 == 1)
3753 $this->addLooseObjects[
$id] =
'all';
3758 $this->addLooseObjects[
$id] =
'even';
3763 $this->addLooseObjects[
$id] =
'odd';
3779 if (is_array($label))
3781 foreach ($label as $l => $v)
3783 $this->
o_info($this->infoObject, $l, $v);
3788 $this->
o_info($this->infoObject, $label, $value);
3798 if (is_array($label))
3800 foreach ($label as $l => $v)
3802 $this->
o_catalog($this->catalogId,
'viewerPreferences', array($l => $v));
3807 $this->
o_catalog($this->catalogId,
'viewerPreferences', array($label => $value));
3821 for ($i = 0; $i < $num; $i++)
3824 $ret += ord($data[$pos + $i]);
3838 $fp = @fopen($file,
'rb');
3846 $data .= fread($fp, 1024);
3854 $errormsg =
'trouble opening file: ' . $file;
3859 $header = chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10);
3861 if (substr($data, 0, 8) != $header)
3864 $errormsg =
'this file does not have a valid header';
3872 $len = strlen($data);
3884 $chunkType = substr($data, $p + 4, 4);
3894 $info[
'bitDepth'] = ord($data[$p + 16]);
3895 $info[
'colorType'] = ord($data[$p + 17]);
3896 $info[
'compressionMethod'] = ord($data[$p + 18]);
3897 $info[
'filterMethod'] = ord($data[$p + 19]);
3898 $info[
'interlaceMethod'] = ord($data[$p + 20]);
3902 if ($info[
'compressionMethod'] != 0)
3905 $errormsg =
'unsupported compression method';
3908 if ($info[
'filterMethod'] != 0)
3911 $errormsg =
'unsupported filter method';
3917 $pdata .= substr($data, $p + 8, $chunkLen);
3922 $idata .= substr($data, $p + 8, $chunkLen);
3929 $transparency = array(
3932 if ($info[
'colorType'] == 3)
3941 $transparency[
'type'] =
'indexed';
3942 $numPalette = strlen($pdata) / 3;
3945 for ($i = $chunkLen; $i >= 0; $i--)
3947 if (ord($data[$p + 8 + $i]) == 0)
3953 $transparency[
'data'] = $trans;
3955 elseif ($info[
'colorType'] == 0)
3961 $transparency[
'type'] =
'indexed';
3962 $transparency[
'data'] = ord($data[$p + 8 + 1]);
3964 elseif ($info[
'colorType'] == 2)
3971 $transparency[
'r'] = $this->
PRVT_getBytes($data, $p + 8, 2);
3972 $transparency[
'g'] = $this->
PRVT_getBytes($data, $p + 10, 2);
3973 $transparency[
'b'] = $this->
PRVT_getBytes($data, $p + 12, 2);
3986 $p += $chunkLen + 12;
3992 $errormsg =
'information header is missing';
3995 if (isset($info[
'interlaceMethod']) && $info[
'interlaceMethod'])
3998 $errormsg =
'There appears to be no support for interlaced images in pdf.';
4002 if (!$error && $info[
'bitDepth'] > 8)
4005 $errormsg =
'only bit depth of 8 or less is supported';
4010 if ($info[
'colorType'] != 2 && $info[
'colorType'] != 0 && $info[
'colorType'] != 3)
4014 =
'transparancey alpha channel not supported, transparency only supported for palette images.';
4018 switch ($info[
'colorType'])
4021 $color =
'DeviceRGB';
4027 $color =
'DeviceRGB';
4033 $color =
'DeviceGray';
4043 $this->
addMessage(
'PNG error - (' . $file .
') ' . $errormsg);
4049 $w = $h / $info[
'height'] * $info[
'width'];
4054 $h = $w * $info[
'height'] / $info[
'width'];
4060 $im = $this->numImages;
4068 'bitsPerComponent' => $info[
'bitDepth'],
4070 'iw' => $info[
'width'],
4071 'ih' => $info[
'height'],
4077 if (isset($transparency))
4079 $options[
'transparency'] = $transparency;
4082 $this->
o_image($this->numObj,
'new', $options);
4084 $this->objects[$this->currentContents][
'c'] .=
"\nq";
4085 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
4089 $x) .
" " .
__sprintf(
'%.3f', $y) .
" cm";
4090 $this->objects[$this->currentContents][
'c'] .=
"\n/" . $label .
' Do';
4091 $this->objects[$this->currentContents][
'c'] .=
"\nQ";
4102 if (!file_exists($img))
4107 $tmp = getimagesize($img);
4108 $imageWidth = $tmp[0];
4109 $imageHeight = $tmp[1];
4111 if (isset($tmp[
'channels']))
4113 $channels = $tmp[
'channels'];
4120 if ($w <= 0 && $h <= 0)
4127 $w = $h / $imageHeight * $imageWidth;
4132 $h = $w * $imageHeight / $imageWidth;
4135 $fp = fopen($img,
'rb');
4137 $data = fread($fp, filesize($img));
4149 function addImage(&$img, $x, $y, $w = 0, $h = 0, $quality = 75)
4166 $imageWidth = imagesx($img);
4167 $imageHeight = imagesy($img);
4169 if ($w <= 0 && $h <= 0)
4176 $w = $h / $imageHeight * $imageWidth;
4181 $h = $w * $imageHeight / $imageWidth;
4188 $tmpName = tempnam($tmpDir,
'img');
4189 imagejpeg($img, $tmpName, $quality);
4190 $fp = fopen($tmpName,
'rb');
4192 $fp = @fopen($tmpName,
'rb');
4200 $data .= fread($fp, 1024);
4208 $errormsg =
'trouble opening file';
4228 $im = $this->numImages;
4233 array(
'label' => $label,
'data' => $data,
'iw' => $imageWidth,
'ih' => $imageHeight,
4234 'channels' => $channels));
4236 $this->objects[$this->currentContents][
'c'] .=
"\nq";
4237 $this->objects[$this->currentContents][
'c'] .=
"\n" .
__sprintf(
'%.3f',
4241 $x) .
" " .
__sprintf(
'%.3f', $y) .
" cm";
4242 $this->objects[$this->currentContents][
'c'] .=
"\n/" . $label .
' Do';
4243 $this->objects[$this->currentContents][
'c'] .=
"\nQ";
4263 array(
'page' => $this->currentPage,
'type' => $style,
'p1' => $a,
'p2' => $b,
'p3' => $c));
4264 $id = $this->catalogId;
4278 array(
'page' => $this->currentPage,
'type' => $style,
'p1' => $a,
'p2' => $b,
'p3' => $c));
4279 $id = $this->numObj;
4281 $this->destinations[
"$label"] =
$id;
4291 if (!is_array($options))
4293 if ($family ==
'init')
4298 $this->fontFamilies[
'Helvetica.afm'] = array
4300 'b' =>
'Helvetica-Bold.afm',
4301 'i' =>
'Helvetica-Oblique.afm',
4302 'bi' =>
'Helvetica-BoldOblique.afm',
4303 'ib' =>
'Helvetica-BoldOblique.afm'
4306 $this->fontFamilies[
'Courier.afm'] = array
4308 'b' =>
'Courier-Bold.afm',
4309 'i' =>
'Courier-Oblique.afm',
4310 'bi' =>
'Courier-BoldOblique.afm',
4311 'ib' =>
'Courier-BoldOblique.afm'
4314 $this->fontFamilies[
'Times-Roman.afm'] = array
4316 'b' =>
'Times-Bold.afm',
4317 'i' =>
'Times-Italic.afm',
4318 'bi' =>
'Times-BoldItalic.afm',
4319 'ib' =>
'Times-BoldItalic.afm'
4327 if (strlen($family))
4329 $this->fontFamilies[$family] = $options;
4339 $this->messages .= $message .
"\n";
4398 $this->checkpoint = clone $this;
4403 if (is_object($this->checkpoint) && isset($this->checkpoint->checkpoint))
4405 $tmp = $this->checkpoint->checkpoint;
4406 $this->checkpoint = $tmp;
4411 $this->checkpoint =
'';
4418 if (is_object($this->checkpoint))
4421 $tmp = $this->checkpoint;
4423 foreach ($tmp as $k => $v)
4425 if ($k !=
'checkpoint')
4437 if (is_object($this->checkpoint))
4440 $tmp = $this->checkpoint;
4442 foreach ($tmp as $k => $v)
4457 $this->fonts_path = $path;
partEllipse($x0, $y0, $astart, $afinish, $r1, $r2=0, $angle=0, $nSeg=8)
PRVTcheckTextDirective1(&$text, $i, &$f, $final, &$x, &$y, $size=0, $angle=0, $wordSpaceAdjust=0)
curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3)
addPngFromFile($file, $x, $y, $w=0, $h=0)
o_info($id, $action, $options='')
addLink($url, $x0, $y0, $x1, $y1)
o_destination($id, $action, $options='')
setEncryption($userPass='', $ownerPass='', $pc=array())
__construct($pageSize=array(0, 0, 612, 792))
o_viewerPreferences($id, $action, $options='')
addImage(&$img, $x, $y, $w=0, $h=0, $quality=75)
addTextWrap($x, $y, $width, $size, $text, $justification='left', $angle=0, $test=0)
addText($x, $y, $size, $text, $angle=0, $wordSpaceAdjust=0)
filledRectangle($x1, $y1, $width, $height)
selectFont($fontName, $encoding='', $set=1)
setFontFamily($family, $options='')
o_outlines($id, $action, $options='')
o_font($id, $action, $options='')
addObject($id, $options='add')
PRVTcheckTextDirective(&$text, $i, &$f)
filledEllipse($x0, $y0, $r1, $r2=0, $angle=0, $nSeg=8, $astart=0, $afinish=360)
o_pages($id, $action, $options='')
addInfo($label, $value=0)
o_procset($id, $action, $options='')
setStrokeColor($r, $g, $b, $force=0)
setLineStyle($width=1, $cap='', $join='', $dash='', $phase=0)
PRVT_getBytes(&$data, $pos, $num)
Cpdf($pageSize=array(0, 0, 612, 792))
addInternalLink($label, $x0, $y0, $x1, $y1)
addJpegImage_common(&$data, $x, $y, $w=0, $h=0, $imageWidth, $imageHeight, $channels=3)
PRVTadjustWrapText($text, $actual, $width, &$x, &$adjust, $justification)
o_page($id, $action, $options='')
addDestination($label, $style, $a=0, $b=0, $c=0)
o_action($id, $action, $options='')
o_fontDescriptor($id, $action, $options='')
newDocument($pageSize=array(0, 0, 612, 792))
ellipse($x0, $y0, $r1, $r2=0, $angle=0, $nSeg=8, $astart=0, $afinish=360, $close=1, $fill=0)
setPreferences($label, $value=0)
o_image($id, $action, $options='')
o_contents($id, $action, $options='')
addJpegFromFile($img, $x, $y, $w=0, $h=0)
o_catalog($id, $action, $options='')
setColor($r, $g, $b, $force=0)
PRVTgetTextPosition($x, $y, $angle, $size, $wa, $text)
rectangle($x1, $y1, $width, $height)
newPage($insert=0, $id=0, $pos='after')
o_fontEncoding($id, $action, $options='')
o_annotation($id, $action, $options='')
openHere($style, $a=0, $b=0, $c=0)
o_encryption($id, $action, $options='')
getTextWidth($size, $text)