diff --git a/config/ftpanbindung.php b/config/ftpanbindung.php new file mode 100644 index 0000000..de7f01a --- /dev/null +++ b/config/ftpanbindung.php @@ -0,0 +1,5 @@ + diff --git a/controller/Directory_Backup_Service.php b/controller/Directory_Backup_Service.php new file mode 100644 index 0000000..0321efb --- /dev/null +++ b/controller/Directory_Backup_Service.php @@ -0,0 +1,120 @@ +"; +/** + * Directory_Backup_Service + * + * PHP5 Class Directory Backup + * Required: PHP 5 >= 5.1.2 + * + * @package Directory_Backup_Service + * @author Damir Enseleit + * @copyright 2013, SELFPHP OHG + * @license BSD License + * @version 1.0.0 + * @link http://www.selfphp.de + * + */ + +class Directory_Backup_Service { + + /** + * @var string ZIP-Format ('zip' , 'bzip2' , 'targz') + */ + private $zipFormat = "zip"; + + /** + * @var string Zeitstempel + */ + private $timeBackup = ""; + + /** + * @var string Upload Filename + */ + private $uploadFile = ""; + + /** + * FTP-Daten + */ + private $ftpUser = 'backup'; // FTP Username + private $ftpPasswd = '7655843'; // FTP Passwort + private $ftpHost = 'www.ja-schwarz.de'; // FTP Host + private $ftpPfad = '/backup/survey/'; // Pfad auf dem Backupserver mit führendem und endendem Slash! + + /** + * Constructor + */ + function __construct( ) { + + $this->timeBackup = date("Y-m-d_H-i-s"); + + } + + + + /** + * Backup komprimieren + */ + public function startBackup( $dateiName, $backupName ) { + + $tarName = $backupName . '_' . $this->timeBackup; + + + if ( $this->zipFormat == 'zip' ) + { + $tarName .= '.zip'; + $shellBefehl = "zip -r $tarName $dateiName"; + exec($shellBefehl, $output, $retval); +#echo "
"; +#echo "Rückgabe mit Status $retval und Ausgabe:\n"; +#print_r($output); +#echo ""; + } + else if($self_config['zipformat'] == "bzip2") + { + $tarName .= '.tar.bz2'; + $shellBefehl = "tar -jcf $tarName $dateiName && bzip2 $tarName"; + } + else + { + $tarName .= '.tar.gz'; + $shellBefehl = "tar -zcf $tarName $dateiName && gzip $tarName"; + } + + $this->uploadFile = $tarName; + + exec($shellBefehl); + + } + + + /** + * FTP-Upload starten + */ + public function curlUpload() { + + $fp = fopen($this->uploadFile, "r"); + $url = "ftp://".$this->ftpUser.":".$this->ftpPasswd."@". + $this->ftpHost.":21" .$this->ftpPfad.$this->uploadFile; + + $handle = curl_init(); + + curl_setopt($handle, CURLOPT_URL, $url); + curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($handle, CURLOPT_UPLOAD, 1); + curl_setopt($handle, CURLOPT_INFILE, $fp); + curl_setopt($handle, CURLOPT_INFILESIZE, filesize($this->uploadFile)); + + $result = curl_exec($handle); + + $info = curl_getinfo ($handle); + + curl_close($handle); + + return $info; + + } +} + +?> \ No newline at end of file diff --git a/controller/start_Directory_Backup_Service.php b/controller/start_Directory_Backup_Service.php new file mode 100644 index 0000000..6cc6f05 --- /dev/null +++ b/controller/start_Directory_Backup_Service.php @@ -0,0 +1,25 @@ + startBackup( '../../survey/', 'survey' ); + +// FTP-Upload starten +$infoF = $fileBackup->curlUpload( ); +$files = glob('./*.zip'); // get all zip file names +foreach($files as $file){ // iterate files + if(is_file($file)) { + unlink($file); // delete file + } +} + +echo 'Dateigröße: ' . $infoF['size_upload'] . '
1. What's exactly the license of FPDF? Are there any usage restrictions?
+FPDF is released under a permissive license: there is no usage restriction. You may embed it +freely in your application (commercial or not), with or without modifications. +2. I get the following error when I try to generate a PDF: Some data has already been output, can't send PDF file
+You must send nothing to the browser except the PDF itself: no HTML, no space, no carriage return. A common +case is having extra blank at the end of an included script file.ob_end_clean();
+3. Accented letters are replaced by some strange characters like é.
+Don't use UTF-8 with the standard fonts; they expect text encoded in windows-1252. +You can perform a conversion with iconv: +$str = iconv('UTF-8', 'windows-1252', $str);
+$str = mb_convert_encoding($str, 'windows-1252', 'UTF-8');
+4. I try to display the Euro symbol but it doesn't work.
+The standard fonts have the Euro character at position 128. You can define a constant like this +for convenience: +define('EURO', chr(128));
+5. I try to display a variable in the Header method but nothing prints.
+You have to use theglobal
keyword to access global variables, for example:
+function Header()
+{
+ global $title;
+
+ $this->SetFont('Arial', 'B', 15);
+ $this->Cell(0, 10, $title, 1, 1, 'C');
+}
+
+$title = 'My title';
+function Header()
+{
+ $this->SetFont('Arial', 'B', 15);
+ $this->Cell(0, 10, $this->title, 1, 1, 'C');
+}
+
+$pdf->title = 'My title';
+6. I have defined the Header and Footer methods in my PDF class but nothing shows.
+You have to create an object from the PDF class, not FPDF: +$pdf = new PDF();
+7. I can't make line breaks work. I put \n in the string printed by MultiCell but it doesn't work.
+You have to enclose your string with double quotes, not single ones. +8. I use jQuery to generate the PDF but it doesn't show.
+Don't use an AJAX request to retrieve the PDF. +9. I draw a frame with very precise dimensions, but when printed I notice some differences.
+To respect dimensions, select "None" for the Page Scaling setting instead of "Shrink to Printable Area" in the print dialog box. +10. I'd like to use the whole surface of the page, but when printed I always have some margins. How can I get rid of them?
+Printers have physical margins (different depending on the models); it is therefore impossible to remove +them and print on the whole surface of the paper. +11. How can I put a background in my PDF?
+For a picture, call Image() in the Header() method, before any other output. To set a background color, use Rect(). +12. How can I set a specific header or footer on the first page?
+Just test the page number: +function Header()
+{
+ if($this->PageNo()==1)
+ {
+ //First page
+ ...
+ }
+ else
+ {
+ //Other pages
+ ...
+ }
+}
+13. I'd like to use extensions provided by different scripts. How can I combine them?
+Use an inheritance chain. If you have two classes, say A in a.php: +require('fpdf.php');
+
+class A extends FPDF
+{
+...
+}
+require('fpdf.php');
+
+class B extends FPDF
+{
+...
+}
+require('a.php');
+
+class B extends A
+{
+...
+}
+require('b.php');
+
+class PDF extends B
+{
+...
+}
+
+$pdf = new PDF();
+14. How can I open the PDF in a new tab?
+Just do the same as you would for an HTML page or anything else: add a target="_blank" to your link or form. +15. How can I send the PDF by email?
+As for any other file, but an easy way is to use PHPMailer and +its in-memory attachment: +$mail = new PHPMailer();
+...
+$doc = $pdf->Output('S');
+$mail->AddStringAttachment($doc, 'doc.pdf', 'base64', 'application/pdf');
+$mail->Send();
+16. What's the limit of the file sizes I can generate with FPDF?
+There is no particular limit. There are some constraints, however: +17. Can I modify a PDF with FPDF?
+It's possible to import pages from an existing PDF document thanks to the +FPDI extension. +Then you can add some content to them. +18. I'd like to make a search engine in PHP and index PDF files. Can I do it with FPDF?
+No. But a GPL C utility does exist, pdftotext, which is able to extract the textual content from a PDF. +It's provided with the Xpdf package. +19. Can I convert an HTML page to PDF with FPDF?
+Not real-world pages. But a GPL C utility does exist, HTMLDOC, +which allows to do it and gives good results. +20. Can I concatenate PDF files with FPDF?
+Not directly, but it's possible to use FPDI +to perform that task. Some free command-line tools also exist: +pdftk and +mbtPdfAsm. +
+ * xref
+ * 1 7
+ * 0000000000 65535 f
+ * 0000000009 00000 n
+ * 0000412075 00000 n
+ * 0000412172 00000 n
+ * 0000412359 00000 n
+ * 0000412417 00000 n
+ * 0000412468 00000 n
+ *
+ *
+ * It shall only be called on the first table.
+ *
+ * @return bool
+ */
+ public function fixFaultySubSectionShift()
+ {
+ $subSections = $this->getSubSections();
+ if (\count($subSections) > 1) {
+ return false;
+ }
+
+ $subSection = \current($subSections);
+ if ($subSection[0] != 1) {
+ return false;
+ }
+
+ if ($this->getOffsetFor(1) === false) {
+ foreach ($subSections as $offset => list($startObject, $objectCount)) {
+ $this->subSections[$offset] = [$startObject - 1, $objectCount];
+ }
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/CrossReference/LineReader.php b/fpdf186/FPDI-master/src/PdfParser/CrossReference/LineReader.php
new file mode 100644
index 0000000..bcbd8e4
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/CrossReference/LineReader.php
@@ -0,0 +1,168 @@
+ 20 bytes).
+ */
+class LineReader extends AbstractReader implements ReaderInterface
+{
+ /**
+ * The object offsets.
+ *
+ * @var array
+ */
+ protected $offsets;
+
+ /**
+ * LineReader constructor.
+ *
+ * @param PdfParser $parser
+ * @throws CrossReferenceException
+ */
+ public function __construct(PdfParser $parser)
+ {
+ $this->read($this->extract($parser->getStreamReader()));
+ parent::__construct($parser);
+ }
+
+ /**
+ * @inheritdoc
+ * @return int|false
+ */
+ public function getOffsetFor($objectNumber)
+ {
+ if (isset($this->offsets[$objectNumber])) {
+ return $this->offsets[$objectNumber][0];
+ }
+
+ return false;
+ }
+
+ /**
+ * Get all found offsets.
+ *
+ * @return array
+ */
+ public function getOffsets()
+ {
+ return $this->offsets;
+ }
+
+ /**
+ * Extracts the cross reference data from the stream reader.
+ *
+ * @param StreamReader $reader
+ * @return string
+ * @throws CrossReferenceException
+ */
+ protected function extract(StreamReader $reader)
+ {
+ $bytesPerCycle = 100;
+ $reader->reset(null, $bytesPerCycle);
+
+ $cycles = 0;
+ do {
+ // 6 = length of "trailer" - 1
+ $pos = \max(($bytesPerCycle * $cycles) - 6, 0);
+ $trailerPos = \strpos($reader->getBuffer(false), 'trailer', $pos);
+ $cycles++;
+ } while ($trailerPos === false && $reader->increaseLength($bytesPerCycle) !== false);
+
+ if ($trailerPos === false) {
+ throw new CrossReferenceException(
+ 'Unexpected end of cross reference. "trailer"-keyword not found.',
+ CrossReferenceException::NO_TRAILER_FOUND
+ );
+ }
+
+ $xrefContent = \substr($reader->getBuffer(false), 0, $trailerPos);
+ $reader->reset($reader->getPosition() + $trailerPos);
+
+ return $xrefContent;
+ }
+
+ /**
+ * Read the cross-reference entries.
+ *
+ * @param string $xrefContent
+ * @throws CrossReferenceException
+ */
+ protected function read($xrefContent)
+ {
+ // get eol markers in the first 100 bytes
+ \preg_match_all("/(\r\n|\n|\r)/", \substr($xrefContent, 0, 100), $m);
+
+ if (\count($m[0]) === 0) {
+ throw new CrossReferenceException(
+ 'No data found in cross-reference.',
+ CrossReferenceException::INVALID_DATA
+ );
+ }
+
+ // count(array_count_values()) is faster then count(array_unique())
+ // @see https://github.com/symfony/symfony/pull/23731
+ // can be reverted for php7.2
+ $differentLineEndings = \count(\array_count_values($m[0]));
+ if ($differentLineEndings > 1) {
+ $lines = \preg_split("/(\r\n|\n|\r)/", $xrefContent, -1, PREG_SPLIT_NO_EMPTY);
+ } else {
+ $lines = \explode($m[0][0], $xrefContent);
+ }
+
+ unset($differentLineEndings, $m);
+ if (!\is_array($lines)) {
+ $this->offsets = [];
+ return;
+ }
+
+ $start = 0;
+ $offsets = [];
+
+ // trim all lines and remove empty lines
+ $lines = \array_filter(\array_map('\trim', $lines));
+ foreach ($lines as $line) {
+ $pieces = \explode(' ', $line);
+
+ switch (\count($pieces)) {
+ case 2:
+ $start = (int) $pieces[0];
+ break;
+
+ case 3:
+ switch ($pieces[2]) {
+ case 'n':
+ $offsets[$start] = [(int) $pieces[0], (int) $pieces[1]];
+ $start++;
+ break 2;
+ case 'f':
+ $start++;
+ break 2;
+ }
+ // fall through if pieces doesn't match
+
+ default:
+ throw new CrossReferenceException(
+ \sprintf('Unexpected data in xref table (%s)', \implode(' ', $pieces)),
+ CrossReferenceException::INVALID_DATA
+ );
+ }
+ }
+
+ $this->offsets = $offsets;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/CrossReference/ReaderInterface.php b/fpdf186/FPDI-master/src/PdfParser/CrossReference/ReaderInterface.php
new file mode 100644
index 0000000..0bdc0ab
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/CrossReference/ReaderInterface.php
@@ -0,0 +1,34 @@
+
+ if ($ch === 126 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 62) {
+ break;
+ }
+
+ if ($ch === 122 /* z */ && $state === 0) {
+ $out .= \chr(0) . \chr(0) . \chr(0) . \chr(0);
+ continue;
+ }
+
+ if ($ch < 33 /* ! */ || $ch > 117 /* u */) {
+ throw new Ascii85Exception(
+ 'Illegal character found while ASCII85 decode.',
+ Ascii85Exception::ILLEGAL_CHAR_FOUND
+ );
+ }
+
+ $chn[$state] = $ch - 33;/* ! */
+ $state++;
+
+ if ($state === 5) {
+ $state = 0;
+ $r = 0;
+ for ($j = 0; $j < 5; ++$j) {
+ /** @noinspection UnnecessaryCastingInspection */
+ $r = (int)($r * 85 + $chn[$j]);
+ }
+
+ $out .= \chr($r >> 24)
+ . \chr($r >> 16)
+ . \chr($r >> 8)
+ . \chr($r);
+ }
+ }
+
+ if ($state === 1) {
+ throw new Ascii85Exception(
+ 'Illegal length while ASCII85 decode.',
+ Ascii85Exception::ILLEGAL_LENGTH
+ );
+ }
+
+ if ($state === 2) {
+ $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1] + 1) * 85 * 85 * 85;
+ $out .= \chr($r >> 24);
+ } elseif ($state === 3) {
+ $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2] + 1) * 85 * 85;
+ $out .= \chr($r >> 24);
+ $out .= \chr($r >> 16);
+ } elseif ($state === 4) {
+ $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3] + 1) * 85;
+ $out .= \chr($r >> 24);
+ $out .= \chr($r >> 16);
+ $out .= \chr($r >> 8);
+ }
+
+ return $out;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Filter/Ascii85Exception.php b/fpdf186/FPDI-master/src/PdfParser/Filter/Ascii85Exception.php
new file mode 100644
index 0000000..83a780c
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Filter/Ascii85Exception.php
@@ -0,0 +1,27 @@
+'));
+ if ((\strlen($data) % 2) === 1) {
+ $data .= '0';
+ }
+
+ return \pack('H*', $data);
+ }
+
+ /**
+ * Converts a string into ASCII hexadecimal representation.
+ *
+ * @param string $data The input string
+ * @param boolean $leaveEOD
+ * @return string
+ */
+ public function encode($data, $leaveEOD = false)
+ {
+ $t = \unpack('H*', $data);
+ return \current($t)
+ . ($leaveEOD ? '' : '>');
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Filter/FilterException.php b/fpdf186/FPDI-master/src/PdfParser/Filter/FilterException.php
new file mode 100644
index 0000000..c71ff38
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Filter/FilterException.php
@@ -0,0 +1,23 @@
+extensionLoaded()) {
+ $oData = $data;
+ $data = (($data !== '') ? @\gzuncompress($data) : '');
+ if ($data === false) {
+ // let's try if the checksum is CRC32
+ $fh = fopen('php://temp', 'w+b');
+ fwrite($fh, "\x1f\x8b\x08\x00\x00\x00\x00\x00" . $oData);
+ // "window" == 31 -> 16 + (8 to 15): Uses the low 4 bits of the value as the window size logarithm.
+ // The input must include a gzip header and trailer (via 16).
+ stream_filter_append($fh, 'zlib.inflate', STREAM_FILTER_READ, ['window' => 31]);
+ fseek($fh, 0);
+ $data = @stream_get_contents($fh);
+ fclose($fh);
+
+ if ($data) {
+ return $data;
+ }
+
+ // Try this fallback
+ $tries = 0;
+
+ $oDataLen = strlen($oData);
+ while ($tries < 6 && ($data === false || (strlen($data) < ($oDataLen - $tries - 1)))) {
+ $data = @(gzinflate(substr($oData, $tries)));
+ $tries++;
+ }
+
+ // let's use this fallback only if the $data is longer than the original data
+ if (strlen($data) > ($oDataLen - $tries - 1)) {
+ return $data;
+ }
+
+ if (!$data) {
+ throw new FlateException(
+ 'Error while decompressing stream.',
+ FlateException::DECOMPRESS_ERROR
+ );
+ }
+ }
+ } else {
+ throw new FlateException(
+ 'To handle FlateDecode filter, enable zlib support in PHP.',
+ FlateException::NO_ZLIB
+ );
+ }
+
+ return $data;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Filter/FlateException.php b/fpdf186/FPDI-master/src/PdfParser/Filter/FlateException.php
new file mode 100644
index 0000000..7791ca7
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Filter/FlateException.php
@@ -0,0 +1,27 @@
+initsTable();
+
+ $this->data = $data;
+ $this->dataLength = \strlen($data);
+
+ // Initialize pointers
+ $this->bytePointer = 0;
+
+ $this->nextData = 0;
+ $this->nextBits = 0;
+
+ $prevCode = 0;
+
+ $uncompData = '';
+
+ while (($code = $this->getNextCode()) !== 257) {
+ if ($code === 256) {
+ $this->initsTable();
+ } elseif ($prevCode === 256) {
+ $uncompData .= $this->sTable[$code];
+ } elseif ($code < $this->tIdx) {
+ $string = $this->sTable[$code];
+ $uncompData .= $string;
+
+ $this->addStringToTable($this->sTable[$prevCode], $string[0]);
+ } else {
+ $string = $this->sTable[$prevCode];
+ $string .= $string[0];
+ $uncompData .= $string;
+
+ $this->addStringToTable($string);
+ }
+ $prevCode = $code;
+ }
+
+ return $uncompData;
+ }
+
+ /**
+ * Initialize the string table.
+ */
+ protected function initsTable()
+ {
+ $this->sTable = [];
+
+ for ($i = 0; $i < 256; $i++) {
+ $this->sTable[$i] = \chr($i);
+ }
+
+ $this->tIdx = 258;
+ $this->bitsToGet = 9;
+ }
+
+ /**
+ * Add a new string to the string table.
+ *
+ * @param string $oldString
+ * @param string $newString
+ */
+ protected function addStringToTable($oldString, $newString = '')
+ {
+ $string = $oldString . $newString;
+
+ // Add this new String to the table
+ $this->sTable[$this->tIdx++] = $string;
+
+ if ($this->tIdx === 511) {
+ $this->bitsToGet = 10;
+ } elseif ($this->tIdx === 1023) {
+ $this->bitsToGet = 11;
+ } elseif ($this->tIdx === 2047) {
+ $this->bitsToGet = 12;
+ }
+ }
+
+ /**
+ * Returns the next 9, 10, 11 or 12 bits.
+ *
+ * @return int
+ */
+ protected function getNextCode()
+ {
+ if ($this->bytePointer === $this->dataLength) {
+ return 257;
+ }
+
+ $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff);
+ $this->nextBits += 8;
+
+ if ($this->nextBits < $this->bitsToGet) {
+ $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff);
+ $this->nextBits += 8;
+ }
+
+ $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet - 9];
+ $this->nextBits -= $this->bitsToGet;
+
+ return $code;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Filter/LzwException.php b/fpdf186/FPDI-master/src/PdfParser/Filter/LzwException.php
new file mode 100644
index 0000000..9f42038
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Filter/LzwException.php
@@ -0,0 +1,22 @@
+streamReader = $streamReader;
+ $this->tokenizer = new Tokenizer($streamReader);
+ }
+
+ /**
+ * Removes cycled references.
+ *
+ * @internal
+ */
+ public function cleanUp()
+ {
+ $this->xref = null;
+ }
+
+ /**
+ * Get the stream reader instance.
+ *
+ * @return StreamReader
+ */
+ public function getStreamReader()
+ {
+ return $this->streamReader;
+ }
+
+ /**
+ * Get the tokenizer instance.
+ *
+ * @return Tokenizer
+ */
+ public function getTokenizer()
+ {
+ return $this->tokenizer;
+ }
+
+ /**
+ * Resolves the file header.
+ *
+ * @throws PdfParserException
+ * @return int
+ */
+ protected function resolveFileHeader()
+ {
+ if ($this->fileHeader) {
+ return $this->fileHeaderOffset;
+ }
+
+ $this->streamReader->reset(0);
+ $maxIterations = 1000;
+ while (true) {
+ $buffer = $this->streamReader->getBuffer(false);
+ $offset = \strpos($buffer, '%PDF-');
+ if ($offset === false) {
+ if (!$this->streamReader->increaseLength(100) || (--$maxIterations === 0)) {
+ throw new PdfParserException(
+ 'Unable to find PDF file header.',
+ PdfParserException::FILE_HEADER_NOT_FOUND
+ );
+ }
+ continue;
+ }
+ break;
+ }
+
+ $this->fileHeaderOffset = $offset;
+ $this->streamReader->setOffset($offset);
+
+ $this->fileHeader = \trim($this->streamReader->readLine());
+ return $this->fileHeaderOffset;
+ }
+
+ /**
+ * Get the cross-reference instance.
+ *
+ * @return CrossReference
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public function getCrossReference()
+ {
+ if ($this->xref === null) {
+ $this->xref = new CrossReference($this, $this->resolveFileHeader());
+ }
+
+ return $this->xref;
+ }
+
+ /**
+ * Get the PDF version.
+ *
+ * @return int[] An array of major and minor version.
+ * @throws PdfParserException
+ */
+ public function getPdfVersion()
+ {
+ $this->resolveFileHeader();
+
+ if (\preg_match('/%PDF-(\d)\.(\d)/', $this->fileHeader, $result) === 0) {
+ throw new PdfParserException(
+ 'Unable to extract PDF version from file header.',
+ PdfParserException::PDF_VERSION_NOT_FOUND
+ );
+ }
+ list(, $major, $minor) = $result;
+
+ $catalog = $this->getCatalog();
+ if (isset($catalog->value['Version'])) {
+ $versionParts = \explode(
+ '.',
+ PdfName::unescape(PdfType::resolve($catalog->value['Version'], $this)->value)
+ );
+ if (count($versionParts) === 2) {
+ list($major, $minor) = $versionParts;
+ }
+ }
+
+ return [(int) $major, (int) $minor];
+ }
+
+ /**
+ * Get the catalog dictionary.
+ *
+ * @return PdfDictionary
+ * @throws Type\PdfTypeException
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public function getCatalog()
+ {
+ $trailer = $this->getCrossReference()->getTrailer();
+
+ $catalog = PdfType::resolve(PdfDictionary::get($trailer, 'Root'), $this);
+
+ return PdfDictionary::ensure($catalog);
+ }
+
+ /**
+ * Get an indirect object by its object number.
+ *
+ * @param int $objectNumber
+ * @param bool $cache
+ * @return PdfIndirectObject
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public function getIndirectObject($objectNumber, $cache = false)
+ {
+ $objectNumber = (int) $objectNumber;
+ if (isset($this->objects[$objectNumber])) {
+ return $this->objects[$objectNumber];
+ }
+
+ $object = $this->getCrossReference()->getIndirectObject($objectNumber);
+
+ if ($cache) {
+ $this->objects[$objectNumber] = $object;
+ }
+
+ return $object;
+ }
+
+ /**
+ * Read a PDF value.
+ *
+ * @param null|bool|string $token
+ * @param null|string $expectedType
+ * @return false|PdfArray|PdfBoolean|PdfDictionary|PdfHexString|PdfIndirectObject|PdfIndirectObjectReference|PdfName|PdfNull|PdfNumeric|PdfStream|PdfString|PdfToken
+ * @throws Type\PdfTypeException
+ */
+ public function readValue($token = null, $expectedType = null)
+ {
+ if ($token === null) {
+ $token = $this->tokenizer->getNextToken();
+ }
+
+ if ($token === false) {
+ if ($expectedType !== null) {
+ throw new Type\PdfTypeException('Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE);
+ }
+ return false;
+ }
+
+ switch ($token) {
+ case '(':
+ $this->ensureExpectedType($token, $expectedType);
+ return PdfString::parse($this->streamReader);
+
+ case '<':
+ if ($this->streamReader->getByte() === '<') {
+ $this->ensureExpectedType('<<', $expectedType);
+ $this->streamReader->addOffset(1);
+ return PdfDictionary::parse($this->tokenizer, $this->streamReader, $this);
+ }
+
+ $this->ensureExpectedType($token, $expectedType);
+ return PdfHexString::parse($this->streamReader);
+
+ case '/':
+ $this->ensureExpectedType($token, $expectedType);
+ return PdfName::parse($this->tokenizer, $this->streamReader);
+
+ case '[':
+ $this->ensureExpectedType($token, $expectedType);
+ return PdfArray::parse($this->tokenizer, $this);
+
+ default:
+ if (\is_numeric($token)) {
+ if (($token2 = $this->tokenizer->getNextToken()) !== false) {
+ if (\is_numeric($token2) && ($token3 = $this->tokenizer->getNextToken()) !== false) {
+ switch ($token3) {
+ case 'obj':
+ if ($expectedType !== null && $expectedType !== PdfIndirectObject::class) {
+ throw new Type\PdfTypeException(
+ 'Got unexpected token type.',
+ Type\PdfTypeException::INVALID_DATA_TYPE
+ );
+ }
+
+ return PdfIndirectObject::parse(
+ (int) $token,
+ (int) $token2,
+ $this,
+ $this->tokenizer,
+ $this->streamReader
+ );
+ case 'R':
+ if (
+ $expectedType !== null &&
+ $expectedType !== PdfIndirectObjectReference::class
+ ) {
+ throw new Type\PdfTypeException(
+ 'Got unexpected token type.',
+ Type\PdfTypeException::INVALID_DATA_TYPE
+ );
+ }
+
+ return PdfIndirectObjectReference::create((int) $token, (int) $token2);
+ }
+
+ $this->tokenizer->pushStack($token3);
+ }
+
+ $this->tokenizer->pushStack($token2);
+ }
+
+ if ($expectedType !== null && $expectedType !== PdfNumeric::class) {
+ throw new Type\PdfTypeException(
+ 'Got unexpected token type.',
+ Type\PdfTypeException::INVALID_DATA_TYPE
+ );
+ }
+ return PdfNumeric::create($token + 0);
+ }
+
+ if ($token === 'true' || $token === 'false') {
+ $this->ensureExpectedType($token, $expectedType);
+ return PdfBoolean::create($token === 'true');
+ }
+
+ if ($token === 'null') {
+ $this->ensureExpectedType($token, $expectedType);
+ return new PdfNull();
+ }
+
+ if ($expectedType !== null && $expectedType !== PdfToken::class) {
+ throw new Type\PdfTypeException(
+ 'Got unexpected token type.',
+ Type\PdfTypeException::INVALID_DATA_TYPE
+ );
+ }
+
+ $v = new PdfToken();
+ $v->value = $token;
+
+ return $v;
+ }
+ }
+
+ /**
+ * Ensures that the token will evaluate to an expected object type (or not).
+ *
+ * @param string $token
+ * @param string|null $expectedType
+ * @return bool
+ * @throws Type\PdfTypeException
+ */
+ private function ensureExpectedType($token, $expectedType)
+ {
+ static $mapping = [
+ '(' => PdfString::class,
+ '<' => PdfHexString::class,
+ '<<' => PdfDictionary::class,
+ '/' => PdfName::class,
+ '[' => PdfArray::class,
+ 'true' => PdfBoolean::class,
+ 'false' => PdfBoolean::class,
+ 'null' => PdfNull::class
+ ];
+
+ if ($expectedType === null || $mapping[$token] === $expectedType) {
+ return true;
+ }
+
+ throw new Type\PdfTypeException('Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE);
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/PdfParserException.php b/fpdf186/FPDI-master/src/PdfParser/PdfParserException.php
new file mode 100644
index 0000000..0629d9d
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/PdfParserException.php
@@ -0,0 +1,49 @@
+stream = $stream;
+ $this->closeStream = $closeStream;
+ $this->reset();
+ }
+
+ /**
+ * The destructor.
+ */
+ public function __destruct()
+ {
+ $this->cleanUp();
+ }
+
+ /**
+ * Closes the file handle.
+ */
+ public function cleanUp()
+ {
+ if ($this->closeStream && is_resource($this->stream)) {
+ \fclose($this->stream);
+ }
+ }
+
+ /**
+ * Returns the byte length of the buffer.
+ *
+ * @param bool $atOffset
+ * @return int
+ */
+ public function getBufferLength($atOffset = false)
+ {
+ if ($atOffset === false) {
+ return $this->bufferLength;
+ }
+
+ return $this->bufferLength - $this->offset;
+ }
+
+ /**
+ * Get the current position in the stream.
+ *
+ * @return int
+ */
+ public function getPosition()
+ {
+ return $this->position;
+ }
+
+ /**
+ * Returns the current buffer.
+ *
+ * @param bool $atOffset
+ * @return string
+ */
+ public function getBuffer($atOffset = true)
+ {
+ if ($atOffset === false) {
+ return $this->buffer;
+ }
+
+ $string = \substr($this->buffer, $this->offset);
+
+ return (string) $string;
+ }
+
+ /**
+ * Gets a byte at a specific position in the buffer.
+ *
+ * If the position is invalid the method will return false.
+ *
+ * If the $position parameter is set to null the value of $this->offset will be used.
+ *
+ * @param int|null $position
+ * @return string|bool
+ */
+ public function getByte($position = null)
+ {
+ $position = (int) ($position !== null ? $position : $this->offset);
+ if (
+ $position >= $this->bufferLength
+ && (!$this->increaseLength() || $position >= $this->bufferLength)
+ ) {
+ return false;
+ }
+
+ return $this->buffer[$position];
+ }
+
+ /**
+ * Returns a byte at a specific position, and set the offset to the next byte position.
+ *
+ * If the position is invalid the method will return false.
+ *
+ * If the $position parameter is set to null the value of $this->offset will be used.
+ *
+ * @param int|null $position
+ * @return string|bool
+ */
+ public function readByte($position = null)
+ {
+ if ($position !== null) {
+ $position = (int) $position;
+ // check if needed bytes are available in the current buffer
+ if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) {
+ $this->reset($position);
+ $offset = $this->offset;
+ } else {
+ $offset = $position - $this->position;
+ }
+ } else {
+ $offset = $this->offset;
+ }
+
+ if (
+ $offset >= $this->bufferLength
+ && ((!$this->increaseLength()) || $offset >= $this->bufferLength)
+ ) {
+ return false;
+ }
+
+ $this->offset = $offset + 1;
+ return $this->buffer[$offset];
+ }
+
+ /**
+ * Read bytes from the current or a specific offset position and set the internal pointer to the next byte.
+ *
+ * If the position is invalid the method will return false.
+ *
+ * If the $position parameter is set to null the value of $this->offset will be used.
+ *
+ * @param int $length
+ * @param int|null $position
+ * @return string|false
+ */
+ public function readBytes($length, $position = null)
+ {
+ $length = (int) $length;
+ if ($position !== null) {
+ // check if needed bytes are available in the current buffer
+ if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) {
+ $this->reset($position, $length);
+ $offset = $this->offset;
+ } else {
+ $offset = $position - $this->position;
+ }
+ } else {
+ $offset = $this->offset;
+ }
+
+ if (
+ ($offset + $length) > $this->bufferLength
+ && ((!$this->increaseLength($length)) || ($offset + $length) > $this->bufferLength)
+ ) {
+ return false;
+ }
+
+ $bytes = \substr($this->buffer, $offset, $length);
+ $this->offset = $offset + $length;
+
+ return $bytes;
+ }
+
+ /**
+ * Read a line from the current position.
+ *
+ * @param int $length
+ * @return string|bool
+ */
+ public function readLine($length = 1024)
+ {
+ if ($this->ensureContent() === false) {
+ return false;
+ }
+
+ $line = '';
+ while ($this->ensureContent()) {
+ $char = $this->readByte();
+
+ if ($char === "\n") {
+ break;
+ }
+
+ if ($char === "\r") {
+ if ($this->getByte() === "\n") {
+ $this->addOffset(1);
+ }
+ break;
+ }
+
+ $line .= $char;
+
+ if (\strlen($line) >= $length) {
+ break;
+ }
+ }
+
+ return $line;
+ }
+
+ /**
+ * Set the offset position in the current buffer.
+ *
+ * @param int $offset
+ */
+ public function setOffset($offset)
+ {
+ if ($offset > $this->bufferLength || $offset < 0) {
+ throw new \OutOfRangeException(
+ \sprintf('Offset (%s) out of range (length: %s)', $offset, $this->bufferLength)
+ );
+ }
+
+ $this->offset = (int) $offset;
+ }
+
+ /**
+ * Returns the current offset in the current buffer.
+ *
+ * @return int
+ */
+ public function getOffset()
+ {
+ return $this->offset;
+ }
+
+ /**
+ * Add an offset to the current offset.
+ *
+ * @param int $offset
+ */
+ public function addOffset($offset)
+ {
+ $this->setOffset($this->offset + $offset);
+ }
+
+ /**
+ * Make sure that there is at least one character beyond the current offset in the buffer.
+ *
+ * @return bool
+ */
+ public function ensureContent()
+ {
+ while ($this->offset >= $this->bufferLength) {
+ if (!$this->increaseLength()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the stream.
+ *
+ * @return resource
+ */
+ public function getStream()
+ {
+ return $this->stream;
+ }
+
+ /**
+ * Gets the total available length.
+ *
+ * @return int
+ */
+ public function getTotalLength()
+ {
+ if ($this->totalLength === null) {
+ $stat = \fstat($this->stream);
+ $this->totalLength = $stat['size'];
+ }
+
+ return $this->totalLength;
+ }
+
+ /**
+ * Resets the buffer to a position and re-read the buffer with the given length.
+ *
+ * If the $pos parameter is negative the start buffer position will be the $pos'th position from
+ * the end of the file.
+ *
+ * If the $pos parameter is negative and the absolute value is bigger then the totalLength of
+ * the file $pos will set to zero.
+ *
+ * @param int|null $pos Start position of the new buffer
+ * @param int $length Length of the new buffer. Mustn't be negative
+ */
+ public function reset($pos = 0, $length = 200)
+ {
+ if ($pos === null) {
+ $pos = $this->position + $this->offset;
+ } elseif ($pos < 0) {
+ $pos = \max(0, $this->getTotalLength() + $pos);
+ }
+
+ \fseek($this->stream, $pos);
+
+ $this->position = $pos;
+ $this->buffer = $length > 0 ? \fread($this->stream, $length) : '';
+ $this->bufferLength = \strlen($this->buffer);
+ $this->offset = 0;
+
+ // If a stream wrapper is in use it is possible that
+ // length values > 8096 will be ignored, so use the
+ // increaseLength()-method to correct that behavior
+ if ($this->bufferLength < $length && $this->increaseLength($length - $this->bufferLength)) {
+ // increaseLength parameter is $minLength, so cut to have only the required bytes in the buffer
+ $this->buffer = \substr($this->buffer, 0, $length);
+ $this->bufferLength = \strlen($this->buffer);
+ }
+ }
+
+ /**
+ * Ensures bytes in the buffer with a specific length and location in the file.
+ *
+ * @param int $pos
+ * @param int $length
+ * @see reset()
+ */
+ public function ensure($pos, $length)
+ {
+ if (
+ $pos >= $this->position
+ && $pos < ($this->position + $this->bufferLength)
+ && ($this->position + $this->bufferLength) >= ($pos + $length)
+ ) {
+ $this->offset = $pos - $this->position;
+ } else {
+ $this->reset($pos, $length);
+ }
+ }
+
+ /**
+ * Forcefully read more data into the buffer.
+ *
+ * @param int $minLength
+ * @return bool Returns false if the stream reaches the end
+ */
+ public function increaseLength($minLength = 100)
+ {
+ $length = \max($minLength, 100);
+
+ if (\feof($this->stream) || $this->getTotalLength() === $this->position + $this->bufferLength) {
+ return false;
+ }
+
+ $newLength = $this->bufferLength + $length;
+ do {
+ $this->buffer .= \fread($this->stream, $newLength - $this->bufferLength);
+ $this->bufferLength = \strlen($this->buffer);
+ } while (($this->bufferLength !== $newLength) && !\feof($this->stream));
+
+ return true;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Tokenizer.php b/fpdf186/FPDI-master/src/PdfParser/Tokenizer.php
new file mode 100644
index 0000000..5c1ccd8
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Tokenizer.php
@@ -0,0 +1,154 @@
+streamReader = $streamReader;
+ }
+
+ /**
+ * Get the stream reader instance.
+ *
+ * @return StreamReader
+ */
+ public function getStreamReader()
+ {
+ return $this->streamReader;
+ }
+
+ /**
+ * Clear the token stack.
+ */
+ public function clearStack()
+ {
+ $this->stack = [];
+ }
+
+ /**
+ * Push a token onto the stack.
+ *
+ * @param string $token
+ */
+ public function pushStack($token)
+ {
+ $this->stack[] = $token;
+ }
+
+ /**
+ * Get next token.
+ *
+ * @return bool|string
+ */
+ public function getNextToken()
+ {
+ $token = \array_pop($this->stack);
+ if ($token !== null) {
+ return $token;
+ }
+
+ if (($byte = $this->streamReader->readByte()) === false) {
+ return false;
+ }
+
+ if (\in_array($byte, ["\x20", "\x0A", "\x0D", "\x0C", "\x09", "\x00"], true)) {
+ if ($this->leapWhiteSpaces() === false) {
+ return false;
+ }
+ $byte = $this->streamReader->readByte();
+ }
+
+ switch ($byte) {
+ case '/':
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '<':
+ case '>':
+ return $byte;
+ case '%':
+ $this->streamReader->readLine();
+ return $this->getNextToken();
+ }
+
+ /* This way is faster than checking single bytes.
+ */
+ $bufferOffset = $this->streamReader->getOffset();
+ do {
+ $lastBuffer = $this->streamReader->getBuffer(false);
+ $pos = \strcspn(
+ $lastBuffer,
+ "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%",
+ $bufferOffset
+ );
+ } while (
+ // Break the loop if a delimiter or white space char is matched
+ // in the current buffer or increase the buffers length
+ $lastBuffer !== false &&
+ (
+ $bufferOffset + $pos === \strlen($lastBuffer) &&
+ $this->streamReader->increaseLength()
+ )
+ );
+
+ $result = \substr($lastBuffer, $bufferOffset - 1, $pos + 1);
+ $this->streamReader->setOffset($bufferOffset + $pos);
+
+ return $result;
+ }
+
+ /**
+ * Leap white spaces.
+ *
+ * @return boolean
+ */
+ public function leapWhiteSpaces()
+ {
+ do {
+ if (!$this->streamReader->ensureContent()) {
+ return false;
+ }
+
+ $buffer = $this->streamReader->getBuffer(false);
+ $matches = \strspn($buffer, "\x20\x0A\x0C\x0D\x09\x00", $this->streamReader->getOffset());
+ if ($matches > 0) {
+ $this->streamReader->addOffset($matches);
+ }
+ } while ($this->streamReader->getOffset() >= $this->streamReader->getBufferLength());
+
+ return true;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfArray.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfArray.php
new file mode 100644
index 0000000..33c6bc4
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfArray.php
@@ -0,0 +1,85 @@
+getNextToken()) !== ']') {
+ if ($token === false || ($value = $parser->readValue($token)) === false) {
+ return false;
+ }
+
+ $result[] = $value;
+ }
+
+ $v = new self();
+ $v->value = $result;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param PdfType[] $values
+ * @return self
+ */
+ public static function create(array $values = [])
+ {
+ $v = new self();
+ $v->value = $values;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed array is a PdfArray instance with a (optional) specific size.
+ *
+ * @param mixed $array
+ * @param null|int $size
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($array, $size = null)
+ {
+ $result = PdfType::ensureType(self::class, $array, 'Array value expected.');
+
+ if ($size !== null && \count($array->value) !== $size) {
+ throw new PdfTypeException(
+ \sprintf('Array with %s entries expected.', $size),
+ PdfTypeException::INVALID_DATA_SIZE
+ );
+ }
+
+ return $result;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfBoolean.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfBoolean.php
new file mode 100644
index 0000000..ad7c5d6
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfBoolean.php
@@ -0,0 +1,42 @@
+value = (bool) $value;
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfBoolean instance.
+ *
+ * @param mixed $value
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($value)
+ {
+ return PdfType::ensureType(self::class, $value, 'Boolean value expected.');
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfDictionary.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfDictionary.php
new file mode 100644
index 0000000..8991322
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfDictionary.php
@@ -0,0 +1,134 @@
+getNextToken();
+ if ($token === '>' && $streamReader->getByte() === '>') {
+ $streamReader->addOffset(1);
+ break;
+ }
+
+ $key = $parser->readValue($token);
+ if ($key === false) {
+ return false;
+ }
+
+ // ensure the first value to be a Name object
+ if (!($key instanceof PdfName)) {
+ $lastToken = null;
+ // ignore all other entries and search for the closing brackets
+ while (($token = $tokenizer->getNextToken()) !== '>' && $token !== false && $lastToken !== '>') {
+ $lastToken = $token;
+ }
+
+ if ($token === false) {
+ return false;
+ }
+
+ break;
+ }
+
+
+ $value = $parser->readValue();
+ if ($value === false) {
+ return false;
+ }
+
+ if ($value instanceof PdfNull) {
+ continue;
+ }
+
+ // catch missing value
+ if ($value instanceof PdfToken && $value->value === '>' && $streamReader->getByte() === '>') {
+ $streamReader->addOffset(1);
+ break;
+ }
+
+ $entries[$key->value] = $value;
+ }
+
+ $v = new self();
+ $v->value = $entries;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param PdfType[] $entries The keys are the name entries of the dictionary.
+ * @return self
+ */
+ public static function create(array $entries = [])
+ {
+ $v = new self();
+ $v->value = $entries;
+
+ return $v;
+ }
+
+ /**
+ * Get a value by its key from a dictionary or a default value.
+ *
+ * @param mixed $dictionary
+ * @param string $key
+ * @param PdfType|null $default
+ * @return PdfNull|PdfType
+ * @throws PdfTypeException
+ */
+ public static function get($dictionary, $key, PdfType $default = null)
+ {
+ $dictionary = self::ensure($dictionary);
+
+ if (isset($dictionary->value[$key])) {
+ return $dictionary->value[$key];
+ }
+
+ return $default === null
+ ? new PdfNull()
+ : $default;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfDictionary instance.
+ *
+ * @param mixed $dictionary
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($dictionary)
+ {
+ return PdfType::ensureType(self::class, $dictionary, 'Dictionary value expected.');
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfHexString.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfHexString.php
new file mode 100644
index 0000000..86694b0
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfHexString.php
@@ -0,0 +1,77 @@
+getOffset();
+
+ while (true) {
+ $buffer = $streamReader->getBuffer(false);
+ $pos = \strpos($buffer, '>', $bufferOffset);
+ if ($pos === false) {
+ if (!$streamReader->increaseLength()) {
+ return false;
+ }
+ continue;
+ }
+
+ break;
+ }
+
+ $result = \substr($buffer, $bufferOffset, $pos - $bufferOffset);
+ $streamReader->setOffset($pos + 1);
+
+ $v = new self();
+ $v->value = $result;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param string $string The hex encoded string.
+ * @return self
+ */
+ public static function create($string)
+ {
+ $v = new self();
+ $v->value = $string;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfHexString instance.
+ *
+ * @param mixed $hexString
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($hexString)
+ {
+ return PdfType::ensureType(self::class, $hexString, 'Hex string value expected.');
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfIndirectObject.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfIndirectObject.php
new file mode 100644
index 0000000..8b7898f
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfIndirectObject.php
@@ -0,0 +1,103 @@
+readValue();
+ if ($value === false) {
+ return false;
+ }
+
+ $nextToken = $tokenizer->getNextToken();
+ if ($nextToken === 'stream') {
+ $value = PdfStream::parse($value, $reader, $parser);
+ } elseif ($nextToken !== false) {
+ $tokenizer->pushStack($nextToken);
+ }
+
+ $v = new self();
+ $v->objectNumber = (int) $objectNumberToken;
+ $v->generationNumber = (int) $objectGenerationNumberToken;
+ $v->value = $value;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param int $objectNumber
+ * @param int $generationNumber
+ * @param PdfType $value
+ * @return self
+ */
+ public static function create($objectNumber, $generationNumber, PdfType $value)
+ {
+ $v = new self();
+ $v->objectNumber = (int) $objectNumber;
+ $v->generationNumber = (int) $generationNumber;
+ $v->value = $value;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfIndirectObject instance.
+ *
+ * @param mixed $indirectObject
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($indirectObject)
+ {
+ return PdfType::ensureType(self::class, $indirectObject, 'Indirect object expected.');
+ }
+
+ /**
+ * The object number.
+ *
+ * @var int
+ */
+ public $objectNumber;
+
+ /**
+ * The generation number.
+ *
+ * @var int
+ */
+ public $generationNumber;
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfIndirectObjectReference.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfIndirectObjectReference.php
new file mode 100644
index 0000000..975e9e8
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfIndirectObjectReference.php
@@ -0,0 +1,52 @@
+value = (int) $objectNumber;
+ $v->generationNumber = (int) $generationNumber;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfIndirectObject instance.
+ *
+ * @param mixed $value
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($value)
+ {
+ return PdfType::ensureType(self::class, $value, 'Indirect reference value expected.');
+ }
+
+ /**
+ * The generation number.
+ *
+ * @var int
+ */
+ public $generationNumber;
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfName.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfName.php
new file mode 100644
index 0000000..0fbfe52
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfName.php
@@ -0,0 +1,82 @@
+getByte(), "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%") === 0) {
+ $v->value = (string) $tokenizer->getNextToken();
+ return $v;
+ }
+
+ $v->value = '';
+ return $v;
+ }
+
+ /**
+ * Unescapes a name string.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function unescape($value)
+ {
+ if (strpos($value, '#') === false) {
+ return $value;
+ }
+
+ return preg_replace_callback('/#([a-fA-F\d]{2})/', function ($matches) {
+ return chr(hexdec($matches[1]));
+ }, $value);
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param string $string
+ * @return self
+ */
+ public static function create($string)
+ {
+ $v = new self();
+ $v->value = $string;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfName instance.
+ *
+ * @param mixed $name
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($name)
+ {
+ return PdfType::ensureType(self::class, $name, 'Name value expected.');
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfNull.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfNull.php
new file mode 100644
index 0000000..4830564
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfNull.php
@@ -0,0 +1,19 @@
+value = $value + 0;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfNumeric instance.
+ *
+ * @param mixed $value
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($value)
+ {
+ return PdfType::ensureType(self::class, $value, 'Numeric value expected.');
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfStream.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfStream.php
new file mode 100644
index 0000000..f72114e
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfStream.php
@@ -0,0 +1,321 @@
+value = $dictionary;
+ $v->reader = $reader;
+ $v->parser = $parser;
+
+ $offset = $reader->getOffset();
+
+ // Find the first "newline"
+ while (($firstByte = $reader->getByte($offset)) !== false) {
+ $offset++;
+ if ($firstByte === "\n" || $firstByte === "\r") {
+ break;
+ }
+ }
+
+ if ($firstByte === false) {
+ throw new PdfTypeException(
+ 'Unable to parse stream data. No newline after the stream keyword found.',
+ PdfTypeException::NO_NEWLINE_AFTER_STREAM_KEYWORD
+ );
+ }
+
+ $sndByte = $reader->getByte($offset);
+ if ($sndByte === "\n" && $firstByte !== "\n") {
+ $offset++;
+ }
+
+ $reader->setOffset($offset);
+ // let's only save the byte-offset and read the stream only when needed
+ $v->stream = $reader->getPosition() + $reader->getOffset();
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param PdfDictionary $dictionary
+ * @param string $stream
+ * @return self
+ */
+ public static function create(PdfDictionary $dictionary, $stream)
+ {
+ $v = new self();
+ $v->value = $dictionary;
+ $v->stream = (string) $stream;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfStream instance.
+ *
+ * @param mixed $stream
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($stream)
+ {
+ return PdfType::ensureType(self::class, $stream, 'Stream value expected.');
+ }
+
+ /**
+ * The stream or its byte-offset position.
+ *
+ * @var int|string
+ */
+ protected $stream;
+
+ /**
+ * The stream reader instance.
+ *
+ * @var StreamReader|null
+ */
+ protected $reader;
+
+ /**
+ * The PDF parser instance.
+ *
+ * @var PdfParser
+ */
+ protected $parser;
+
+ /**
+ * Get the stream data.
+ *
+ * @param bool $cache Whether cache the stream data or not.
+ * @return bool|string
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public function getStream($cache = false)
+ {
+ if (\is_int($this->stream)) {
+ $length = PdfDictionary::get($this->value, 'Length');
+ if ($this->parser !== null) {
+ $length = PdfType::resolve($length, $this->parser);
+ }
+
+ if (!($length instanceof PdfNumeric) || $length->value === 0) {
+ $this->reader->reset($this->stream, 100000);
+ $buffer = $this->extractStream();
+ } else {
+ $this->reader->reset($this->stream, $length->value);
+ $buffer = $this->reader->getBuffer(false);
+ if ($this->parser !== null) {
+ $this->reader->reset($this->stream + strlen($buffer));
+ $this->parser->getTokenizer()->clearStack();
+ $token = $this->parser->readValue();
+ if ($token === false || !($token instanceof PdfToken) || $token->value !== 'endstream') {
+ $this->reader->reset($this->stream, 100000);
+ $buffer = $this->extractStream();
+ $this->reader->reset($this->stream + strlen($buffer));
+ }
+ }
+ }
+
+ if ($cache === false) {
+ return $buffer;
+ }
+
+ $this->stream = $buffer;
+ $this->reader = null;
+ }
+
+ return $this->stream;
+ }
+
+ /**
+ * Extract the stream "manually".
+ *
+ * @return string
+ * @throws PdfTypeException
+ */
+ protected function extractStream()
+ {
+ while (true) {
+ $buffer = $this->reader->getBuffer(false);
+ $length = \strpos($buffer, 'endstream');
+ if ($length === false) {
+ if (!$this->reader->increaseLength(100000)) {
+ throw new PdfTypeException('Cannot extract stream.');
+ }
+ continue;
+ }
+ break;
+ }
+
+ $buffer = \substr($buffer, 0, $length);
+ $lastByte = \substr($buffer, -1);
+
+ /* Check for EOL marker =
+ * CARRIAGE RETURN (\r) and a LINE FEED (\n) or just a LINE FEED (\n},
+ * and not by a CARRIAGE RETURN (\r) alone
+ */
+ if ($lastByte === "\n") {
+ $buffer = \substr($buffer, 0, -1);
+
+ $lastByte = \substr($buffer, -1);
+ if ($lastByte === "\r") {
+ $buffer = \substr($buffer, 0, -1);
+ }
+ }
+
+ // There are streams in the wild, which have only white signs in them but need to be parsed manually due
+ // to a problem encountered before (e.g. Length === 0). We should set them to empty streams to avoid problems
+ // in further processing (e.g. applying of filters).
+ if (trim($buffer) === '') {
+ $buffer = '';
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Get the unfiltered stream data.
+ *
+ * @return string
+ * @throws FilterException
+ * @throws PdfParserException
+ */
+ public function getUnfilteredStream()
+ {
+ $stream = $this->getStream();
+ $filters = PdfDictionary::get($this->value, 'Filter');
+ if ($filters instanceof PdfNull) {
+ return $stream;
+ }
+
+ if ($filters instanceof PdfArray) {
+ $filters = $filters->value;
+ } else {
+ $filters = [$filters];
+ }
+
+ $decodeParams = PdfDictionary::get($this->value, 'DecodeParms');
+ if ($decodeParams instanceof PdfArray) {
+ $decodeParams = $decodeParams->value;
+ } else {
+ $decodeParams = [$decodeParams];
+ }
+
+ foreach ($filters as $key => $filter) {
+ if (!($filter instanceof PdfName)) {
+ continue;
+ }
+
+ $decodeParam = null;
+ if (isset($decodeParams[$key])) {
+ $decodeParam = ($decodeParams[$key] instanceof PdfDictionary ? $decodeParams[$key] : null);
+ }
+
+ switch ($filter->value) {
+ case 'FlateDecode':
+ case 'Fl':
+ case 'LZWDecode':
+ case 'LZW':
+ if (\strpos($filter->value, 'LZW') === 0) {
+ $filterObject = new Lzw();
+ } else {
+ $filterObject = new Flate();
+ }
+
+ $stream = $filterObject->decode($stream);
+
+ if ($decodeParam instanceof PdfDictionary) {
+ $predictor = PdfDictionary::get($decodeParam, 'Predictor', PdfNumeric::create(1));
+ if ($predictor->value !== 1) {
+ if (!\class_exists(Predictor::class)) {
+ throw new PdfParserException(
+ 'This PDF document makes use of features which are only implemented in the ' .
+ 'commercial "FPDI PDF-Parser" add-on (see https://www.setasign.com/fpdi-pdf-' .
+ 'parser).',
+ PdfParserException::IMPLEMENTED_IN_FPDI_PDF_PARSER
+ );
+ }
+
+ $colors = PdfDictionary::get($decodeParam, 'Colors', PdfNumeric::create(1));
+ $bitsPerComponent = PdfDictionary::get(
+ $decodeParam,
+ 'BitsPerComponent',
+ PdfNumeric::create(8)
+ );
+
+ $columns = PdfDictionary::get($decodeParam, 'Columns', PdfNumeric::create(1));
+
+ $filterObject = new Predictor(
+ $predictor->value,
+ $colors->value,
+ $bitsPerComponent->value,
+ $columns->value
+ );
+
+ $stream = $filterObject->decode($stream);
+ }
+ }
+
+ break;
+ case 'ASCII85Decode':
+ case 'A85':
+ $filterObject = new Ascii85();
+ $stream = $filterObject->decode($stream);
+ break;
+
+ case 'ASCIIHexDecode':
+ case 'AHx':
+ $filterObject = new AsciiHex();
+ $stream = $filterObject->decode($stream);
+ break;
+
+ default:
+ throw new FilterException(
+ \sprintf('Unsupported filter "%s".', $filter->value),
+ FilterException::UNSUPPORTED_FILTER
+ );
+ }
+ }
+
+ return $stream;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfString.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfString.php
new file mode 100644
index 0000000..41b66ed
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfString.php
@@ -0,0 +1,172 @@
+getOffset();
+ $openBrackets = 1;
+ do {
+ $buffer = $streamReader->getBuffer(false);
+ for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) {
+ switch ($buffer[$pos]) {
+ case '(':
+ $openBrackets++;
+ break;
+ case ')':
+ $openBrackets--;
+ break;
+ case '\\':
+ $pos++;
+ }
+ }
+ } while ($openBrackets !== 0 && $streamReader->increaseLength());
+
+ $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1);
+ $streamReader->setOffset($pos);
+
+ $v = new self();
+ $v->value = $result;
+
+ return $v;
+ }
+
+ /**
+ * Helper method to create an instance.
+ *
+ * @param string $value The string needs to be escaped accordingly.
+ * @return self
+ */
+ public static function create($value)
+ {
+ $v = new self();
+ $v->value = $value;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfString instance.
+ *
+ * @param mixed $string
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($string)
+ {
+ return PdfType::ensureType(self::class, $string, 'String value expected.');
+ }
+
+ /**
+ * Unescapes escaped sequences in a PDF string according to the PDF specification.
+ *
+ * @param string $s
+ * @return string
+ */
+ public static function unescape($s)
+ {
+ $out = '';
+ /** @noinspection ForeachInvariantsInspection */
+ for ($count = 0, $n = \strlen($s); $count < $n; $count++) {
+ if ($s[$count] !== '\\') {
+ $out .= $s[$count];
+ } else {
+ // A backslash at the end of the string - ignore it
+ if ($count === ($n - 1)) {
+ break;
+ }
+
+ switch ($s[++$count]) {
+ case ')':
+ case '(':
+ case '\\':
+ $out .= $s[$count];
+ break;
+
+ case 'f':
+ $out .= "\x0C";
+ break;
+
+ case 'b':
+ $out .= "\x08";
+ break;
+
+ case 't':
+ $out .= "\x09";
+ break;
+
+ case 'r':
+ $out .= "\x0D";
+ break;
+
+ case 'n':
+ $out .= "\x0A";
+ break;
+
+ case "\r":
+ if ($count !== $n - 1 && $s[$count + 1] === "\n") {
+ $count++;
+ }
+ break;
+
+ case "\n":
+ break;
+
+ default:
+ $actualChar = \ord($s[$count]);
+ // ascii 48 = number 0
+ // ascii 57 = number 9
+ if ($actualChar >= 48 && $actualChar <= 57) {
+ $oct = '' . $s[$count];
+
+ /** @noinspection NotOptimalIfConditionsInspection */
+ if (
+ $count + 1 < $n
+ && \ord($s[$count + 1]) >= 48
+ && \ord($s[$count + 1]) <= 57
+ ) {
+ $count++;
+ $oct .= $s[$count];
+
+ /** @noinspection NotOptimalIfConditionsInspection */
+ if (
+ $count + 1 < $n
+ && \ord($s[$count + 1]) >= 48
+ && \ord($s[$count + 1]) <= 57
+ ) {
+ $oct .= $s[++$count];
+ }
+ }
+
+ $out .= \chr(\octdec($oct));
+ } else {
+ // If the character is not one of those defined, the backslash is ignored
+ $out .= $s[$count];
+ }
+ }
+ }
+ }
+ return $out;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfToken.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfToken.php
new file mode 100644
index 0000000..8293c28
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfToken.php
@@ -0,0 +1,43 @@
+value = $token;
+
+ return $v;
+ }
+
+ /**
+ * Ensures that the passed value is a PdfToken instance.
+ *
+ * @param mixed $token
+ * @return self
+ * @throws PdfTypeException
+ */
+ public static function ensure($token)
+ {
+ return PdfType::ensureType(self::class, $token, 'Token value expected.');
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfType.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfType.php
new file mode 100644
index 0000000..065ad38
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfType.php
@@ -0,0 +1,78 @@
+value, $parser, $stopAtIndirectObject);
+ }
+
+ if ($value instanceof PdfIndirectObjectReference) {
+ return self::resolve($parser->getIndirectObject($value->value), $parser, $stopAtIndirectObject);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Ensure that a value is an instance of a specific PDF type.
+ *
+ * @param string $type
+ * @param PdfType $value
+ * @param string $errorMessage
+ * @return mixed
+ * @throws PdfTypeException
+ */
+ protected static function ensureType($type, $value, $errorMessage)
+ {
+ if (!($value instanceof $type)) {
+ throw new PdfTypeException(
+ $errorMessage,
+ PdfTypeException::INVALID_DATA_TYPE
+ );
+ }
+
+ return $value;
+ }
+
+ /**
+ * The value of the PDF type.
+ *
+ * @var mixed
+ */
+ public $value;
+}
diff --git a/fpdf186/FPDI-master/src/PdfParser/Type/PdfTypeException.php b/fpdf186/FPDI-master/src/PdfParser/Type/PdfTypeException.php
new file mode 100644
index 0000000..88d2c20
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfParser/Type/PdfTypeException.php
@@ -0,0 +1,24 @@
+value;
+ $ax = PdfNumeric::ensure(PdfType::resolve($array[0], $parser))->value;
+ $ay = PdfNumeric::ensure(PdfType::resolve($array[1], $parser))->value;
+ $bx = PdfNumeric::ensure(PdfType::resolve($array[2], $parser))->value;
+ $by = PdfNumeric::ensure(PdfType::resolve($array[3], $parser))->value;
+
+ return new self($ax, $ay, $bx, $by);
+ }
+
+ public static function byVectors(Vector $ll, Vector $ur)
+ {
+ return new self($ll->getX(), $ll->getY(), $ur->getX(), $ur->getY());
+ }
+
+ /**
+ * Rectangle constructor.
+ *
+ * @param float|int $ax
+ * @param float|int $ay
+ * @param float|int $bx
+ * @param float|int $by
+ */
+ public function __construct($ax, $ay, $bx, $by)
+ {
+ $this->llx = \min($ax, $bx);
+ $this->lly = \min($ay, $by);
+ $this->urx = \max($ax, $bx);
+ $this->ury = \max($ay, $by);
+ }
+
+ /**
+ * Get the width of the rectangle.
+ *
+ * @return float|int
+ */
+ public function getWidth()
+ {
+ return $this->urx - $this->llx;
+ }
+
+ /**
+ * Get the height of the rectangle.
+ *
+ * @return float|int
+ */
+ public function getHeight()
+ {
+ return $this->ury - $this->lly;
+ }
+
+ /**
+ * Get the lower left abscissa.
+ *
+ * @return float|int
+ */
+ public function getLlx()
+ {
+ return $this->llx;
+ }
+
+ /**
+ * Get the lower left ordinate.
+ *
+ * @return float|int
+ */
+ public function getLly()
+ {
+ return $this->lly;
+ }
+
+ /**
+ * Get the upper right abscissa.
+ *
+ * @return float|int
+ */
+ public function getUrx()
+ {
+ return $this->urx;
+ }
+
+ /**
+ * Get the upper right ordinate.
+ *
+ * @return float|int
+ */
+ public function getUry()
+ {
+ return $this->ury;
+ }
+
+ /**
+ * Get the rectangle as an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return [
+ $this->llx,
+ $this->lly,
+ $this->urx,
+ $this->ury
+ ];
+ }
+
+ /**
+ * Get the rectangle as a PdfArray.
+ *
+ * @return PdfArray
+ */
+ public function toPdfArray()
+ {
+ $array = new PdfArray();
+ $array->value[] = PdfNumeric::create($this->llx);
+ $array->value[] = PdfNumeric::create($this->lly);
+ $array->value[] = PdfNumeric::create($this->urx);
+ $array->value[] = PdfNumeric::create($this->ury);
+
+ return $array;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfReader/Page.php b/fpdf186/FPDI-master/src/PdfReader/Page.php
new file mode 100644
index 0000000..8d08c95
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfReader/Page.php
@@ -0,0 +1,391 @@
+pageObject = $page;
+ $this->parser = $parser;
+ }
+
+ /**
+ * Get the indirect object of this page.
+ *
+ * @return PdfIndirectObject
+ */
+ public function getPageObject()
+ {
+ return $this->pageObject;
+ }
+
+ /**
+ * Get the dictionary of this page.
+ *
+ * @return PdfDictionary
+ * @throws PdfParserException
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ */
+ public function getPageDictionary()
+ {
+ if ($this->pageDictionary === null) {
+ $this->pageDictionary = PdfDictionary::ensure(PdfType::resolve($this->getPageObject(), $this->parser));
+ }
+
+ return $this->pageDictionary;
+ }
+
+ /**
+ * Get a page attribute.
+ *
+ * @param string $name
+ * @param bool $inherited
+ * @return PdfType|null
+ * @throws PdfParserException
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ */
+ public function getAttribute($name, $inherited = true)
+ {
+ $dict = $this->getPageDictionary();
+
+ if (isset($dict->value[$name])) {
+ return $dict->value[$name];
+ }
+
+ $inheritedKeys = ['Resources', 'MediaBox', 'CropBox', 'Rotate'];
+ if ($inherited && \in_array($name, $inheritedKeys, true)) {
+ if ($this->inheritedAttributes === null) {
+ $this->inheritedAttributes = [];
+ $inheritedKeys = \array_filter($inheritedKeys, function ($key) use ($dict) {
+ return !isset($dict->value[$key]);
+ });
+
+ if (\count($inheritedKeys) > 0) {
+ $parentDict = PdfType::resolve(PdfDictionary::get($dict, 'Parent'), $this->parser);
+ while ($parentDict instanceof PdfDictionary) {
+ foreach ($inheritedKeys as $index => $key) {
+ if (isset($parentDict->value[$key])) {
+ $this->inheritedAttributes[$key] = $parentDict->value[$key];
+ unset($inheritedKeys[$index]);
+ }
+ }
+
+ /** @noinspection NotOptimalIfConditionsInspection */
+ if (isset($parentDict->value['Parent']) && \count($inheritedKeys) > 0) {
+ $parentDict = PdfType::resolve(PdfDictionary::get($parentDict, 'Parent'), $this->parser);
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ if (isset($this->inheritedAttributes[$name])) {
+ return $this->inheritedAttributes[$name];
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the rotation value.
+ *
+ * @return int
+ * @throws PdfParserException
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ */
+ public function getRotation()
+ {
+ $rotation = $this->getAttribute('Rotate');
+ if ($rotation === null) {
+ return 0;
+ }
+
+ $rotation = PdfNumeric::ensure(PdfType::resolve($rotation, $this->parser))->value % 360;
+
+ if ($rotation < 0) {
+ $rotation += 360;
+ }
+
+ return $rotation;
+ }
+
+ /**
+ * Get a boundary of this page.
+ *
+ * @param string $box
+ * @param bool $fallback
+ * @return bool|Rectangle
+ * @throws PdfParserException
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ * @see PageBoundaries
+ */
+ public function getBoundary($box = PageBoundaries::CROP_BOX, $fallback = true)
+ {
+ $value = $this->getAttribute($box);
+
+ if ($value !== null) {
+ return Rectangle::byPdfArray($value, $this->parser);
+ }
+
+ if ($fallback === false) {
+ return false;
+ }
+
+ switch ($box) {
+ case PageBoundaries::BLEED_BOX:
+ case PageBoundaries::TRIM_BOX:
+ case PageBoundaries::ART_BOX:
+ return $this->getBoundary(PageBoundaries::CROP_BOX, true);
+ case PageBoundaries::CROP_BOX:
+ return $this->getBoundary(PageBoundaries::MEDIA_BOX, true);
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the width and height of this page.
+ *
+ * @param string $box
+ * @param bool $fallback
+ * @return array|bool
+ * @throws PdfParserException
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ */
+ public function getWidthAndHeight($box = PageBoundaries::CROP_BOX, $fallback = true)
+ {
+ $boundary = $this->getBoundary($box, $fallback);
+ if ($boundary === false) {
+ return false;
+ }
+
+ $rotation = $this->getRotation();
+ $interchange = ($rotation / 90) % 2;
+
+ return [
+ $interchange ? $boundary->getHeight() : $boundary->getWidth(),
+ $interchange ? $boundary->getWidth() : $boundary->getHeight()
+ ];
+ }
+
+ /**
+ * Get the raw content stream.
+ *
+ * @return string
+ * @throws PdfReaderException
+ * @throws PdfTypeException
+ * @throws FilterException
+ * @throws PdfParserException
+ */
+ public function getContentStream()
+ {
+ $dict = $this->getPageDictionary();
+ $contents = PdfType::resolve(PdfDictionary::get($dict, 'Contents'), $this->parser);
+ if ($contents instanceof PdfNull) {
+ return '';
+ }
+
+ if ($contents instanceof PdfArray) {
+ $result = [];
+ foreach ($contents->value as $content) {
+ $content = PdfType::resolve($content, $this->parser);
+ if (!($content instanceof PdfStream)) {
+ continue;
+ }
+ $result[] = $content->getUnfilteredStream();
+ }
+
+ return \implode("\n", $result);
+ }
+
+ if ($contents instanceof PdfStream) {
+ return $contents->getUnfilteredStream();
+ }
+
+ throw new PdfReaderException(
+ 'Array or stream expected.',
+ PdfReaderException::UNEXPECTED_DATA_TYPE
+ );
+ }
+
+ /**
+ * Get information of all external links on this page.
+ *
+ * All coordinates are normalized in view to rotation and translation of the boundary-box, so that their
+ * origin is lower-left.
+ *
+ * @return array
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ * @throws PdfTypeException
+ */
+ public function getExternalLinks($box = PageBoundaries::CROP_BOX)
+ {
+ $dict = $this->getPageDictionary();
+ $annotations = PdfType::resolve(PdfDictionary::get($dict, 'Annots'), $this->parser);
+
+ if (!$annotations instanceof PdfArray) {
+ return [];
+ }
+
+ $links = [];
+
+ foreach ($annotations->value as $entry) {
+ $annotation = PdfType::resolve($entry, $this->parser);
+
+ $value = PdfType::resolve(PdfDictionary::get($annotation, 'Subtype'), $this->parser);
+ if (!$value instanceof PdfName || $value->value !== 'Link') {
+ continue;
+ }
+
+ $dest = PdfType::resolve(PdfDictionary::get($annotation, 'Dest'), $this->parser);
+ if (!$dest instanceof PdfNull) {
+ continue;
+ }
+
+ $action = PdfType::resolve(PdfDictionary::get($annotation, 'A'), $this->parser);
+ if (!$action instanceof PdfDictionary) {
+ continue;
+ }
+
+ $actionType = PdfType::resolve(PdfDictionary::get($action, 'S'), $this->parser);
+ if (!$actionType instanceof PdfName || $actionType->value !== 'URI') {
+ continue;
+ }
+
+ $uri = PdfType::resolve(PdfDictionary::get($action, 'URI'), $this->parser);
+ if ($uri instanceof PdfString) {
+ $uriValue = PdfString::unescape($uri->value);
+ } elseif ($uri instanceof PdfHexString) {
+ $uriValue = \hex2bin($uri->value);
+ } else {
+ continue;
+ }
+
+ $rect = PdfType::resolve(PdfDictionary::get($annotation, 'Rect'), $this->parser);
+ if (!$rect instanceof PdfArray || count($rect->value) !== 4) {
+ continue;
+ }
+
+ $rect = Rectangle::byPdfArray($rect, $this->parser);
+ if ($rect->getWidth() === 0 || $rect->getHeight() === 0) {
+ continue;
+ }
+
+ $bbox = $this->getBoundary($box);
+ $rotation = $this->getRotation();
+
+ $gs = new GraphicsState();
+ $gs->translate(-$bbox->getLlx(), -$bbox->getLly());
+ $gs->rotate($bbox->getLlx(), $bbox->getLly(), -$rotation);
+
+ switch ($rotation) {
+ case 90:
+ $gs->translate(-$bbox->getWidth(), 0);
+ break;
+ case 180:
+ $gs->translate(-$bbox->getWidth(), -$bbox->getHeight());
+ break;
+ case 270:
+ $gs->translate(0, -$bbox->getHeight());
+ break;
+ }
+
+ $normalizedRect = Rectangle::byVectors(
+ $gs->toUserSpace(new Vector($rect->getLlx(), $rect->getLly())),
+ $gs->toUserSpace(new Vector($rect->getUrx(), $rect->getUry()))
+ );
+
+ $quadPoints = PdfType::resolve(PdfDictionary::get($annotation, 'QuadPoints'), $this->parser);
+ $normalizedQuadPoints = [];
+ if ($quadPoints instanceof PdfArray) {
+ $quadPointsCount = count($quadPoints->value);
+ if ($quadPointsCount % 8 === 0) {
+ for ($i = 0; ($i + 1) < $quadPointsCount; $i += 2) {
+ $x = PdfNumeric::ensure(PdfType::resolve($quadPoints->value[$i], $this->parser));
+ $y = PdfNumeric::ensure(PdfType::resolve($quadPoints->value[$i + 1], $this->parser));
+
+ $v = $gs->toUserSpace(new Vector($x->value, $y->value));
+ $normalizedQuadPoints[] = $v->getX();
+ $normalizedQuadPoints[] = $v->getY();
+ }
+ }
+ }
+
+ $links[] = [
+ 'rect' => $normalizedRect,
+ 'quadPoints' => $normalizedQuadPoints,
+ 'uri' => $uriValue,
+ 'pdfObject' => $annotation
+ ];
+ }
+
+ return $links;
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfReader/PageBoundaries.php b/fpdf186/FPDI-master/src/PdfReader/PageBoundaries.php
new file mode 100644
index 0000000..ec24cde
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfReader/PageBoundaries.php
@@ -0,0 +1,94 @@
+parser = $parser;
+ }
+
+ /**
+ * PdfReader destructor.
+ */
+ public function __destruct()
+ {
+ if ($this->parser !== null) {
+ $this->parser->cleanUp();
+ }
+ }
+
+ /**
+ * Get the pdf parser instance.
+ *
+ * @return PdfParser
+ */
+ public function getParser()
+ {
+ return $this->parser;
+ }
+
+ /**
+ * Get the PDF version.
+ *
+ * @return string
+ * @throws PdfParserException
+ */
+ public function getPdfVersion()
+ {
+ return \implode('.', $this->parser->getPdfVersion());
+ }
+
+ /**
+ * Get the page count.
+ *
+ * @return int
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public function getPageCount()
+ {
+ if ($this->pageCount === null) {
+ $catalog = $this->parser->getCatalog();
+
+ $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser);
+ $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser);
+
+ $this->pageCount = PdfNumeric::ensure($count)->value;
+ }
+
+ return $this->pageCount;
+ }
+
+ /**
+ * Get a page instance.
+ *
+ * @param int $pageNumber
+ * @return Page
+ * @throws PdfTypeException
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ * @throws \InvalidArgumentException
+ */
+ public function getPage($pageNumber)
+ {
+ if (!\is_numeric($pageNumber)) {
+ throw new \InvalidArgumentException(
+ 'Page number needs to be a number.'
+ );
+ }
+
+ if ($pageNumber < 1 || $pageNumber > $this->getPageCount()) {
+ throw new \InvalidArgumentException(
+ \sprintf(
+ 'Page number "%s" out of available page range (1 - %s)',
+ $pageNumber,
+ $this->getPageCount()
+ )
+ );
+ }
+
+ $this->readPages();
+
+ $page = $this->pages[$pageNumber - 1];
+
+ if ($page instanceof PdfIndirectObjectReference) {
+ $readPages = function ($kids) use (&$readPages) {
+ $kids = PdfArray::ensure($kids);
+
+ /** @noinspection LoopWhichDoesNotLoopInspection */
+ foreach ($kids->value as $reference) {
+ $reference = PdfIndirectObjectReference::ensure($reference);
+ $object = $this->parser->getIndirectObject($reference->value);
+ $type = PdfDictionary::get($object->value, 'Type');
+
+ if ($type->value === 'Pages') {
+ return $readPages(PdfDictionary::get($object->value, 'Kids'));
+ }
+
+ return $object;
+ }
+
+ throw new PdfReaderException(
+ 'Kids array cannot be empty.',
+ PdfReaderException::KIDS_EMPTY
+ );
+ };
+
+ $page = $this->parser->getIndirectObject($page->value);
+ $dict = PdfType::resolve($page, $this->parser);
+ $type = PdfDictionary::get($dict, 'Type');
+
+ if ($type->value === 'Pages') {
+ $kids = PdfType::resolve(PdfDictionary::get($dict, 'Kids'), $this->parser);
+ try {
+ $page = $this->pages[$pageNumber - 1] = $readPages($kids);
+ } catch (PdfReaderException $e) {
+ if ($e->getCode() !== PdfReaderException::KIDS_EMPTY) {
+ throw $e;
+ }
+
+ // let's reset the pages array and read all page objects
+ $this->pages = [];
+ $this->readPages(true);
+ // @phpstan-ignore-next-line
+ $page = $this->pages[$pageNumber - 1];
+ }
+ } else {
+ $this->pages[$pageNumber - 1] = $page;
+ }
+ }
+
+ return new Page($page, $this->parser);
+ }
+
+ /**
+ * Walk the page tree and resolve all indirect objects of all pages.
+ *
+ * @param bool $readAll
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ * @throws PdfTypeException
+ */
+ protected function readPages($readAll = false)
+ {
+ if (\count($this->pages) > 0) {
+ return;
+ }
+
+ $expectedPageCount = $this->getPageCount();
+ $readPages = function ($kids, $count) use (&$readPages, $readAll, $expectedPageCount) {
+ $kids = PdfArray::ensure($kids);
+ $isLeaf = ($count->value === \count($kids->value));
+
+ foreach ($kids->value as $reference) {
+ $reference = PdfIndirectObjectReference::ensure($reference);
+
+ if (!$readAll && $isLeaf) {
+ $this->pages[] = $reference;
+ continue;
+ }
+
+ $object = $this->parser->getIndirectObject($reference->value);
+ $type = PdfDictionary::get($object->value, 'Type');
+
+ if ($type->value === 'Pages') {
+ $readPages(PdfDictionary::get($object->value, 'Kids'), PdfDictionary::get($object->value, 'Count'));
+ } else {
+ $this->pages[] = $object;
+ }
+
+ // stop if all pages are read - faulty documents exists with additional entries with invalid data.
+ if (count($this->pages) === $expectedPageCount) {
+ break;
+ }
+ }
+ };
+
+ $catalog = $this->parser->getCatalog();
+ $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser);
+ $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser);
+ $kids = PdfType::resolve(PdfDictionary::get($pages, 'Kids'), $this->parser);
+ $readPages($kids, $count);
+ }
+}
diff --git a/fpdf186/FPDI-master/src/PdfReader/PdfReaderException.php b/fpdf186/FPDI-master/src/PdfReader/PdfReaderException.php
new file mode 100644
index 0000000..2b3487e
--- /dev/null
+++ b/fpdf186/FPDI-master/src/PdfReader/PdfReaderException.php
@@ -0,0 +1,34 @@
+cleanUp();
+ }
+
+ /**
+ * Get the next template id.
+ *
+ * @return int
+ */
+ protected function getNextTemplateId()
+ {
+ return $this->templateId++;
+ }
+
+ /**
+ * Draws an imported page onto the page or another template.
+ *
+ * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the
+ * aspect ratio.
+ *
+ * @param mixed $tpl The template id
+ * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
+ * with the keys "x", "y", "width", "height", "adjustPageSize".
+ * @param float|int $y The ordinate of upper-left corner.
+ * @param float|int|null $width The width.
+ * @param float|int|null $height The height.
+ * @param bool $adjustPageSize
+ * @return array The size
+ * @see FpdiTrait::getTemplateSize()
+ */
+ public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
+ {
+ return $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize);
+ }
+
+ /**
+ * Draws an imported page onto the page.
+ *
+ * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the
+ * aspect ratio.
+ *
+ * @param mixed $pageId The page id
+ * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
+ * with the keys "x", "y", "width", "height", "adjustPageSize".
+ * @param float|int $y The ordinate of upper-left corner.
+ * @param float|int|null $width The width.
+ * @param float|int|null $height The height.
+ * @param bool $adjustPageSize
+ * @return array The size.
+ * @see Fpdi::getTemplateSize()
+ */
+ public function useImportedPage($pageId, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
+ {
+ $size = $this->fpdiUseImportedPage($pageId, $x, $y, $width, $height, $adjustPageSize);
+ if ($this->inxobj) {
+ $importedPage = $this->importedPages[$pageId];
+ $this->xobjects[$this->xobjid]['importedPages'][$importedPage['id']] = $pageId;
+ }
+
+ return $size;
+ }
+
+ /**
+ * Get the size of an imported page.
+ *
+ * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the
+ * aspect ratio.
+ *
+ * @param mixed $tpl The template id
+ * @param float|int|null $width The width.
+ * @param float|int|null $height The height.
+ * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
+ */
+ public function getTemplateSize($tpl, $width = null, $height = null)
+ {
+ return $this->getImportedPageSize($tpl, $width, $height);
+ }
+
+ /**
+ * @inheritdoc
+ * @return string
+ */
+ protected function _getxobjectdict()
+ {
+ $out = parent::_getxobjectdict();
+
+ foreach ($this->importedPages as $pageData) {
+ $out .= '/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R ';
+ }
+
+ return $out;
+ }
+
+ /**
+ * @inheritdoc
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ protected function _putxobjects()
+ {
+ foreach ($this->importedPages as $key => $pageData) {
+ $this->currentObjectNumber = $this->_newobj();
+ $this->importedPages[$key]['objectNumber'] = $this->currentObjectNumber;
+ $this->currentReaderId = $pageData['readerId'];
+ $this->writePdfType($pageData['stream']);
+ $this->_put('endobj');
+ }
+
+ foreach (\array_keys($this->readers) as $readerId) {
+ $parser = $this->getPdfReader($readerId)->getParser();
+ $this->currentReaderId = $readerId;
+
+ while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) {
+ try {
+ $object = $parser->getIndirectObject($objectNumber);
+ } catch (CrossReferenceException $e) {
+ if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) {
+ $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull());
+ } else {
+ throw $e;
+ }
+ }
+
+ $this->writePdfType($object);
+ }
+ }
+
+ // let's prepare resources for imported pages in templates
+ foreach ($this->xobjects as $xObjectId => $data) {
+ if (!isset($data['importedPages'])) {
+ continue;
+ }
+
+ foreach ($data['importedPages'] as $id => $pageKey) {
+ $page = $this->importedPages[$pageKey];
+ $this->xobjects[$xObjectId]['xobjects'][$id] = ['n' => $page['objectNumber']];
+ }
+ }
+
+
+ parent::_putxobjects();
+ $this->currentObjectNumber = null;
+ }
+
+ /**
+ * Append content to the buffer of TCPDF.
+ *
+ * @param string $s
+ * @param bool $newLine
+ */
+ protected function _put($s, $newLine = true)
+ {
+ if ($newLine) {
+ $this->setBuffer($s . "\n");
+ } else {
+ $this->setBuffer($s);
+ }
+ }
+
+ /**
+ * Begin a new object and return the object number.
+ *
+ * @param int|string $objid Object ID (leave empty to get a new ID).
+ * @return int object number
+ */
+ protected function _newobj($objid = '')
+ {
+ $this->_out($this->_getobj($objid));
+ return $this->n;
+ }
+
+ /**
+ * Writes a PdfType object to the resulting buffer.
+ *
+ * @param PdfType $value
+ * @throws PdfTypeException
+ */
+ protected function writePdfType(PdfType $value)
+ {
+ if (!$this->encrypted) {
+ $this->fpdiWritePdfType($value);
+ return;
+ }
+
+ if ($value instanceof PdfString) {
+ $string = PdfString::unescape($value->value);
+ $string = $this->_encrypt_data($this->currentObjectNumber, $string);
+ $value->value = \TCPDF_STATIC::_escape($string);
+ } elseif ($value instanceof PdfHexString) {
+ $filter = new AsciiHex();
+ $string = $filter->decode($value->value);
+ $string = $this->_encrypt_data($this->currentObjectNumber, $string);
+ $value->value = $filter->encode($string, true);
+ } elseif ($value instanceof PdfStream) {
+ $stream = $value->getStream();
+ $stream = $this->_encrypt_data($this->currentObjectNumber, $stream);
+ $dictionary = $value->value;
+ $dictionary->value['Length'] = PdfNumeric::create(\strlen($stream));
+ $value = PdfStream::create($dictionary, $stream);
+ } elseif ($value instanceof PdfIndirectObject) {
+ /**
+ * @var PdfIndirectObject $value
+ */
+ $this->currentObjectNumber = $this->objectMap[$this->currentReaderId][$value->objectNumber];
+ }
+
+ $this->fpdiWritePdfType($value);
+ }
+
+ /**
+ * This method will add additional data to the last created link/annotation.
+ *
+ * It will copy styling properties (supported by TCPDF) of the imported link.
+ *
+ * @param array $externalLink
+ * @param float|int $xPt
+ * @param float|int $scaleX
+ * @param float|int $yPt
+ * @param float|int $newHeightPt
+ * @param float|int $scaleY
+ * @param array $importedPage
+ * @return void
+ */
+ protected function adjustLastLink($externalLink, $xPt, $scaleX, $yPt, $newHeightPt, $scaleY, $importedPage)
+ {
+ $parser = $this->getPdfReader($importedPage['readerId'])->getParser();
+
+ if ($this->inxobj) {
+ // store parameters for later use on template
+ $lastAnnotationKey = count($this->xobjects[$this->xobjid]['annotations']) - 1;
+ $lastAnnotationOpt = &$this->xobjects[$this->xobjid]['annotations'][$lastAnnotationKey]['opt'];
+ } else {
+ $lastAnnotationKey = count($this->PageAnnots[$this->page]) - 1;
+ $lastAnnotationOpt = &$this->PageAnnots[$this->page][$lastAnnotationKey]['opt'];
+ }
+
+ // ensure we have a default value - otherwise TCPDF will set it to 4 throughout
+ $lastAnnotationOpt['f'] = 0;
+
+ $values = $externalLink['pdfObject']->value;
+ unset(
+ $values['P'],
+ $values['NM'],
+ $values['AP'],
+ $values['AS'],
+ $values['Type'],
+ $values['Subtype'],
+ $values['Rect'],
+ $values['A'],
+ $values['QuadPoints'],
+ $values['Rotate'],
+ $values['M'],
+ $values['StructParent']
+ );
+
+ foreach ($values as $key => $value) {
+ try {
+ switch ($key) {
+ case 'BS':
+ $value = PdfDictionary::ensure($value);
+ $bs = [];
+ if (isset($value->value['W'])) {
+ $bs['w'] = PdfNumeric::ensure(PdfType::resolve($value->value['W'], $parser))->value;
+ }
+
+ if (isset($value->value['S'])) {
+ $bs['s'] = PdfName::ensure(PdfType::resolve($value->value['S'], $parser))->value;
+ }
+
+ if (isset($value->value['D'])) {
+ $d = [];
+ foreach (PdfArray::ensure(PdfType::resolve($value->value['D'], $parser))->value as $item) {
+ $d[] = PdfNumeric::ensure(PdfType::resolve($item, $parser))->value;
+ }
+ $bs['d'] = $d;
+ }
+
+ $lastAnnotationOpt['bs'] = $bs;
+ break;
+
+ case 'Border':
+ $borderArray = PdfArray::ensure(PdfType::resolve($value, $parser))->value;
+ if (count($borderArray) < 3) {
+ continue 2;
+ }
+
+ $border = [
+ PdfNumeric::ensure(PdfType::resolve($borderArray[0], $parser))->value,
+ PdfNumeric::ensure(PdfType::resolve($borderArray[1], $parser))->value,
+ PdfNumeric::ensure(PdfType::resolve($borderArray[2], $parser))->value,
+ ];
+ if (isset($borderArray[3])) {
+ $dashArray = [];
+ foreach (PdfArray::ensure(PdfType::resolve($borderArray[3], $parser))->value as $item) {
+ $dashArray[] = PdfNumeric::ensure(PdfType::resolve($item, $parser))->value;
+ }
+ $border[] = $dashArray;
+ }
+
+ $lastAnnotationOpt['border'] = $border;
+ break;
+
+ case 'C':
+ $c = [];
+ $colors = PdfArray::ensure(PdfType::resolve($value, $parser))->value;
+ $m = count($colors) === 4 ? 100 : 255;
+ foreach ($colors as $item) {
+ $c[] = PdfNumeric::ensure(PdfType::resolve($item, $parser))->value * $m;
+ }
+ $lastAnnotationOpt['c'] = $c;
+ break;
+
+ case 'F':
+ $lastAnnotationOpt['f'] = $value->value;
+ break;
+
+ case 'BE':
+ // is broken in current TCPDF version: "bc" key is checked but "bs" is used.
+ break;
+ }
+ // let's silence invalid/not supported values
+ } catch (FpdiException $e) {
+ continue;
+ }
+ }
+
+ // QuadPoints are not supported by TCPDF
+// if (count($externalLink['quadPoints']) > 0) {
+// $quadPoints = [];
+// for ($i = 0, $n = count($externalLink['quadPoints']); $i < $n; $i += 2) {
+// $quadPoints[] = $xPt + $externalLink['quadPoints'][$i] * $scaleX;
+// $quadPoints[] = $this->hPt - $yPt - $newHeightPt + $externalLink['quadPoints'][$i + 1] * $scaleY;
+// }
+//
+// ????? = $quadPoints;
+// }
+ }
+}
diff --git a/fpdf186/FPDI-master/src/TcpdfFpdi.php b/fpdf186/FPDI-master/src/TcpdfFpdi.php
new file mode 100644
index 0000000..8f3c095
--- /dev/null
+++ b/fpdf186/FPDI-master/src/TcpdfFpdi.php
@@ -0,0 +1,23 @@
+
+
+
+
+__construct([string orientation [, string unit [, mixed size]]])
+orientation
P
or Portrait
L
or Landscape
P
.
+unit
pt
: pointmm
: millimetercm
: centimeterin
: inchmm
.
+size
A3
A4
A5
Letter
Legal
unit
).A4
.
+$pdf = new FPDF('P', 'mm', array(100,150));
+boolean AcceptPageBreak()
+class PDF extends FPDF
+{
+ protected $col = 0;
+
+ function SetCol($col)
+ {
+ // Move position to a column
+ $this->col = $col;
+ $x = 10 + $col*65;
+ $this->SetLeftMargin($x);
+ $this->SetX($x);
+ }
+
+ function AcceptPageBreak()
+ {
+ if($this->col<2)
+ {
+ // Go to next column
+ $this->SetCol($this->col+1);
+ $this->SetY(10);
+ return false;
+ }
+ else
+ {
+ // Go back to first column and issue page break
+ $this->SetCol(0);
+ return true;
+ }
+ }
+}
+
+$pdf = new PDF();
+$pdf->AddPage();
+$pdf->SetFont('Arial', '', 12);
+for($i=1;$i<=300;$i++)
+ $pdf->Cell(0, 5, "Line $i", 0, 1);
+$pdf->Output();
+AddFont(string family [, string style [, string file [, string dir]]])
+FPDF_FONTPATH
constant (if that constant is defined)font
directory located in the same directory as fpdf.php
family
style
B
: boldI
: italicBI
or IB
: bold italicfile
dir
$pdf->AddFont('Comic', 'I');
+$pdf->AddFont('Comic', 'I', 'comici.php');
+int AddLink()
+AddPage([string orientation [, mixed size [, int rotation]]])
+orientation
P
or Portrait
L
or Landscape
size
A3
A4
A5
Letter
Legal
rotation
0
.
+AliasNbPages([string alias])
+alias
{nb}
.
+class PDF extends FPDF
+{
+ function Footer()
+ {
+ // Go to 1.5 cm from bottom
+ $this->SetY(-15);
+ // Select Arial italic 8
+ $this->SetFont('Arial', 'I', 8);
+ // Print current and total page numbers
+ $this->Cell(0, 10, 'Page '.$this->PageNo().'/{nb}', 0, 0, 'C');
+ }
+}
+
+$pdf = new PDF();
+$pdf->AliasNbPages();
+Cell(float w [, float h [, string txt [, mixed border [, int ln [, string align [, boolean fill [, mixed link]]]]]]])
+w
0
, the cell extends up to the right margin.
+h
0
.
+txt
border
0
: no border1
: frameL
: leftT
: topR
: rightB
: bottom0
.
+ln
0
: to the right1
: to the beginning of the next line2
: below1
is equivalent to putting 0
and calling Ln() just after.
+Default value: 0
.
+align
L
or empty string: left align (default value)C
: centerR
: right alignfill
true
) or transparent (false
).
+Default value: false
.
+link
// Set font
+$pdf->SetFont('Arial', 'B', 16);
+// Move to 8 cm to the right
+$pdf->Cell(80);
+// Centered text in a framed 20*10 mm cell and line break
+$pdf->Cell(20, 10, 'Title', 1, 1, 'C');
+Close()
+Error(string msg)
+msg
Footer()
+class PDF extends FPDF
+{
+ function Footer()
+ {
+ // Go to 1.5 cm from bottom
+ $this->SetY(-15);
+ // Select Arial italic 8
+ $this->SetFont('Arial', 'I', 8);
+ // Print centered page number
+ $this->Cell(0, 10, 'Page '.$this->PageNo(), 0, 0, 'C');
+ }
+}
+float GetPageHeight()
+float GetPageWidth()
+float GetStringWidth(string s)
+s
float GetX()
+float GetY()
+Header()
+class PDF extends FPDF
+{
+ function Header()
+ {
+ // Select Arial bold 15
+ $this->SetFont('Arial', 'B', 15);
+ // Move to the right
+ $this->Cell(80);
+ // Framed title
+ $this->Cell(30, 10, 'Title', 1, 0, 'C');
+ // Line break
+ $this->Ln(20);
+ }
+}
+Image(string file [, float x [, float y [, float w [, float h [, string type [, mixed link]]]]]])
+file
x
null
, the current abscissa
+is used.
+y
null
, the current ordinate
+is used; moreover, a page break is triggered first if necessary (in case automatic page breaking is enabled)
+and, after the call, the current ordinate is moved to the bottom of the image.
+w
h
type
JPG
, JPEG
, PNG
and GIF
.
+If not specified, the type is inferred from the file extension.
+link
// Insert a logo in the top-left corner at 300 dpi
+$pdf->Image('logo.png', 10, 10, -300);
+// Insert a dynamic image from a URL
+$pdf->Image('http://chart.googleapis.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World', 60, 30, 90, 0, 'PNG');
+Line(float x1, float y1, float x2, float y2)
+x1
y1
x2
y2
Link(float x, float y, float w, float h, mixed link)
+x
y
w
h
link
Ln([float h])
+h
MultiCell(float w, float h, string txt [, mixed border [, string align [, boolean fill]]])
+w
0
, they extend up to the right margin of the page.
+h
txt
border
0
: no border1
: frameL
: leftT
: topR
: rightB
: bottom0
.
+align
L
: left alignmentC
: centerR
: right alignmentJ
: justification (default value)fill
true
) or transparent (false
).
+Default value: false
.
+string Output([string dest [, string name [, boolean isUTF8]]])
+dest
I
: send the file inline to the browser. The PDF viewer is used if available.D
: send to the browser and force a file download with the name given by name
.F
: save to a local file with the name given by name
(may include a path).S
: return the document as a string.I
.
+name
S
.doc.pdf
.
+isUTF8
name
is encoded in ISO-8859-1 (false
) or UTF-8 (true
).
+Only used for destinations I
and D
.false
.
+$pdf->Output('F', 'reports/report.pdf');
+$pdf->Output('D', 'report.pdf');
+int PageNo()
+Rect(float x, float y, float w, float h [, string style])
+x
y
w
h
style
D
or empty string: draw. This is the default value.F
: fillDF
or FD
: draw and fillSetAuthor(string author [, boolean isUTF8])
+author
isUTF8
false
) or UTF-8 (true
).false
.
+SetAutoPageBreak(boolean auto [, float margin])
+auto
margin
SetCompression(boolean compress)
+compress
SetCreator(string creator [, boolean isUTF8])
+creator
isUTF8
false
) or UTF-8 (true
).false
.
+SetDisplayMode(mixed zoom [, string layout])
+zoom
fullpage
: displays the entire page on screenfullwidth
: uses maximum width of windowreal
: uses real size (equivalent to 100% zoom)default
: uses viewer default modelayout
single
: displays one page at oncecontinuous
: displays pages continuouslytwo
: displays two pages on two columnsdefault
: uses viewer default modedefault
.
+SetDrawColor(int r [, int g, int b])
+r
g
et b
are given, red component; if not, indicates the gray level.
+Value between 0 and 255.
+g
b
SetFillColor(int r [, int g, int b])
+r
g
and b
are given, red component; if not, indicates the gray level.
+Value between 0 and 255.
+g
b
SetFont(string family [, string style [, float size]])
+family
Courier
(fixed-width)Helvetica
or Arial
(synonymous; sans serif)Times
(serif)Symbol
(symbolic)ZapfDingbats
(symbolic)style
B
: boldI
: italicU
: underlineSymbol
and ZapfDingbats
.
+size
// Times regular 12
+$pdf->SetFont('Times');
+// Arial bold 14
+$pdf->SetFont('Arial', 'B', 14);
+// Removes bold
+$pdf->SetFont('');
+// Times bold, italic and underlined 14
+$pdf->SetFont('Times', 'BIU');
+SetFontSize(float size)
+size
SetKeywords(string keywords [, boolean isUTF8])
+keywords
isUTF8
false
) or UTF-8 (true
).false
.
+SetLeftMargin(float margin)
+margin
SetLineWidth(float width)
+width
SetLink(int link [, float y [, int page]])
+link
y
-1
indicates the current position.
+The default value is 0
(top of page).
+page
-1
indicates the current page. This is the default value.
+SetMargins(float left, float top [, float right])
+left
top
right
SetRightMargin(float margin)
+margin
SetSubject(string subject [, boolean isUTF8])
+subject
isUTF8
false
) or UTF-8 (true
).false
.
+SetTextColor(int r [, int g, int b])
+r
g
et b
are given, red component; if not, indicates the gray level.
+Value between 0 and 255.
+g
b
SetTitle(string title [, boolean isUTF8])
+title
isUTF8
false
) or UTF-8 (true
).false
.
+SetTopMargin(float margin)
+margin
SetX(float x)
+x
SetXY(float x, float y)
+x
y
SetY(float y [, boolean resetX])
+y
resetX
true
.
+Text(float x, float y, string txt)
+x
y
txt
Write(float h, string txt [, mixed link])
+h
txt
link
// Begin with regular font
+$pdf->SetFont('Arial', '', 14);
+$pdf->Write(5, 'Visit ');
+// Then put a blue underlined link
+$pdf->SetTextColor(0, 0, 255);
+$pdf->SetFont('', 'U');
+$pdf->Write(5, 'www.fpdf.org', 'http://www.fpdf.org');
+<?php
+require('fpdf.php');
+
+$pdf = new FPDF();
+$pdf->AddPage();
+$pdf->SetFont('Arial','B',16);
+$pdf->Cell(40,10,'Hello World!');
+$pdf->Output();
+?>
+$pdf = new FPDF('P','mm','A4');
+
+L
), other page sizes (such as Letter
and
+Legal
) and units (pt
, cm
, in
).
+$pdf->SetFont('Arial','B',16);
+
+$pdf->Cell(40,10,'Hello World !',1);
+
+$pdf->Cell(60,10,'Powered by FPDF.',0,1,'C');
+
+<?php
+require('fpdf.php');
+
+class PDF extends FPDF
+{
+// Page header
+function Header()
+{
+ // Logo
+ $this->Image('logo.png',10,6,30);
+ // Arial bold 15
+ $this->SetFont('Arial','B',15);
+ // Move to the right
+ $this->Cell(80);
+ // Title
+ $this->Cell(30,10,'Title',1,0,'C');
+ // Line break
+ $this->Ln(20);
+}
+
+// Page footer
+function Footer()
+{
+ // Position at 1.5 cm from bottom
+ $this->SetY(-15);
+ // Arial italic 8
+ $this->SetFont('Arial','I',8);
+ // Page number
+ $this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
+}
+}
+
+// Instanciation of inherited class
+$pdf = new PDF();
+$pdf->AliasNbPages();
+$pdf->AddPage();
+$pdf->SetFont('Times','',12);
+for($i=1;$i<=40;$i++)
+ $pdf->Cell(0,10,'Printing line number '.$i,0,1);
+$pdf->Output();
+?>
+{nb}
which is substituted when the document is finished
+(provided you first called AliasNbPages()).
+<?php
+require('fpdf.php');
+
+class PDF extends FPDF
+{
+function Header()
+{
+ global $title;
+
+ // Arial bold 15
+ $this->SetFont('Arial','B',15);
+ // Calculate width of title and position
+ $w = $this->GetStringWidth($title)+6;
+ $this->SetX((210-$w)/2);
+ // Colors of frame, background and text
+ $this->SetDrawColor(0,80,180);
+ $this->SetFillColor(230,230,0);
+ $this->SetTextColor(220,50,50);
+ // Thickness of frame (1 mm)
+ $this->SetLineWidth(1);
+ // Title
+ $this->Cell($w,9,$title,1,1,'C',true);
+ // Line break
+ $this->Ln(10);
+}
+
+function Footer()
+{
+ // Position at 1.5 cm from bottom
+ $this->SetY(-15);
+ // Arial italic 8
+ $this->SetFont('Arial','I',8);
+ // Text color in gray
+ $this->SetTextColor(128);
+ // Page number
+ $this->Cell(0,10,'Page '.$this->PageNo(),0,0,'C');
+}
+
+function ChapterTitle($num, $label)
+{
+ // Arial 12
+ $this->SetFont('Arial','',12);
+ // Background color
+ $this->SetFillColor(200,220,255);
+ // Title
+ $this->Cell(0,6,"Chapter $num : $label",0,1,'L',true);
+ // Line break
+ $this->Ln(4);
+}
+
+function ChapterBody($file)
+{
+ // Read text file
+ $txt = file_get_contents($file);
+ // Times 12
+ $this->SetFont('Times','',12);
+ // Output justified text
+ $this->MultiCell(0,5,$txt);
+ // Line break
+ $this->Ln();
+ // Mention in italics
+ $this->SetFont('','I');
+ $this->Cell(0,5,'(end of excerpt)');
+}
+
+function PrintChapter($num, $title, $file)
+{
+ $this->AddPage();
+ $this->ChapterTitle($num,$title);
+ $this->ChapterBody($file);
+}
+}
+
+$pdf = new PDF();
+$title = '20000 Leagues Under the Seas';
+$pdf->SetTitle($title);
+$pdf->SetAuthor('Jules Verne');
+$pdf->PrintChapter(1,'A RUNAWAY REEF','20k_c1.txt');
+$pdf->PrintChapter(2,'THE PROS AND CONS','20k_c2.txt');
+$pdf->Output();
+?>
+true
indicates that the background must
+be filled).
+<?php
+require('fpdf.php');
+
+class PDF extends FPDF
+{
+protected $col = 0; // Current column
+protected $y0; // Ordinate of column start
+
+function Header()
+{
+ // Page header
+ global $title;
+
+ $this->SetFont('Arial','B',15);
+ $w = $this->GetStringWidth($title)+6;
+ $this->SetX((210-$w)/2);
+ $this->SetDrawColor(0,80,180);
+ $this->SetFillColor(230,230,0);
+ $this->SetTextColor(220,50,50);
+ $this->SetLineWidth(1);
+ $this->Cell($w,9,$title,1,1,'C',true);
+ $this->Ln(10);
+ // Save ordinate
+ $this->y0 = $this->GetY();
+}
+
+function Footer()
+{
+ // Page footer
+ $this->SetY(-15);
+ $this->SetFont('Arial','I',8);
+ $this->SetTextColor(128);
+ $this->Cell(0,10,'Page '.$this->PageNo(),0,0,'C');
+}
+
+function SetCol($col)
+{
+ // Set position at a given column
+ $this->col = $col;
+ $x = 10+$col*65;
+ $this->SetLeftMargin($x);
+ $this->SetX($x);
+}
+
+function AcceptPageBreak()
+{
+ // Method accepting or not automatic page break
+ if($this->col<2)
+ {
+ // Go to next column
+ $this->SetCol($this->col+1);
+ // Set ordinate to top
+ $this->SetY($this->y0);
+ // Keep on page
+ return false;
+ }
+ else
+ {
+ // Go back to first column
+ $this->SetCol(0);
+ // Page break
+ return true;
+ }
+}
+
+function ChapterTitle($num, $label)
+{
+ // Title
+ $this->SetFont('Arial','',12);
+ $this->SetFillColor(200,220,255);
+ $this->Cell(0,6,"Chapter $num : $label",0,1,'L',true);
+ $this->Ln(4);
+ // Save ordinate
+ $this->y0 = $this->GetY();
+}
+
+function ChapterBody($file)
+{
+ // Read text file
+ $txt = file_get_contents($file);
+ // Font
+ $this->SetFont('Times','',12);
+ // Output text in a 6 cm width column
+ $this->MultiCell(60,5,$txt);
+ $this->Ln();
+ // Mention
+ $this->SetFont('','I');
+ $this->Cell(0,5,'(end of excerpt)');
+ // Go back to first column
+ $this->SetCol(0);
+}
+
+function PrintChapter($num, $title, $file)
+{
+ // Add chapter
+ $this->AddPage();
+ $this->ChapterTitle($num,$title);
+ $this->ChapterBody($file);
+}
+}
+
+$pdf = new PDF();
+$title = '20000 Leagues Under the Seas';
+$pdf->SetTitle($title);
+$pdf->SetAuthor('Jules Verne');
+$pdf->PrintChapter(1,'A RUNAWAY REEF','20k_c1.txt');
+$pdf->PrintChapter(2,'THE PROS AND CONS','20k_c2.txt');
+$pdf->Output();
+?>
+<?php
+require('fpdf.php');
+
+class PDF extends FPDF
+{
+// Load data
+function LoadData($file)
+{
+ // Read file lines
+ $lines = file($file);
+ $data = array();
+ foreach($lines as $line)
+ $data[] = explode(';',trim($line));
+ return $data;
+}
+
+// Simple table
+function BasicTable($header, $data)
+{
+ // Header
+ foreach($header as $col)
+ $this->Cell(40,7,$col,1);
+ $this->Ln();
+ // Data
+ foreach($data as $row)
+ {
+ foreach($row as $col)
+ $this->Cell(40,6,$col,1);
+ $this->Ln();
+ }
+}
+
+// Better table
+function ImprovedTable($header, $data)
+{
+ // Column widths
+ $w = array(40, 35, 40, 45);
+ // Header
+ for($i=0;$i<count($header);$i++)
+ $this->Cell($w[$i],7,$header[$i],1,0,'C');
+ $this->Ln();
+ // Data
+ foreach($data as $row)
+ {
+ $this->Cell($w[0],6,$row[0],'LR');
+ $this->Cell($w[1],6,$row[1],'LR');
+ $this->Cell($w[2],6,number_format($row[2]),'LR',0,'R');
+ $this->Cell($w[3],6,number_format($row[3]),'LR',0,'R');
+ $this->Ln();
+ }
+ // Closing line
+ $this->Cell(array_sum($w),0,'','T');
+}
+
+// Colored table
+function FancyTable($header, $data)
+{
+ // Colors, line width and bold font
+ $this->SetFillColor(255,0,0);
+ $this->SetTextColor(255);
+ $this->SetDrawColor(128,0,0);
+ $this->SetLineWidth(.3);
+ $this->SetFont('','B');
+ // Header
+ $w = array(40, 35, 40, 45);
+ for($i=0;$i<count($header);$i++)
+ $this->Cell($w[$i],7,$header[$i],1,0,'C',true);
+ $this->Ln();
+ // Color and font restoration
+ $this->SetFillColor(224,235,255);
+ $this->SetTextColor(0);
+ $this->SetFont('');
+ // Data
+ $fill = false;
+ foreach($data as $row)
+ {
+ $this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
+ $this->Cell($w[1],6,$row[1],'LR',0,'L',$fill);
+ $this->Cell($w[2],6,number_format($row[2]),'LR',0,'R',$fill);
+ $this->Cell($w[3],6,number_format($row[3]),'LR',0,'R',$fill);
+ $this->Ln();
+ $fill = !$fill;
+ }
+ // Closing line
+ $this->Cell(array_sum($w),0,'','T');
+}
+}
+
+$pdf = new PDF();
+// Column headings
+$header = array('Country', 'Capital', 'Area (sq km)', 'Pop. (thousands)');
+// Data loading
+$data = $pdf->LoadData('countries.txt');
+$pdf->SetFont('Arial','',14);
+$pdf->AddPage();
+$pdf->BasicTable($header,$data);
+$pdf->AddPage();
+$pdf->ImprovedTable($header,$data);
+$pdf->AddPage();
+$pdf->FancyTable($header,$data);
+$pdf->Output();
+?>
+border
parameter of the Cell() method, which specifies which sides of the
+cell must be drawn. Here we want the left (L
) and right (R
) ones. It remains
+the problem of the horizontal line to finish the table. There are two possibilities: either
+check for the last line in the loop, in which case we use LRB
for the border
+parameter; or, as done here, add the line once the loop is over.
+<?php
+require('fpdf.php');
+
+class PDF extends FPDF
+{
+protected $B = 0;
+protected $I = 0;
+protected $U = 0;
+protected $HREF = '';
+
+function WriteHTML($html)
+{
+ // HTML parser
+ $html = str_replace("\n",' ',$html);
+ $a = preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
+ foreach($a as $i=>$e)
+ {
+ if($i%2==0)
+ {
+ // Text
+ if($this->HREF)
+ $this->PutLink($this->HREF,$e);
+ else
+ $this->Write(5,$e);
+ }
+ else
+ {
+ // Tag
+ if($e[0]=='/')
+ $this->CloseTag(strtoupper(substr($e,1)));
+ else
+ {
+ // Extract attributes
+ $a2 = explode(' ',$e);
+ $tag = strtoupper(array_shift($a2));
+ $attr = array();
+ foreach($a2 as $v)
+ {
+ if(preg_match('/([^=]*)=["\']?([^"\']*)/',$v,$a3))
+ $attr[strtoupper($a3[1])] = $a3[2];
+ }
+ $this->OpenTag($tag,$attr);
+ }
+ }
+ }
+}
+
+function OpenTag($tag, $attr)
+{
+ // Opening tag
+ if($tag=='B' || $tag=='I' || $tag=='U')
+ $this->SetStyle($tag,true);
+ if($tag=='A')
+ $this->HREF = $attr['HREF'];
+ if($tag=='BR')
+ $this->Ln(5);
+}
+
+function CloseTag($tag)
+{
+ // Closing tag
+ if($tag=='B' || $tag=='I' || $tag=='U')
+ $this->SetStyle($tag,false);
+ if($tag=='A')
+ $this->HREF = '';
+}
+
+function SetStyle($tag, $enable)
+{
+ // Modify style and select corresponding font
+ $this->$tag += ($enable ? 1 : -1);
+ $style = '';
+ foreach(array('B', 'I', 'U') as $s)
+ {
+ if($this->$s>0)
+ $style .= $s;
+ }
+ $this->SetFont('',$style);
+}
+
+function PutLink($URL, $txt)
+{
+ // Put a hyperlink
+ $this->SetTextColor(0,0,255);
+ $this->SetStyle('U',true);
+ $this->Write(5,$txt,$URL);
+ $this->SetStyle('U',false);
+ $this->SetTextColor(0);
+}
+}
+
+$html = 'You can now easily print text mixing different styles: <b>bold</b>, <i>italic</i>,
+<u>underlined</u>, or <b><i><u>all at once</u></i></b>!<br><br>You can also insert links on
+text, such as <a href="http://www.fpdf.org">www.fpdf.org</a>, or on an image: click on the logo.';
+
+$pdf = new PDF();
+// First page
+$pdf->AddPage();
+$pdf->SetFont('Arial','',20);
+$pdf->Write(5,"To find out what's new in this tutorial, click ");
+$pdf->SetFont('','U');
+$link = $pdf->AddLink();
+$pdf->Write(5,'here',$link);
+$pdf->SetFont('');
+// Second page
+$pdf->AddPage();
+$pdf->SetLink($link);
+$pdf->Image('logo.png',10,12,30,0,'','http://www.fpdf.org');
+$pdf->SetLeftMargin(45);
+$pdf->SetFontSize(14);
+$pdf->WriteHTML($html);
+$pdf->Output();
+?>
+MakeFont(string fontfile [, string enc [, boolean embed [, boolean subset]]])
+fontfile
Path to the .ttf, .otf or .pfb file.
+enc
Name of the encoding to use. Default value: cp1252
.
embed
Whether to embed the font or not. Default value: true
.
subset
Whether to subset the font or not. Default value: true
.
$file
in the .php file accordingly.
+<?php
+require('makefont/makefont.php');
+
+MakeFont('C:\\Windows\\Fonts\\comic.ttf','cp1252');
+?>
+$pdf->AddFont('Comic','','comic.php');
+
+$pdf->AddFont('Comic','B','comicbd.php');
+
+<?php
+require('makefont/makefont.php');
+
+MakeFont('CevicheOne-Regular.ttf','cp1252');
+?>
+<?php
+require('fpdf.php');
+
+$pdf = new FPDF();
+$pdf->AddFont('CevicheOne','','CevicheOne-Regular.php');
+$pdf->AddPage();
+$pdf->SetFont('CevicheOne','',45);
+$pdf->Write(10,'Enjoy new fonts with FPDF!');
+$pdf->Output();
+?>
+