1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2023 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Report; 21 22use function count; 23use function explode; 24use function hexdec; 25use function preg_match; 26use function str_replace; 27use function substr_count; 28 29/** 30 * Class ReportPdfText 31 */ 32class ReportPdfText extends ReportBaseText 33{ 34 /** 35 * PDF Text renderer 36 * 37 * @param PdfRenderer $renderer 38 * 39 * @return void 40 */ 41 public function render($renderer): void 42 { 43 // Set up the style 44 if ($renderer->getCurrentStyle() !== $this->styleName) { 45 $renderer->setCurrentStyle($this->styleName); 46 } 47 $temptext = str_replace('#PAGENUM#', (string) $renderer->tcpdf->PageNo(), $this->text); 48 // underline «title» part of Source item 49 $temptext = str_replace([ 50 '«', 51 '»', 52 ], [ 53 '<u>', 54 '</u>', 55 ], $temptext); 56 57 // Paint the text color or they might use inherited colors by the previous function 58 $match = []; 59 if (preg_match('/#?(..)(..)(..)/', $this->color, $match)) { 60 $r = hexdec($match[1]); 61 $g = hexdec($match[2]); 62 $b = hexdec($match[3]); 63 $renderer->tcpdf->setTextColor($r, $g, $b); 64 } else { 65 $renderer->tcpdf->setTextColor(0, 0, 0); 66 } 67 $temptext = RightToLeftSupport::spanLtrRtl($temptext); 68 $temptext = str_replace( 69 [ 70 '<br><span dir="rtl">', 71 '<br><span dir="ltr">', 72 '> ', 73 ' <', 74 ], 75 [ 76 '<span dir="rtl" ><br>', 77 '<span dir="ltr" ><br>', 78 '> ', 79 ' <', 80 ], 81 $temptext 82 ); 83 $renderer->tcpdf->writeHTML( 84 $temptext, 85 false, 86 false, 87 true, 88 false, 89 '' 90 ); //change height - line break etc. - the form is mirror on rtl pages 91 // Reset the text color to black or it will be inherited 92 $renderer->tcpdf->setTextColor(0, 0, 0); 93 } 94 95 /** 96 * Returns the height in points of the text element 97 * The height is already calculated in getWidth() 98 * 99 * @param PdfRenderer $renderer 100 * 101 * @return float 102 */ 103 public function getHeight($renderer): float 104 { 105 return 0; 106 } 107 108 /** 109 * Splits the text into lines if necessary to fit into a giving cell 110 * 111 * @param PdfRenderer $renderer 112 * 113 * @return array{0:float,1:int,2:float} 114 */ 115 public function getWidth($renderer): array 116 { 117 // Setup the style name, a font must be selected to calculate the width 118 if ($renderer->getCurrentStyle() !== $this->styleName) { 119 $renderer->setCurrentStyle($this->styleName); 120 } 121 122 // Check for the largest font size in the box 123 $fsize = $renderer->getCurrentStyleHeight(); 124 if ($fsize > $renderer->largestFontHeight) { 125 $renderer->largestFontHeight = $fsize; 126 } 127 128 // Get the line width for the text in points 129 $lw = $renderer->tcpdf->GetStringWidth($this->text); 130 // Line Feed counter - Number of lines in the text 131 $lfct = substr_count($this->text, "\n") + 1; 132 // If there is still remaining wrap width... 133 $wrapWidthRemaining = $this->wrapWidthRemaining; 134 if ($wrapWidthRemaining > 0) { 135 // Check with line counter too! 136 if ($lw >= $wrapWidthRemaining || $lfct > 1) { 137 $newtext = ''; 138 $lines = explode("\n", $this->text); 139 // Go through the text line by line 140 foreach ($lines as $line) { 141 // Line width in points + a little margin 142 $lw = $renderer->tcpdf->GetStringWidth($line); 143 // If the line has to be wrapped 144 if ($lw > $wrapWidthRemaining) { 145 $words = explode(' ', $line); 146 $addspace = count($words); 147 $lw = 0; 148 foreach ($words as $word) { 149 $addspace--; 150 $lw += $renderer->tcpdf->GetStringWidth($word . ' '); 151 if ($lw <= $wrapWidthRemaining) { 152 $newtext .= $word; 153 if ($addspace !== 0) { 154 $newtext .= ' '; 155 } 156 } else { 157 $lw = $renderer->tcpdf->GetStringWidth($word . ' '); 158 $newtext .= "\n$word"; 159 if ($addspace !== 0) { 160 $newtext .= ' '; 161 } 162 // Reset the wrap width to the cell width 163 $wrapWidthRemaining = $this->wrapWidthCell; 164 } 165 } 166 } else { 167 $newtext .= $line; 168 } 169 // Check the Line Feed counter 170 if ($lfct > 1) { 171 // Add a new line as long as it’s not the last line 172 $newtext .= "\n"; 173 // Reset the line width 174 $lw = 0; 175 // Reset the wrap width to the cell width 176 $wrapWidthRemaining = $this->wrapWidthCell; 177 } 178 $lfct--; 179 } 180 $this->text = $newtext; 181 $lfct = substr_count($this->text, "\n"); 182 183 return [ 184 $lw, 185 1, 186 $lfct, 187 ]; 188 } 189 } 190 $l = 0; 191 $lfct = substr_count($this->text, "\n"); 192 if ($lfct > 0) { 193 $l = 2; 194 } 195 196 return [ 197 $lw, 198 $l, 199 $lfct, 200 ]; 201 } 202} 203