Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.74% covered (success)
94.74%
36 / 38
85.71% covered (success)
85.71%
12 / 14
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractCompiler
94.74% covered (success)
94.74%
36 / 38
85.71% covered (success)
85.71%
12 / 14
19.05
0.00% covered (danger)
0.00%
0 / 1
 getDocument
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRoot
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParent
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getInfo
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFonts
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFontReferences
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 lastIndex
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getOutput
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRoot
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setParent
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setInfo
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 calculateByteLength
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 formatByteLength
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCoordinates
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
5
 setDocument
n/a
0 / 0
n/a
0 / 0
0
 finalize
n/a
0 / 0
n/a
0 / 0
0
 prepareFonts
n/a
0 / 0
n/a
0 / 0
0
 prepareImages
n/a
0 / 0
n/a
0 / 0
0
 prepareText
n/a
0 / 0
n/a
0 / 0
0
 prepareAnnotations
n/a
0 / 0
n/a
0 / 0
0
 preparePaths
n/a
0 / 0
n/a
0 / 0
0
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Pdf\Build;
15
16use Pop\Pdf\Document;
17
18/**
19 * Abstract Pdf compiler class
20 *
21 * @category   Pop
22 * @package    Pop\Pdf
23 * @author     Nick Sagona, III <dev@nolainteractive.com>
24 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
25 * @license    http://www.popphp.org/license     New BSD License
26 * @version    5.0.0
27 */
28abstract class AbstractCompiler implements CompilerInterface
29{
30
31    /**
32     * Root object
33     * @var ?PdfObject\RootObject
34     */
35    protected ?PdfObject\RootObject $root = null;
36
37    /**
38     * Parent object
39     * @var ?PdfObject\ParentObject
40     */
41    protected ?PdfObject\ParentObject$parent = null;
42
43    /**
44     * Info object
45     * @var ?PdfObject\InfoObject
46     */
47    protected ?PdfObject\InfoObject$info = null;
48
49    /**
50     * Document object
51     * @var ?Document
52     */
53    protected ?Document $document = null;
54
55    /**
56     * Pages array
57     * @var array
58     */
59    protected array $pages = [];
60
61    /**
62     * Objects array
63     * @var array
64     */
65    protected array $objects = [];
66
67    /**
68     * Fonts array
69     * @var array
70     */
71    protected array $fonts = [];
72
73    /**
74     * Font references
75     * @var array
76     */
77    protected array $fontReferences = [];
78
79    /**
80     * Compression property
81     * @var bool
82     */
83    protected bool $compression = true;
84
85    /**
86     * PDF byte length
87     * @var ?int
88     */
89    protected ?int $byteLength = null;
90
91    /**
92     * PDF document trailer
93     * @var ?string
94     */
95    protected ?string $trailer = null;
96
97    /**
98     * PDF document output buffer
99     * @var ?string
100     */
101    protected ?string $output = null;
102
103    /**
104     * Get the document object
105     *
106     * @return ?Document
107     */
108    public function getDocument(): ?Document
109    {
110        return $this->document;
111    }
112
113    /**
114     * Get the root object
115     *
116     * @return ?PdfObject\RootObject
117     */
118    public function getRoot(): ?PdfObject\RootObject
119    {
120        return $this->root;
121    }
122
123    /**
124     * Get the parent object
125     *
126     * @return ?PdfObject\ParentObject
127     */
128    public function getParent(): ?PdfObject\ParentObject
129    {
130        return $this->parent;
131    }
132
133    /**
134     * Get the info object
135     *
136     * @return ?PdfObject\InfoObject
137     */
138    public function getInfo(): ?PdfObject\InfoObject
139    {
140        return $this->info;
141    }
142
143    /**
144     * Get the fonts
145     *
146     * @return array
147     */
148    public function getFonts(): array
149    {
150        return $this->fonts;
151    }
152
153    /**
154     * Get the font references
155     *
156     * @return array
157     */
158    public function getFontReferences(): array
159    {
160        return $this->fontReferences;
161    }
162
163    /**
164     * Return the last object index.
165     *
166     * @return int
167     */
168    public function lastIndex(): int
169    {
170        if (count($this->objects) == 0) {
171            return 0;
172        } else {
173            $indices = array_keys($this->objects);
174            sort($indices);
175            return $indices[count($indices) - 1];
176        }
177    }
178
179    /**
180     * Get the compiled output
181     *
182     * @return string
183     */
184    public function getOutput(): string
185    {
186        return $this->output;
187    }
188
189    /**
190     * Set the root object
191     *
192     * @param  PdfObject\RootObject $root
193     * @return AbstractCompiler
194     */
195    protected function setRoot(PdfObject\RootObject $root): AbstractCompiler
196    {
197        $this->root = $root;
198        $this->objects[$this->root->getIndex()] = $this->root;
199        return $this;
200    }
201
202    /**
203     * Set the parent object
204     *
205     * @param  PdfObject\ParentObject $parent
206     * @return AbstractCompiler
207     */
208    protected function setParent(PdfObject\ParentObject $parent): AbstractCompiler
209    {
210        $this->parent = $parent;
211        $this->objects[$this->parent->getIndex()] = $this->parent;
212        return $this;
213    }
214
215    /**
216     * Set the info object
217     *
218     * @param  PdfObject\InfoObject $info
219     * @return AbstractCompiler
220     */
221    protected function setInfo(PdfObject\InfoObject $info): AbstractCompiler
222    {
223        $this->info = $info;
224        $this->objects[$this->info->getIndex()] = $this->info;
225        return $this;
226    }
227
228    /**
229     * Calculate byte length
230     *
231     * @param  ?string $string
232     * @return int
233     */
234    protected function calculateByteLength(?string $string): int
235    {
236        return strlen((string)$string);
237    }
238
239    /**
240     * Format byte length
241     *
242     * @param  int|string $num
243     * @return string
244     */
245    protected function formatByteLength(int|string $num): string
246    {
247        return sprintf('%010d', $num);
248    }
249
250    /**
251     * Get coordinates based on document origin
252     *
253     * @param  int $x
254     * @param  int $y
255     * @param  PdfObject\PageObject $pageObject
256     * @return array
257     */
258    protected function getCoordinates(int $x, int $y, PdfObject\PageObject $pageObject): array
259    {
260        $coordinates = ['x' => $x, 'y' => $y];
261        $width       = $pageObject->getWidth();
262        $height      = $pageObject->getHeight();
263
264        switch ($this->document->getOrigin()) {
265            case \Pop\Pdf\Document::ORIGIN_TOP_LEFT:
266                $coordinates['y'] = $height - $y;
267                break;
268            case \Pop\Pdf\Document::ORIGIN_TOP_RIGHT:
269                $coordinates['x'] = $width - $x;
270                $coordinates['y'] = $height - $y;
271                break;
272            case \Pop\Pdf\Document::ORIGIN_BOTTOM_RIGHT:
273                $coordinates['x'] = $width - $x;
274                break;
275            case \Pop\Pdf\Document::ORIGIN_CENTER:
276                $coordinates['x'] = round($width / 2) + $x;
277                $coordinates['y'] = round($height / 2) + $y;
278                break;
279        }
280
281        return $coordinates;
282    }
283
284    /**
285     * Set the document object
286     *
287     * @param  Document\AbstractDocument $document
288     * @return Compiler
289     */
290    abstract public function setDocument(Document\AbstractDocument $document): Compiler;
291
292    /**
293     * Compile and finalize the PDF document
294     *
295     * @param  ?Document\AbstractDocument $document
296     * @return void
297     */
298    abstract public function finalize(Document\AbstractDocument $document = null): void;
299
300    /**
301     * Prepare the font objects
302     *
303     * @return void
304     */
305    abstract public function prepareFonts(): void;
306
307    /**
308     * Prepare the image objects
309     *
310     * @param  array $images
311     * @param  PdfObject\PageObject $pageObject
312     * @return void
313     */
314    abstract protected function prepareImages(array $images, PdfObject\PageObject $pageObject): void;
315
316    /**
317     * Prepare the text objects
318     *
319     * @param  array $text
320     * @param  PdfObject\PageObject $pageObject
321     * @return void
322     */
323    abstract protected function prepareText(array $text, PdfObject\PageObject $pageObject): void;
324
325    /**
326     * Prepare the annotation objects
327     *
328     * @param  array $annotations
329     * @param  PdfObject\PageObject $pageObject
330     * @return void
331     */
332    abstract protected function prepareAnnotations(array $annotations, PdfObject\PageObject $pageObject): void;
333
334    /**
335     * Prepare the path objects
336     *
337     * @param  array $paths
338     * @param  PdfObject\PageObject $pageObject
339     * @return void
340     */
341    abstract protected function preparePaths(array $paths, PdfObject\PageObject $pageObject): void;
342
343}