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