Lines 87.17% 68 / 78
Methods 72.22% 26 / 36
Classes 0.00% 0 / 1
Covered by tests of size
Name Lines Methods CRAP
 __construct 100.00% 5 / 5 100.00% 1 / 1 1
 open 100.00% 4 / 4 100.00% 1 / 1 1
 output 100.00% 1 / 1 100.00% 1 / 1 1
 addPage 100.00% 1 / 1 100.00% 1 / 1 1
 setPrintHeader 100.00% 1 / 1 100.00% 1 / 1 1
 setDisplayMode 100.00% 1 / 1 100.00% 1 / 1 1
 setTitle 0.00% 0 / 1 0.00% 0 / 1 2
 setAuthor 0.00% 0 / 1 0.00% 0 / 1 2
 setCreator 0.00% 0 / 1 0.00% 0 / 1 2
 bookmark 100.00% 1 / 1 100.00% 1 / 1 1
 setMargins 100.00% 1 / 1 100.00% 1 / 1 1
 setHeaderMargin 0.00% 0 / 1 0.00% 0 / 1 2
 setFooterMargin 0.00% 0 / 1 0.00% 0 / 1 2
 setFont 100.00% 1 / 1 100.00% 1 / 1 1
 setFontSubsetting 0.00% 0 / 1 0.00% 0 / 1 2
 setImageScale 0.00% 0 / 1 0.00% 0 / 1 2
 setDefaultMonospacedFont 0.00% 0 / 1 0.00% 0 / 1 2
 setRtl 100.00% 1 / 1 100.00% 1 / 1 1
 write 0.00% 0 / 1 0.00% 0 / 1 2
 ln 100.00% 1 / 1 100.00% 1 / 1 1
 writeHtml 100.00% 1 / 1 100.00% 1 / 1 1
 writeHtmlCell 100.00% 1 / 1 100.00% 1 / 1 1
 multiCell 100.00% 1 / 1 100.00% 1 / 1 1
 cell 100.00% 1 / 1 100.00% 1 / 1 1
 setY 100.00% 1 / 1 100.00% 1 / 1 1
 setTextColor 100.00% 1 / 1 100.00% 1 / 1 1
 getLastH 100.00% 1 / 1 100.00% 1 / 1 1
 addTocPage 100.00% 1 / 1 100.00% 1 / 1 1
 addToc 100.00% 1 / 1 100.00% 1 / 1 1
 endTocPage 100.00% 1 / 1 100.00% 1 / 1 1
 getAliasNumPage 100.00% 1 / 1 100.00% 1 / 1 1
 getAliasNbPages 100.00% 1 / 1 100.00% 1 / 1 1
 onHeader 100.00% 1 / 1 100.00% 1 / 1 1
 onFooter 100.00% 1 / 1 100.00% 1 / 1 1
 defineTcpdfConstants 100.00% 35 / 35 100.00% 1 / 1 3
 defineIfMissing 50.00% 1 / 2 0.00% 0 / 1 2.50
