1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2021 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 Fisharebest\Webtrees\Functions\FunctionsRtl; 23 24use function count; 25use function explode; 26use function hexdec; 27use function preg_match; 28use function str_replace; 29use function substr_count; 30 31/** 32 * Class ReportPdfText 33 */ 34class ReportPdfText extends ReportBaseText 35{ 36 /** 37 * PDF Text renderer 38 * 39 * @param PdfRenderer $renderer 40 * 41 * @return void 42 */ 43 public function render($renderer): void 44 { 45 // Set up the style 46 if ($renderer->getCurrentStyle() !== $this->styleName) { 47 $renderer->setCurrentStyle($this->styleName); 48 } 49 $temptext = str_replace('#PAGENUM#', (string) $renderer->tcpdf->PageNo(), $this->text); 50 // underline «title» part of Source item 51 $temptext = str_replace([ 52 '«', 53 '»', 54 ], [ 55 '<u>', 56 '</u>', 57 ], $temptext); 58 59 // Paint the text color or they might use inherited colors by the previous function 60 $match = []; 61 if (preg_match('/#?(..)(..)(..)/', $this->color, $match)) { 62 $r = hexdec($match[1]); 63 $g = hexdec($match[2]); 64 $b = hexdec($match[3]); 65 $renderer->tcpdf->SetTextColor($r, $g, $b); 66 } else { 67 $renderer->tcpdf->SetTextColor(0, 0, 0); 68 } 69 $temptext = FunctionsRtl::spanLtrRtl($temptext); 70 $temptext = str_replace( 71 [ 72 '<br><span dir="rtl">', 73 '<br><span dir="ltr">', 74 '> ', 75 ' <', 76 ], 77 [ 78 '<span dir="rtl" ><br>', 79 '<span dir="ltr" ><br>', 80 '> ', 81 ' <', 82 ], 83 $temptext 84 ); 85 $renderer->tcpdf->writeHTML( 86 $temptext, 87 false, 88 false, 89 true, 90 false, 91 '' 92 ); //change height - line break etc. - the form is mirror on rtl pages 93 // Reset the text color to black or it will be inherited 94 $renderer->tcpdf->SetTextColor(0, 0, 0); 95 } 96 97 /** 98 * Returns the height in points of the text element 99 * The height is already calculated in getWidth() 100 * 101 * @param PdfRenderer $renderer 102 * 103 * @return float 104 */ 105 public function getHeight($renderer): float 106 { 107 return 0; 108 } 109 110 /** 111 * Splits the text into lines if necessary to fit into a giving cell 112 * 113 * @param PdfRenderer $renderer 114 * 115 * @return array{0:float,1:int,2:float} 116 */ 117 public function getWidth($renderer): array 118 { 119 // Setup the style name, a font must be selected to calculate the width 120 if ($renderer->getCurrentStyle() !== $this->styleName) { 121 $renderer->setCurrentStyle($this->styleName); 122 } 123 124 // Check for the largest font size in the box 125 $fsize = $renderer->getCurrentStyleHeight(); 126 if ($fsize > $renderer->largestFontHeight) { 127 $renderer->largestFontHeight = $fsize; 128 } 129 130 // Get the line width for the text in points 131 $lw = $renderer->tcpdf->GetStringWidth($this->text); 132 // Line Feed counter - Number of lines in the text 133 $lfct = substr_count($this->text, "\n") + 1; 134 // If there is still remaining wrap width... 135 $wrapWidthRemaining = $this->wrapWidthRemaining; 136 if ($wrapWidthRemaining > 0) { 137 // Check with line counter too! 138 if ($lw >= $wrapWidthRemaining || $lfct > 1) { 139 $newtext = ''; 140 $lines = explode("\n", $this->text); 141 // Go throught the text line by line 142 foreach ($lines as $line) { 143 // Line width in points + a little margin 144 $lw = $renderer->tcpdf->GetStringWidth($line); 145 // If the line has to be wraped 146 if ($lw > $wrapWidthRemaining) { 147 $words = explode(' ', $line); 148 $addspace = count($words); 149 $lw = 0; 150 foreach ($words as $word) { 151 $addspace--; 152 $lw += $renderer->tcpdf->GetStringWidth($word . ' '); 153 if ($lw <= $wrapWidthRemaining) { 154 $newtext .= $word; 155 if ($addspace !== 0) { 156 $newtext .= ' '; 157 } 158 } else { 159 $lw = $renderer->tcpdf->GetStringWidth($word . ' '); 160 $newtext .= "\n$word"; 161 if ($addspace !== 0) { 162 $newtext .= ' '; 163 } 164 // Reset the wrap width to the cell width 165 $wrapWidthRemaining = $this->wrapWidthCell; 166 } 167 } 168 } else { 169 $newtext .= $line; 170 } 171 // Check the Line Feed counter 172 if ($lfct > 1) { 173 // Add a new line as long as it’s not the last line 174 $newtext .= "\n"; 175 // Reset the line width 176 $lw = 0; 177 // Reset the wrap width to the cell width 178 $wrapWidthRemaining = $this->wrapWidthCell; 179 } 180 $lfct--; 181 } 182 $this->text = $newtext; 183 $lfct = substr_count($this->text, "\n"); 184 185 return [ 186 $lw, 187 1, 188 $lfct, 189 ]; 190 } 191 } 192 $l = 0; 193 $lfct = substr_count($this->text, "\n"); 194 if ($lfct > 0) { 195 $l = 2; 196 } 197 198 return [ 199 $lw, 200 $l, 201 $lfct, 202 ]; 203 } 204} 205