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