24final readonly class TcpdfEngine implements PdfEngineInterface
25{
26    private TcpdfDocument $document;
27
28    public function __construct()
29    {
30        self::defineTcpdfConstants();
31
32        $this->document = new TcpdfDocument(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT);
33        $this->document->setFontSubsetting(false);
34        $this->document->setImageScale(PDF_IMAGE_SCALE_RATIO);
35        $this->document->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
36    }
37
38    public function open(): void
39    {
40        $this->document->Open();
41        $this->document->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
42        $this->document->SetHeaderMargin(PDF_MARGIN_HEADER);
43        $this->document->SetFooterMargin(PDF_MARGIN_FOOTER);
44    }
45
46    public function output(string $name, string $dest): string
47    {
48        return (string) $this->document->Output($name, $dest);
49    }
50
51    public function addPage(): void
52    {
53        $this->document->AddPage();
54    }
55
56    public function setPrintHeader(bool $val): void
57    {
58        $this->document->setPrintHeader($val);
59    }
60
61    public function setDisplayMode(mixed $zoom): void
62    {
63        $this->document->SetDisplayMode($zoom);
64    }
65
66    public function setTitle(string $title): void
67    {
68        $this->document->SetTitle($title);
69    }
70
71    public function setAuthor(string $author): void
72    {
73        $this->document->SetAuthor($author);
74    }
75
76    public function setCreator(string $creator): void
77    {
78        $this->document->SetCreator($creator);
79    }
80
81    public function bookmark(string $txt, int $level = 0, float $y = -1): void
82    {
83        $this->document->Bookmark($txt, $level, $y);
84    }
85
86    public function setMargins(float $left, float $top, float $right = -1): void
87    {
88        $this->document->SetMargins($left, $top, $right);
89    }
90
91    public function setHeaderMargin(float $margin): void
92    {
93        $this->document->SetHeaderMargin($margin);
94    }
95
96    public function setFooterMargin(float $margin): void
97    {
98        $this->document->SetFooterMargin($margin);
99    }
100
101    public function setFont(string $family, string $style = '', float $size = 0): void
102    {
103        $this->document->SetFont($family, $style, $size);
104    }
105
106    public function setFontSubsetting(bool $enable): void
107    {
108        $this->document->setFontSubsetting($enable);
109    }
110
111    public function setImageScale(float $scale): void
112    {
113        $this->document->setImageScale($scale);
114    }
115
116    public function setDefaultMonospacedFont(string $font): void
117    {
118        $this->document->SetDefaultMonospacedFont($font);
119    }
120
121    public function setRtl(bool $enable): void
122    {
123        $this->document->setRTL($enable);
124    }
125
126    public function write(float $h, string $txt): void
127    {
128        $this->document->Write($h, $txt);
129    }
130
131    public function ln(?float $h = null): void
132    {
133        $this->document->Ln($h);
134    }
135
136    public function writeHtml(
137        string $html,
138        bool $ln = true,
139        bool $fill = false,
140        bool $reseth = false,
141        bool $cell = false,
142        string $align = '',
143    ): void {
144        $this->document->writeHTML($html, $ln, $fill, $reseth, $cell, $align);
145    }
146
147    /* @mago-expect lint:excessive-parameter-list - mirrors the TCPDF method signature */
148    public function writeHtmlCell(
149        float $w,
150        float $h,
151        ?float $x,
152        ?float $y,
153        string $html,
154        mixed $border = 0,
155        int $ln = 0,
156        bool $fill = false,
157        bool $reseth = true,
158        string $align = '',
159    ): void {
160        $this->document->writeHTMLCell($w, $h, $x, $y, $html, $border, $ln, $fill, $reseth, $align);
161    }
162
163    public function multiCell(float $w, float $h, string $txt, mixed $border = 0, string $align = 'J'): void
164    {
165        $this->document->MultiCell($w, $h, $txt, $border, $align);
166    }
167
168    /* @mago-expect lint:excessive-parameter-list - mirrors the TCPDF method signature */
169    public function cell(
170        float $w,
171        float $h,
172        string $txt,
173        mixed $border = 0,
174        int $ln = 0,
175        string $align = '',
176        bool $fill = false,
177        string $link = '',
178    ): void {
179        $this->document->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);
180    }
181
182    public function setY(float $y): void
183    {
184        $this->document->SetY($y);
185    }
186
187    public function setTextColor(int $col1, int $col2 = -1, int $col3 = -1): void
188    {
189        $this->document->SetTextColor($col1, $col2, $col3);
190    }
191
192    public function getLastH(): float
193    {
194        return $this->document->getLastH();
195    }
196
197    public function addTocPage(): void
198    {
199        $this->document->addTOCPage();
200    }
201
202    public function addToc(
203        int $page,
204        string $numbersfont,
205        string $filler,
206        string $tocName,
207        string $style,
208        array $color,
209    ): void {
210        $this->document->addTOC($page, $numbersfont, $filler, $tocName, $style, $color);
211    }
212
213    public function endTocPage(): void
214    {
215        $this->document->endTOCPage();
216    }
217
218    public function getAliasNumPage(): string
219    {
220        return $this->document->getAliasNumPage();
221    }
222
223    public function getAliasNbPages(): string
224    {
225        return $this->document->getAliasNbPages();
226    }
227
228    public function onHeader(callable $renderer): void
229    {
230        $this->document->setHeaderRenderer($renderer);
231    }
232
233    public function onFooter(callable $renderer): void
234    {
235        $this->document->setFooterRenderer($renderer);
236    }
237
238    private static function defineTcpdfConstants(): void
239    {
240        // Note: this file lives one directory deeper (Engine/) than the original
241        // Wrapper, so the fallback paths carry one extra "../" to resolve identically.
242        $pmfRootDir = defined('PMF_ROOT_DIR') ? (string) PMF_ROOT_DIR : __DIR__ . '/../../../../';
243        $pmfSrcDir = defined('PMF_SRC_DIR') ? (string) PMF_SRC_DIR : __DIR__ . '/../../../';
244
245        self::defineIfMissing('K_TCPDF_EXTERNAL_CONFIG', true);
246        self::defineIfMissing('K_PATH_URL', '');
247        self::defineIfMissing('K_PATH_MAIN', $pmfSrcDir . '/libs/tecnickcom/tcpdf/');
248        self::defineIfMissing('K_PATH_FONTS', $pmfSrcDir . '/fonts/');
249        self::defineIfMissing('K_PATH_CACHE', $pmfRootDir . '/content/user/images/');
250        self::defineIfMissing('K_PATH_URL_CACHE', K_PATH_CACHE);
251        self::defineIfMissing('K_PATH_IMAGES', $pmfRootDir . '/content/user/images/');
252        self::defineIfMissing('K_BLANK_IMAGE', (string) constant('K_PATH_IMAGES') . '_blank.png');
253        self::defineIfMissing('PDF_PAGE_FORMAT', 'A4');
254        self::defineIfMissing('PDF_PAGE_ORIENTATION', 'P');
255        self::defineIfMissing('PDF_CREATOR', 'TCPDF');
256        self::defineIfMissing('PDF_AUTHOR', 'TCPDF');
257        self::defineIfMissing('PDF_HEADER_TITLE', 'phpMyFAQ');
258        self::defineIfMissing('PDF_HEADER_STRING', 'by phpMyFAQ - www.phpmyfaq.de');
259        self::defineIfMissing('PDF_HEADER_LOGO', 'tcpdf_logo.jpg');
260        self::defineIfMissing('PDF_HEADER_LOGO_WIDTH', 30);
261        self::defineIfMissing('PDF_UNIT', 'mm');
262        self::defineIfMissing('PDF_MARGIN_HEADER', 5);
263        self::defineIfMissing('PDF_MARGIN_FOOTER', 10);
264        self::defineIfMissing('PDF_MARGIN_TOP', 27);
265        self::defineIfMissing('PDF_MARGIN_BOTTOM', 25);
266        self::defineIfMissing('PDF_MARGIN_LEFT', 15);
267        self::defineIfMissing('PDF_MARGIN_RIGHT', 15);
268        self::defineIfMissing('PDF_FONT_NAME_MAIN', 'dejavusans');
269        self::defineIfMissing('PDF_FONT_SIZE_MAIN', 10);
270        self::defineIfMissing('PDF_FONT_NAME_DATA', 'dejavusans');
271        self::defineIfMissing('PDF_FONT_SIZE_DATA', 8);
272        self::defineIfMissing('PDF_FONT_MONOSPACED', 'DejaVuSansMono');
273        self::defineIfMissing('PDF_IMAGE_SCALE_RATIO', 1);
274        self::defineIfMissing('HEAD_MAGNIFICATION', 1.1);
275        self::defineIfMissing('K_CELL_HEIGHT_RATIO', 1.25);
276        self::defineIfMissing('K_TITLE_MAGNIFICATION', 1.3);
277        self::defineIfMissing('K_SMALL_RATIO', 2 / 3);
278    }
279
280    private static function defineIfMissing(string $name, mixed $value): void
281    {
282        if (!defined($name)) {
283            define($name, $value);
284        }
285    }
286}