1b6f35a76SGreg Roach<?php 2b6f35a76SGreg Roach 3b6f35a76SGreg Roach/** 4b6f35a76SGreg Roach * webtrees: online genealogy 589f7189bSGreg Roach * Copyright (C) 2021 webtrees development team 6b6f35a76SGreg Roach * This program is free software: you can redistribute it and/or modify 7b6f35a76SGreg Roach * it under the terms of the GNU General Public License as published by 8b6f35a76SGreg Roach * the Free Software Foundation, either version 3 of the License, or 9b6f35a76SGreg Roach * (at your option) any later version. 10b6f35a76SGreg Roach * This program is distributed in the hope that it will be useful, 11b6f35a76SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12b6f35a76SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13b6f35a76SGreg Roach * GNU General Public License for more details. 14b6f35a76SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 16b6f35a76SGreg Roach */ 17b6f35a76SGreg Roach 18b6f35a76SGreg Roachdeclare(strict_types=1); 19b6f35a76SGreg Roach 20b6f35a76SGreg Roachnamespace Fisharebest\Webtrees\Report; 21b6f35a76SGreg Roach 22b6f35a76SGreg Roachuse Fisharebest\Webtrees\MediaFile; 23b6f35a76SGreg Roachuse Fisharebest\Webtrees\Webtrees; 24f7cf8a15SGreg Roachuse League\Flysystem\FilesystemOperator; 25b6f35a76SGreg Roach 26b6f35a76SGreg Roachuse function count; 27b6f35a76SGreg Roach 28b6f35a76SGreg Roach/** 29b6f35a76SGreg Roach * Class PdfRenderer 30b6f35a76SGreg Roach */ 31b6f35a76SGreg Roachclass PdfRenderer extends AbstractRenderer 32b6f35a76SGreg Roach{ 33b6f35a76SGreg Roach /** 34b6f35a76SGreg Roach * PDF compression - Zlib extension is required 35b6f35a76SGreg Roach * 36b6f35a76SGreg Roach * @var bool const 37b6f35a76SGreg Roach */ 38b6f35a76SGreg Roach private const COMPRESSION = true; 39b6f35a76SGreg Roach 40b6f35a76SGreg Roach /** 41b6f35a76SGreg Roach * If true reduce the RAM memory usage by caching temporary data on filesystem (slower). 42b6f35a76SGreg Roach * 43b6f35a76SGreg Roach * @var bool const 44b6f35a76SGreg Roach */ 45b6f35a76SGreg Roach private const DISK_CACHE = false; 46b6f35a76SGreg Roach 47b6f35a76SGreg Roach /** 48b6f35a76SGreg Roach * true means that the input text is unicode (PDF) 49b6f35a76SGreg Roach * 50b6f35a76SGreg Roach * @var bool const 51b6f35a76SGreg Roach */ 52b6f35a76SGreg Roach private const UNICODE = true; 53b6f35a76SGreg Roach 54b6f35a76SGreg Roach /** 55b6f35a76SGreg Roach * false means that the full font is embedded, true means only the used chars 56b6f35a76SGreg Roach * in TCPDF v5.9 font subsetting is a very slow process, this leads to larger files 57b6f35a76SGreg Roach * 58b6f35a76SGreg Roach * @var bool const 59b6f35a76SGreg Roach */ 60b6f35a76SGreg Roach private const SUBSETTING = false; 61b6f35a76SGreg Roach 62b6f35a76SGreg Roach /** 63b6f35a76SGreg Roach * @var TcpdfWrapper 64b6f35a76SGreg Roach */ 65b6f35a76SGreg Roach public $tcpdf; 66b6f35a76SGreg Roach 67b6f35a76SGreg Roach /** @var ReportBaseElement[] Array of elements in the header */ 68b6f35a76SGreg Roach public $headerElements = []; 69b6f35a76SGreg Roach 70b6f35a76SGreg Roach /** @var ReportBaseElement[] Array of elements in the footer */ 71b6f35a76SGreg Roach public $footerElements = []; 72b6f35a76SGreg Roach 73b6f35a76SGreg Roach /** @var ReportBaseElement[] Array of elements in the body */ 74b6f35a76SGreg Roach public $bodyElements = []; 75b6f35a76SGreg Roach 76b6f35a76SGreg Roach /** @var ReportPdfFootnote[] Array of elements in the footer notes */ 77b6f35a76SGreg Roach public $printedfootnotes = []; 78b6f35a76SGreg Roach 79b6f35a76SGreg Roach /** @var string Currently used style name */ 80b6f35a76SGreg Roach public $currentStyle = ''; 81b6f35a76SGreg Roach 82b6f35a76SGreg Roach /** @var float The last cell height */ 83b6f35a76SGreg Roach public $lastCellHeight = 0; 84b6f35a76SGreg Roach 85b6f35a76SGreg Roach /** @var float The largest font size within a TextBox to calculate the height */ 86b6f35a76SGreg Roach public $largestFontHeight = 0; 87b6f35a76SGreg Roach 88b6f35a76SGreg Roach /** @var int The last pictures page number */ 89b6f35a76SGreg Roach public $lastpicpage = 0; 90b6f35a76SGreg Roach 91b6f35a76SGreg Roach /** @var PdfRenderer The current report. */ 92b6f35a76SGreg Roach public $wt_report; 93b6f35a76SGreg Roach 94b6f35a76SGreg Roach /** 95b6f35a76SGreg Roach * PDF Header -PDF 96b6f35a76SGreg Roach * 97b6f35a76SGreg Roach * @return void 98b6f35a76SGreg Roach */ 99b6f35a76SGreg Roach public function header(): void 100b6f35a76SGreg Roach { 101b6f35a76SGreg Roach foreach ($this->headerElements as $element) { 102b6f35a76SGreg Roach if ($element instanceof ReportBaseElement) { 103b6f35a76SGreg Roach $element->render($this); 104b6f35a76SGreg Roach } elseif ($element === 'footnotetexts') { 105b6f35a76SGreg Roach $this->footnotes(); 106b6f35a76SGreg Roach } elseif ($element === 'addpage') { 107b6f35a76SGreg Roach $this->newPage(); 108b6f35a76SGreg Roach } 109b6f35a76SGreg Roach } 110b6f35a76SGreg Roach } 111b6f35a76SGreg Roach 112b6f35a76SGreg Roach /** 113b6f35a76SGreg Roach * PDF Body -PDF 114b6f35a76SGreg Roach * 115b6f35a76SGreg Roach * @return void 116b6f35a76SGreg Roach */ 117b6f35a76SGreg Roach public function body(): void 118b6f35a76SGreg Roach { 119b6f35a76SGreg Roach $this->tcpdf->AddPage(); 120b6f35a76SGreg Roach 121b6f35a76SGreg Roach foreach ($this->bodyElements as $key => $element) { 122b6f35a76SGreg Roach if ($element instanceof ReportBaseElement) { 123b6f35a76SGreg Roach $element->render($this); 124b6f35a76SGreg Roach } elseif ($element === 'footnotetexts') { 125b6f35a76SGreg Roach $this->footnotes(); 126b6f35a76SGreg Roach } elseif ($element === 'addpage') { 127b6f35a76SGreg Roach $this->newPage(); 128b6f35a76SGreg Roach } 129b6f35a76SGreg Roach } 130b6f35a76SGreg Roach } 131b6f35a76SGreg Roach 132b6f35a76SGreg Roach /** 133b6f35a76SGreg Roach * PDF Footnotes -PDF 134b6f35a76SGreg Roach * 135b6f35a76SGreg Roach * @return void 136b6f35a76SGreg Roach */ 137b6f35a76SGreg Roach public function footnotes(): void 138b6f35a76SGreg Roach { 139b6f35a76SGreg Roach foreach ($this->printedfootnotes as $element) { 140b6f35a76SGreg Roach if (($this->tcpdf->GetY() + $element->getFootnoteHeight($this)) > $this->tcpdf->getPageHeight()) { 141b6f35a76SGreg Roach $this->tcpdf->AddPage(); 142b6f35a76SGreg Roach } 143b6f35a76SGreg Roach 144b6f35a76SGreg Roach $element->renderFootnote($this); 145b6f35a76SGreg Roach 146b6f35a76SGreg Roach if ($this->tcpdf->GetY() > $this->tcpdf->getPageHeight()) { 147b6f35a76SGreg Roach $this->tcpdf->AddPage(); 148b6f35a76SGreg Roach } 149b6f35a76SGreg Roach } 150b6f35a76SGreg Roach } 151b6f35a76SGreg Roach 152b6f35a76SGreg Roach /** 153b6f35a76SGreg Roach * PDF Footer -PDF 154b6f35a76SGreg Roach * 155b6f35a76SGreg Roach * @return void 156b6f35a76SGreg Roach */ 157b6f35a76SGreg Roach public function footer(): void 158b6f35a76SGreg Roach { 159b6f35a76SGreg Roach foreach ($this->footerElements as $element) { 160b6f35a76SGreg Roach if ($element instanceof ReportBaseElement) { 161b6f35a76SGreg Roach $element->render($this); 162b6f35a76SGreg Roach } elseif ($element === 'footnotetexts') { 163b6f35a76SGreg Roach $this->footnotes(); 164b6f35a76SGreg Roach } elseif ($element === 'addpage') { 165b6f35a76SGreg Roach $this->newPage(); 166b6f35a76SGreg Roach } 167b6f35a76SGreg Roach } 168b6f35a76SGreg Roach } 169b6f35a76SGreg Roach 170b6f35a76SGreg Roach /** 171b6f35a76SGreg Roach * Add an element to the Header -PDF 172b6f35a76SGreg Roach * 173b6f35a76SGreg Roach * @param ReportBaseElement|string $element 174b6f35a76SGreg Roach * 175b6f35a76SGreg Roach * @return void 176b6f35a76SGreg Roach */ 177b6f35a76SGreg Roach public function addHeader($element): void 178b6f35a76SGreg Roach { 179b6f35a76SGreg Roach $this->headerElements[] = $element; 180b6f35a76SGreg Roach } 181b6f35a76SGreg Roach 182b6f35a76SGreg Roach /** 183b6f35a76SGreg Roach * Add an element to the Body -PDF 184b6f35a76SGreg Roach * 185b6f35a76SGreg Roach * @param ReportBaseElement|string $element 186b6f35a76SGreg Roach * 187b6f35a76SGreg Roach * @return void 188b6f35a76SGreg Roach */ 189b6f35a76SGreg Roach public function addBody($element): void 190b6f35a76SGreg Roach { 191b6f35a76SGreg Roach $this->bodyElements[] = $element; 192b6f35a76SGreg Roach } 193b6f35a76SGreg Roach 194b6f35a76SGreg Roach /** 195b6f35a76SGreg Roach * Add an element to the Footer -PDF 196b6f35a76SGreg Roach * 197b6f35a76SGreg Roach * @param ReportBaseElement|string $element 198b6f35a76SGreg Roach * 199b6f35a76SGreg Roach * @return void 200b6f35a76SGreg Roach */ 201b6f35a76SGreg Roach public function addFooter($element): void 202b6f35a76SGreg Roach { 203b6f35a76SGreg Roach $this->footerElements[] = $element; 204b6f35a76SGreg Roach } 205b6f35a76SGreg Roach 206b6f35a76SGreg Roach /** 207b6f35a76SGreg Roach * Remove the header. 208b6f35a76SGreg Roach * 209b6f35a76SGreg Roach * @param int $index 210b6f35a76SGreg Roach * 211b6f35a76SGreg Roach * @return void 212b6f35a76SGreg Roach */ 213b6f35a76SGreg Roach public function removeHeader(int $index): void 214b6f35a76SGreg Roach { 215b6f35a76SGreg Roach unset($this->headerElements[$index]); 216b6f35a76SGreg Roach } 217b6f35a76SGreg Roach 218b6f35a76SGreg Roach /** 219b6f35a76SGreg Roach * Remove the body. 220b6f35a76SGreg Roach * 221b6f35a76SGreg Roach * @param int $index 222b6f35a76SGreg Roach * 223b6f35a76SGreg Roach * @return void 224b6f35a76SGreg Roach */ 225b6f35a76SGreg Roach public function removeBody(int $index): void 226b6f35a76SGreg Roach { 227b6f35a76SGreg Roach unset($this->bodyElements[$index]); 228b6f35a76SGreg Roach } 229b6f35a76SGreg Roach 230b6f35a76SGreg Roach /** 231b6f35a76SGreg Roach * Remove the footer. 232b6f35a76SGreg Roach * 233b6f35a76SGreg Roach * @param int $index 234b6f35a76SGreg Roach * 235b6f35a76SGreg Roach * @return void 236b6f35a76SGreg Roach */ 237b6f35a76SGreg Roach public function removeFooter(int $index): void 238b6f35a76SGreg Roach { 239b6f35a76SGreg Roach unset($this->footerElements[$index]); 240b6f35a76SGreg Roach } 241b6f35a76SGreg Roach 242b6f35a76SGreg Roach /** 243b6f35a76SGreg Roach * Clear the Header -PDF 244b6f35a76SGreg Roach * 245b6f35a76SGreg Roach * @return void 246b6f35a76SGreg Roach */ 247b6f35a76SGreg Roach public function clearHeader(): void 248b6f35a76SGreg Roach { 249b6f35a76SGreg Roach unset($this->headerElements); 250b6f35a76SGreg Roach $this->headerElements = []; 251b6f35a76SGreg Roach } 252b6f35a76SGreg Roach 253b6f35a76SGreg Roach /** 254b6f35a76SGreg Roach * Set the report. 255b6f35a76SGreg Roach * 256b6f35a76SGreg Roach * @param PdfRenderer $report 257b6f35a76SGreg Roach * 258b6f35a76SGreg Roach * @return void 259b6f35a76SGreg Roach */ 260b6f35a76SGreg Roach public function setReport(PdfRenderer $report): void 261b6f35a76SGreg Roach { 262b6f35a76SGreg Roach $this->wt_report = $report; 263b6f35a76SGreg Roach } 264b6f35a76SGreg Roach 265b6f35a76SGreg Roach /** 266b6f35a76SGreg Roach * Get the currently used style name -PDF 267b6f35a76SGreg Roach * 268b6f35a76SGreg Roach * @return string 269b6f35a76SGreg Roach */ 270b6f35a76SGreg Roach public function getCurrentStyle(): string 271b6f35a76SGreg Roach { 272b6f35a76SGreg Roach return $this->currentStyle; 273b6f35a76SGreg Roach } 274b6f35a76SGreg Roach 275b6f35a76SGreg Roach /** 276b6f35a76SGreg Roach * Setup a style for usage -PDF 277b6f35a76SGreg Roach * 278b6f35a76SGreg Roach * @param string $s Style name 279b6f35a76SGreg Roach * 280b6f35a76SGreg Roach * @return void 281b6f35a76SGreg Roach */ 282b6f35a76SGreg Roach public function setCurrentStyle(string $s): void 283b6f35a76SGreg Roach { 284b6f35a76SGreg Roach $this->currentStyle = $s; 285b6f35a76SGreg Roach $style = $this->wt_report->getStyle($s); 286b6f35a76SGreg Roach $this->tcpdf->SetFont($style['font'], $style['style'], $style['size']); 287b6f35a76SGreg Roach } 288b6f35a76SGreg Roach 289b6f35a76SGreg Roach /** 290b6f35a76SGreg Roach * Get the style -PDF 291b6f35a76SGreg Roach * 292b6f35a76SGreg Roach * @param string $s Style name 293b6f35a76SGreg Roach * 294b6f35a76SGreg Roach * @return array 295b6f35a76SGreg Roach */ 296b6f35a76SGreg Roach public function getStyle(string $s): array 297b6f35a76SGreg Roach { 298b6f35a76SGreg Roach if (!isset($this->wt_report->styles[$s])) { 299b6f35a76SGreg Roach $s = $this->getCurrentStyle(); 300b6f35a76SGreg Roach $this->wt_report->styles[$s] = $s; 301b6f35a76SGreg Roach } 302b6f35a76SGreg Roach 303b6f35a76SGreg Roach return $this->wt_report->styles[$s]; 304b6f35a76SGreg Roach } 305b6f35a76SGreg Roach 306b6f35a76SGreg Roach /** 307b6f35a76SGreg Roach * Add margin when static horizontal position is used -PDF 308b6f35a76SGreg Roach * RTL supported 309b6f35a76SGreg Roach * 310b6f35a76SGreg Roach * @param float $x Static position 311b6f35a76SGreg Roach * 312b6f35a76SGreg Roach * @return float 313b6f35a76SGreg Roach */ 314b6f35a76SGreg Roach public function addMarginX(float $x): float 315b6f35a76SGreg Roach { 316b6f35a76SGreg Roach $m = $this->tcpdf->getMargins(); 317b6f35a76SGreg Roach if ($this->tcpdf->getRTL()) { 318b6f35a76SGreg Roach $x += $m['right']; 319b6f35a76SGreg Roach } else { 320b6f35a76SGreg Roach $x += $m['left']; 321b6f35a76SGreg Roach } 322b6f35a76SGreg Roach $this->tcpdf->SetX($x); 323b6f35a76SGreg Roach 324b6f35a76SGreg Roach return $x; 325b6f35a76SGreg Roach } 326b6f35a76SGreg Roach 327b6f35a76SGreg Roach /** 328b6f35a76SGreg Roach * Get the maximum line width to draw from the curren position -PDF 329b6f35a76SGreg Roach * RTL supported 330b6f35a76SGreg Roach * 331b6f35a76SGreg Roach * @return float 332b6f35a76SGreg Roach */ 333b6f35a76SGreg Roach public function getMaxLineWidth(): float 334b6f35a76SGreg Roach { 335b6f35a76SGreg Roach $m = $this->tcpdf->getMargins(); 336b6f35a76SGreg Roach if ($this->tcpdf->getRTL()) { 337b6f35a76SGreg Roach return ($this->tcpdf->getRemainingWidth() + $m['right']); 338b6f35a76SGreg Roach } 339b6f35a76SGreg Roach 340b6f35a76SGreg Roach return ($this->tcpdf->getRemainingWidth() + $m['left']); 341b6f35a76SGreg Roach } 342b6f35a76SGreg Roach 343b6f35a76SGreg Roach /** 344b6f35a76SGreg Roach * Get the height of the footnote. 345b6f35a76SGreg Roach * 346b6f35a76SGreg Roach * @return float 347b6f35a76SGreg Roach */ 348b6f35a76SGreg Roach public function getFootnotesHeight(): float 349b6f35a76SGreg Roach { 350b6f35a76SGreg Roach $h = 0; 351b6f35a76SGreg Roach foreach ($this->printedfootnotes as $element) { 352b6f35a76SGreg Roach $h += $element->getHeight($this); 353b6f35a76SGreg Roach } 354b6f35a76SGreg Roach 355b6f35a76SGreg Roach return $h; 356b6f35a76SGreg Roach } 357b6f35a76SGreg Roach 358b6f35a76SGreg Roach /** 359b6f35a76SGreg Roach * Returns the the current font size height -PDF 360b6f35a76SGreg Roach * 361b6f35a76SGreg Roach * @return float 362b6f35a76SGreg Roach */ 363b6f35a76SGreg Roach public function getCurrentStyleHeight(): float 364b6f35a76SGreg Roach { 365b6f35a76SGreg Roach if ($this->currentStyle === '') { 366b6f35a76SGreg Roach return $this->wt_report->default_font_size; 367b6f35a76SGreg Roach } 368b6f35a76SGreg Roach $style = $this->wt_report->getStyle($this->currentStyle); 369b6f35a76SGreg Roach 370b6f35a76SGreg Roach return (float) $style['size']; 371b6f35a76SGreg Roach } 372b6f35a76SGreg Roach 373b6f35a76SGreg Roach /** 374b6f35a76SGreg Roach * Checks the Footnote and numbers them 375b6f35a76SGreg Roach * 376b6f35a76SGreg Roach * @param ReportPdfFootnote $footnote 377b6f35a76SGreg Roach * 378b6f35a76SGreg Roach * @return ReportPdfFootnote|bool object if already numbered, false otherwise 379b6f35a76SGreg Roach */ 380b6f35a76SGreg Roach public function checkFootnote(ReportPdfFootnote $footnote) 381b6f35a76SGreg Roach { 382b6f35a76SGreg Roach $ct = count($this->printedfootnotes); 383b6f35a76SGreg Roach $val = $footnote->getValue(); 384b6f35a76SGreg Roach $i = 0; 385b6f35a76SGreg Roach while ($i < $ct) { 386b6f35a76SGreg Roach if ($this->printedfootnotes[$i]->getValue() == $val) { 387b6f35a76SGreg Roach // If this footnote already exist then set up the numbers for this object 388b6f35a76SGreg Roach $footnote->setNum($i + 1); 389b6f35a76SGreg Roach $footnote->setAddlink((string) ($i + 1)); 390b6f35a76SGreg Roach 391b6f35a76SGreg Roach return $this->printedfootnotes[$i]; 392b6f35a76SGreg Roach } 393b6f35a76SGreg Roach $i++; 394b6f35a76SGreg Roach } 395b6f35a76SGreg Roach // If this Footnote has not been set up yet 396b6f35a76SGreg Roach $footnote->setNum($ct + 1); 397b6f35a76SGreg Roach $footnote->setAddlink((string) $this->tcpdf->AddLink()); 398b6f35a76SGreg Roach $this->printedfootnotes[] = $footnote; 399b6f35a76SGreg Roach 400b6f35a76SGreg Roach return false; 401b6f35a76SGreg Roach } 402b6f35a76SGreg Roach 403b6f35a76SGreg Roach /** 404b6f35a76SGreg Roach * Used this function instead of AddPage() 405b6f35a76SGreg Roach * This function will make sure that images will not be overwritten 406b6f35a76SGreg Roach * 407b6f35a76SGreg Roach * @return void 408b6f35a76SGreg Roach */ 409b6f35a76SGreg Roach public function newPage(): void 410b6f35a76SGreg Roach { 411b6f35a76SGreg Roach if ($this->lastpicpage > $this->tcpdf->getPage()) { 412b6f35a76SGreg Roach $this->tcpdf->setPage($this->lastpicpage); 413b6f35a76SGreg Roach } 414b6f35a76SGreg Roach $this->tcpdf->AddPage(); 415b6f35a76SGreg Roach } 416b6f35a76SGreg Roach 417b6f35a76SGreg Roach /** 418b6f35a76SGreg Roach * Add a page if needed -PDF 419b6f35a76SGreg Roach * 420b6f35a76SGreg Roach * @param float $height Cell height 421b6f35a76SGreg Roach * 422b6f35a76SGreg Roach * @return bool true in case of page break, false otherwise 423b6f35a76SGreg Roach */ 424b6f35a76SGreg Roach public function checkPageBreakPDF(float $height): bool 425b6f35a76SGreg Roach { 426b6f35a76SGreg Roach return $this->tcpdf->checkPageBreak($height); 427b6f35a76SGreg Roach } 428b6f35a76SGreg Roach 429b6f35a76SGreg Roach /** 430b6f35a76SGreg Roach * Returns the remaining width between the current position and margins -PDF 431b6f35a76SGreg Roach * 432b6f35a76SGreg Roach * @return float Remaining width 433b6f35a76SGreg Roach */ 434b6f35a76SGreg Roach public function getRemainingWidthPDF(): float 435b6f35a76SGreg Roach { 436b6f35a76SGreg Roach return $this->tcpdf->getRemainingWidth(); 437b6f35a76SGreg Roach } 438b6f35a76SGreg Roach /** 439b6f35a76SGreg Roach * PDF Setup - ReportPdf 440b6f35a76SGreg Roach * 441b6f35a76SGreg Roach * @return void 442b6f35a76SGreg Roach */ 443b6f35a76SGreg Roach public function setup(): void 444b6f35a76SGreg Roach { 445b6f35a76SGreg Roach parent::setup(); 446b6f35a76SGreg Roach 447b6f35a76SGreg Roach // Setup the PDF class with custom size pages because WT supports more page sizes. If WT sends an unknown size name then the default would be A4 448b6f35a76SGreg Roach $this->tcpdf = new TcpdfWrapper($this->orientation, parent::UNITS, [ 449b6f35a76SGreg Roach $this->page_width, 450b6f35a76SGreg Roach $this->page_height, 451b6f35a76SGreg Roach ], self::UNICODE, 'UTF-8', self::DISK_CACHE); 452b6f35a76SGreg Roach 453b6f35a76SGreg Roach // Setup the PDF margins 454b6f35a76SGreg Roach $this->tcpdf->SetMargins($this->left_margin, $this->top_margin, $this->right_margin); 455b6f35a76SGreg Roach $this->tcpdf->setHeaderMargin($this->header_margin); 456b6f35a76SGreg Roach $this->tcpdf->setFooterMargin($this->footer_margin); 457b6f35a76SGreg Roach //Set auto page breaks 458b6f35a76SGreg Roach $this->tcpdf->SetAutoPageBreak(true, $this->bottom_margin); 459b6f35a76SGreg Roach // Set font subsetting 460b6f35a76SGreg Roach $this->tcpdf->setFontSubsetting(self::SUBSETTING); 461b6f35a76SGreg Roach // Setup PDF compression 462b6f35a76SGreg Roach $this->tcpdf->SetCompression(self::COMPRESSION); 463b6f35a76SGreg Roach // Setup RTL support 464b6f35a76SGreg Roach $this->tcpdf->setRTL($this->rtl); 465b6f35a76SGreg Roach // Set the document information 466b6f35a76SGreg Roach $this->tcpdf->SetCreator(Webtrees::NAME . ' ' . Webtrees::VERSION); 467b6f35a76SGreg Roach $this->tcpdf->SetAuthor($this->rauthor); 468b6f35a76SGreg Roach $this->tcpdf->SetTitle($this->title); 469b6f35a76SGreg Roach $this->tcpdf->SetSubject($this->rsubject); 470b6f35a76SGreg Roach $this->tcpdf->SetKeywords($this->rkeywords); 471db9b720fSGreg Roach $this->tcpdf->SetHeaderData('', 0, $this->title); 472*f6351d1fSGreg Roach $this->tcpdf->setHeaderFont([$this->default_font, '', $this->default_font_size]); 473b6f35a76SGreg Roach 474b6f35a76SGreg Roach $this->setReport($this); 475b6f35a76SGreg Roach 476b6f35a76SGreg Roach if ($this->show_generated_by) { 477b6f35a76SGreg Roach // The default style name for Generated by.... is 'genby' 478b6f35a76SGreg Roach $element = new ReportPdfCell(0, 10, 0, 'C', '', 'genby', 1, ReportBaseElement::CURRENT_POSITION, ReportBaseElement::CURRENT_POSITION, 0, 0, '', '', true); 479b6f35a76SGreg Roach $element->addText($this->generated_by); 480b6f35a76SGreg Roach $element->setUrl(Webtrees::URL); 481b6f35a76SGreg Roach $this->addFooter($element); 482b6f35a76SGreg Roach } 483b6f35a76SGreg Roach } 484b6f35a76SGreg Roach 485b6f35a76SGreg Roach /** 486b6f35a76SGreg Roach * Add an element. 487b6f35a76SGreg Roach * 488b6f35a76SGreg Roach * @param ReportBaseElement|string $element 489b6f35a76SGreg Roach * 490b6f35a76SGreg Roach * @return void 491b6f35a76SGreg Roach */ 492b6f35a76SGreg Roach public function addElement($element): void 493b6f35a76SGreg Roach { 494b6f35a76SGreg Roach if ($this->processing === 'B') { 495b6f35a76SGreg Roach $this->addBody($element); 496b6f35a76SGreg Roach 497b6f35a76SGreg Roach return; 498b6f35a76SGreg Roach } 499b6f35a76SGreg Roach 500b6f35a76SGreg Roach if ($this->processing === 'H') { 501b6f35a76SGreg Roach $this->addHeader($element); 502b6f35a76SGreg Roach 503b6f35a76SGreg Roach return; 504b6f35a76SGreg Roach } 505b6f35a76SGreg Roach 506b6f35a76SGreg Roach if ($this->processing === 'F') { 507b6f35a76SGreg Roach $this->addFooter($element); 508b6f35a76SGreg Roach 509b6f35a76SGreg Roach return; 510b6f35a76SGreg Roach } 511b6f35a76SGreg Roach } 512b6f35a76SGreg Roach 513b6f35a76SGreg Roach /** 514b6f35a76SGreg Roach * Run the report. 515b6f35a76SGreg Roach * 516b6f35a76SGreg Roach * @return void 517b6f35a76SGreg Roach */ 518b6f35a76SGreg Roach public function run(): void 519b6f35a76SGreg Roach { 520b6f35a76SGreg Roach $this->body(); 521b6f35a76SGreg Roach echo $this->tcpdf->Output('doc.pdf', 'S'); 522b6f35a76SGreg Roach } 523b6f35a76SGreg Roach 524b6f35a76SGreg Roach /** 525b6f35a76SGreg Roach * Create a new Cell object. 526b6f35a76SGreg Roach * 527b6f35a76SGreg Roach * @param int $width cell width (expressed in points) 528b6f35a76SGreg Roach * @param int $height cell height (expressed in points) 529b6f35a76SGreg Roach * @param mixed $border Border style 530b6f35a76SGreg Roach * @param string $align Text alignement 531b6f35a76SGreg Roach * @param string $bgcolor Background color code 532b6f35a76SGreg Roach * @param string $style The name of the text style 533b6f35a76SGreg Roach * @param int $ln Indicates where the current position should go after the call 534b6f35a76SGreg Roach * @param mixed $top Y-position 535b6f35a76SGreg Roach * @param mixed $left X-position 536b6f35a76SGreg Roach * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 1 537b6f35a76SGreg Roach * @param int $stretch Stretch carachter mode 538b6f35a76SGreg Roach * @param string $bocolor Border color 539b6f35a76SGreg Roach * @param string $tcolor Text color 540b6f35a76SGreg Roach * @param bool $reseth 541b6f35a76SGreg Roach * 542b6f35a76SGreg Roach * @return ReportBaseCell 543b6f35a76SGreg Roach */ 54424f2a3afSGreg Roach public function createCell(int $width, int $height, $border, string $align, string $bgcolor, string $style, int $ln, $top, $left, int $fill, int $stretch, string $bocolor, string $tcolor, bool $reseth): ReportBaseCell 545b6f35a76SGreg Roach { 546b6f35a76SGreg Roach return new ReportPdfCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth); 547b6f35a76SGreg Roach } 548b6f35a76SGreg Roach 549b6f35a76SGreg Roach /** 550b6f35a76SGreg Roach * Create a new TextBox object. 551b6f35a76SGreg Roach * 552b6f35a76SGreg Roach * @param float $width Text box width 553b6f35a76SGreg Roach * @param float $height Text box height 554b6f35a76SGreg Roach * @param bool $border 555b6f35a76SGreg Roach * @param string $bgcolor Background color code in HTML 556b6f35a76SGreg Roach * @param bool $newline 557b6f35a76SGreg Roach * @param float $left 558b6f35a76SGreg Roach * @param float $top 559b6f35a76SGreg Roach * @param bool $pagecheck 560b6f35a76SGreg Roach * @param string $style 561b6f35a76SGreg Roach * @param bool $fill 562b6f35a76SGreg Roach * @param bool $padding 563b6f35a76SGreg Roach * @param bool $reseth 564b6f35a76SGreg Roach * 565b6f35a76SGreg Roach * @return ReportBaseTextbox 566b6f35a76SGreg Roach */ 567b6f35a76SGreg Roach public function createTextBox( 568b6f35a76SGreg Roach float $width, 569b6f35a76SGreg Roach float $height, 570b6f35a76SGreg Roach bool $border, 571b6f35a76SGreg Roach string $bgcolor, 572b6f35a76SGreg Roach bool $newline, 573b6f35a76SGreg Roach float $left, 574b6f35a76SGreg Roach float $top, 575b6f35a76SGreg Roach bool $pagecheck, 576b6f35a76SGreg Roach string $style, 577b6f35a76SGreg Roach bool $fill, 578b6f35a76SGreg Roach bool $padding, 579b6f35a76SGreg Roach bool $reseth 580b6f35a76SGreg Roach ): ReportBaseTextbox { 581b6f35a76SGreg Roach return new ReportPdfTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth); 582b6f35a76SGreg Roach } 583b6f35a76SGreg Roach 584b6f35a76SGreg Roach /** 585b6f35a76SGreg Roach * Create a text element. 586b6f35a76SGreg Roach * 587b6f35a76SGreg Roach * @param string $style 588b6f35a76SGreg Roach * @param string $color 589b6f35a76SGreg Roach * 590b6f35a76SGreg Roach * @return ReportBaseText 591b6f35a76SGreg Roach */ 592b6f35a76SGreg Roach public function createText(string $style, string $color): ReportBaseText 593b6f35a76SGreg Roach { 594b6f35a76SGreg Roach return new ReportPdfText($style, $color); 595b6f35a76SGreg Roach } 596b6f35a76SGreg Roach 597b6f35a76SGreg Roach /** 598b6f35a76SGreg Roach * Create a new Footnote object. 599b6f35a76SGreg Roach * 600b6f35a76SGreg Roach * @param string $style Style name 601b6f35a76SGreg Roach * 602b6f35a76SGreg Roach * @return ReportBaseFootnote 603b6f35a76SGreg Roach */ 60424f2a3afSGreg Roach public function createFootnote(string $style): ReportBaseFootnote 605b6f35a76SGreg Roach { 606b6f35a76SGreg Roach return new ReportPdfFootnote($style); 607b6f35a76SGreg Roach } 608b6f35a76SGreg Roach 609b6f35a76SGreg Roach /** 610b6f35a76SGreg Roach * Create a new image object. 611b6f35a76SGreg Roach * 612b6f35a76SGreg Roach * @param string $file Filename 613b6f35a76SGreg Roach * @param float $x 614b6f35a76SGreg Roach * @param float $y 615b6f35a76SGreg Roach * @param float $w Image width 616b6f35a76SGreg Roach * @param float $h Image height 617b6f35a76SGreg Roach * @param string $align L:left, C:center, R:right or empty to use x/y 618b6f35a76SGreg Roach * @param string $ln T:same line, N:next line 619b6f35a76SGreg Roach * 620b6f35a76SGreg Roach * @return ReportBaseImage 621b6f35a76SGreg Roach */ 622b6f35a76SGreg Roach public function createImage(string $file, float $x, float $y, float $w, float $h, string $align, string $ln): ReportBaseImage 623b6f35a76SGreg Roach { 624b6f35a76SGreg Roach return new ReportPdfImage($file, $x, $y, $w, $h, $align, $ln); 625b6f35a76SGreg Roach } 626b6f35a76SGreg Roach 627b6f35a76SGreg Roach /** 628b6f35a76SGreg Roach * Create a new image object from Media Object. 629b6f35a76SGreg Roach * 630b6f35a76SGreg Roach * @param MediaFile $media_file 631b6f35a76SGreg Roach * @param float $x 632b6f35a76SGreg Roach * @param float $y 633b6f35a76SGreg Roach * @param float $w Image width 634b6f35a76SGreg Roach * @param float $h Image height 635b6f35a76SGreg Roach * @param string $align L:left, C:center, R:right or empty to use x/y 636b6f35a76SGreg Roach * @param string $ln T:same line, N:next line 637f7cf8a15SGreg Roach * @param FilesystemOperator $data_filesystem 638b6f35a76SGreg Roach * 639b6f35a76SGreg Roach * @return ReportBaseImage 640b6f35a76SGreg Roach */ 641b6f35a76SGreg Roach public function createImageFromObject( 642b6f35a76SGreg Roach MediaFile $media_file, 643b6f35a76SGreg Roach float $x, 644b6f35a76SGreg Roach float $y, 645b6f35a76SGreg Roach float $w, 646b6f35a76SGreg Roach float $h, 647b6f35a76SGreg Roach string $align, 648b6f35a76SGreg Roach string $ln, 649f7cf8a15SGreg Roach FilesystemOperator $data_filesystem 650b6f35a76SGreg Roach ): ReportBaseImage { 651b6f35a76SGreg Roach return new ReportPdfImage('@' . $media_file->fileContents($data_filesystem), $x, $y, $w, $h, $align, $ln); 652b6f35a76SGreg Roach } 653b6f35a76SGreg Roach 654b6f35a76SGreg Roach /** 655b6f35a76SGreg Roach * Create a line. 656b6f35a76SGreg Roach * 657b6f35a76SGreg Roach * @param float $x1 658b6f35a76SGreg Roach * @param float $y1 659b6f35a76SGreg Roach * @param float $x2 660b6f35a76SGreg Roach * @param float $y2 661b6f35a76SGreg Roach * 662b6f35a76SGreg Roach * @return ReportBaseLine 663b6f35a76SGreg Roach */ 664b6f35a76SGreg Roach public function createLine(float $x1, float $y1, float $x2, float $y2): ReportBaseLine 665b6f35a76SGreg Roach { 666b6f35a76SGreg Roach return new ReportPdfLine($x1, $y1, $x2, $y2); 667b6f35a76SGreg Roach } 668b6f35a76SGreg Roach} 669