1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2019 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 <http://www.gnu.org/licenses/>. 16 */ 17declare(strict_types=1); 18 19namespace Fisharebest\Webtrees\Report; 20 21/** 22 * Class ReportHtmlText 23 */ 24class ReportHtmlText extends ReportBaseText 25{ 26 /** 27 * Render the elements. 28 * 29 * @param ReportHtml $renderer 30 * @param int $curx 31 * @param bool $attrib Is is called from a different element? 32 * 33 * @return void 34 */ 35 public function render($renderer, $curx = 0, $attrib = true) 36 { 37 // Set up the style 38 if ($renderer->getCurrentStyle() != $this->styleName) { 39 $renderer->setCurrentStyle($this->styleName); 40 } 41 $temptext = str_replace('#PAGENUM#', (string) $renderer->pageNo(), $this->text); 42 // underline «title» part of Source item 43 $temptext = str_replace([ 44 '«', 45 '»', 46 ], [ 47 '<u>', 48 '</u>', 49 ], $temptext); 50 51 // If any text at all 52 if (!empty($temptext)) { 53 // If called by an other element 54 if (!$attrib) { 55 $renderer->write($temptext, $this->color); 56 } else { 57 // Save the start positions 58 $startX = $renderer->getX(); 59 $startY = $renderer->getY(); 60 $width = $renderer->getRemainingWidth(); 61 // If text is wider then page width then wrap it 62 if ($renderer->getStringWidth($temptext) > $width) { 63 $lines = explode("\n", $temptext); 64 foreach ($lines as $line) { 65 echo '<div style="position:absolute;top:', $startY, 'pt;', $renderer->alignRTL, ':', $startX, 'pt;width:', $width, 'pt;">'; 66 $line = $renderer->textWrap($line, $width); 67 $startY += $renderer->getTextCellHeight($line); 68 $renderer->setY($startY); 69 $renderer->write($line, $this->color); 70 echo "</div>\n"; 71 } 72 } else { 73 echo '<div style="position:absolute;top:', $startY, 'pt;', $renderer->alignRTL, ':', $startX, 'pt;width:', $width, 'pt;">'; 74 $renderer->write($temptext, $this->color); 75 echo "</div>\n"; 76 $renderer->setX($startX + $renderer->getStringWidth($temptext)); 77 if ($renderer->countLines($temptext) != 1) { 78 $renderer->setXy(0, $startY + $renderer->getTextCellHeight($temptext)); 79 } 80 } 81 } 82 } 83 } 84 85 /** 86 * Returns the height in points of the text element 87 * The height is already calculated in getWidth() 88 * 89 * @param ReportHtml $renderer 90 * 91 * @return float 92 */ 93 public function getHeight($renderer): float 94 { 95 $ct = substr_count($this->text, "\n"); 96 if ($ct > 0) { 97 $ct += 1; 98 } 99 $style = $renderer->getStyle($this->styleName); 100 101 return ($style['size'] * $ct) * $renderer->cellHeightRatio; 102 } 103 104 /** 105 * Get the width of text and wrap it too 106 * 107 * @param ReportHtml $renderer 108 * 109 * @return float|array 110 */ 111 public function getWidth($renderer) 112 { 113 // Setup the style name, a font must be selected to calculate the width 114 if ($renderer->getCurrentStyle() != $this->styleName) { 115 $renderer->setCurrentStyle($this->styleName); 116 } 117 118 // Check for the largest font size in the box 119 $fsize = $renderer->getCurrentStyleHeight(); 120 if ($fsize > $renderer->largestFontHeight) { 121 $renderer->largestFontHeight = $fsize; 122 } 123 124 // Get the line width for the text in points 125 $lw = $renderer->getStringWidth($this->text); 126 // Line Feed counter - Number of lines in the text 127 $lfct = $renderer->countLines($this->text); 128 // If there is still remaining wrap width... 129 $wrapWidthRemaining = $this->wrapWidthRemaining; 130 if ($wrapWidthRemaining > 0) { 131 // Check with line counter too! 132 if ($lw >= $wrapWidthRemaining || $lfct > 1) { 133 $newtext = ''; 134 $lines = explode("\n", $this->text); 135 // Go throught the text line by line 136 foreach ($lines as $line) { 137 // Line width in points + a little margin 138 $lw = $renderer->getStringWidth($line); 139 // If the line has to be wraped 140 if ($lw > $wrapWidthRemaining) { 141 $words = explode(' ', $line); 142 $addspace = count($words); 143 $lw = 0; 144 foreach ($words as $word) { 145 $addspace--; 146 $lw += $renderer->getStringWidth($word . ' '); 147 if ($lw <= $wrapWidthRemaining) { 148 $newtext .= $word; 149 if ($addspace != 0) { 150 $newtext .= ' '; 151 } 152 } else { 153 $lw = $renderer->getStringWidth($word . ' '); 154 $newtext .= "\n$word"; 155 if ($addspace != 0) { 156 $newtext .= ' '; 157 } 158 // Reset the wrap width to the cell width 159 $wrapWidthRemaining = $this->wrapWidthCell; 160 } 161 } 162 } else { 163 $newtext .= $line; 164 } 165 // Check the Line Feed counter 166 if ($lfct > 1) { 167 // Add a new line as long as it’s not the last line 168 $newtext .= "\n"; 169 // Reset the line width 170 $lw = 0; 171 // Reset the wrap width to the cell width 172 $wrapWidthRemaining = $this->wrapWidthCell; 173 } 174 $lfct--; 175 } 176 $this->text = $newtext; 177 $lfct = substr_count($this->text, "\n"); 178 179 return [ 180 $lw, 181 1, 182 $lfct, 183 ]; 184 } 185 } 186 $l = 0; 187 $lfct = substr_count($this->text, "\n"); 188 if ($lfct > 0) { 189 $l = 2; 190 } 191 192 return [ 193 $lw, 194 $l, 195 $lfct, 196 ]; 197 } 198} 199