xref: /webtrees/app/Report/ReportHtmlFootnote.php (revision e2b8114de32f4ac3319ef4ec97dceddeff185499)
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 ReportHtmlFootnote
22 */
23class ReportHtmlFootnote extends ReportBaseFootnote
24{
25    /**
26     * HTML Footnotes number renderer
27     *
28     * @param ReportHtml $renderer
29     *
30     * @return void
31     */
32    public function render($renderer)
33    {
34        $renderer->setCurrentStyle('footnotenum');
35        echo '<a href="#footnote', $this->num, '"><sup>';
36        $renderer->write($renderer->entityRTL . $this->num);
37        echo "</sup></a>\n";
38    }
39
40    /**
41     * Write the Footnote text
42     * Uses style name "footnote" by default
43     *
44     * @param ReportHtml $renderer
45     *
46     * @return void
47     */
48    public function renderFootnote($renderer)
49    {
50        if ($renderer->getCurrentStyle() != $this->styleName) {
51            $renderer->setCurrentStyle($this->styleName);
52        }
53
54        $temptext = str_replace('#PAGENUM#', (string) $renderer->pageNo(), $this->text);
55        // underline «title» part of Source item
56        $temptext = str_replace([
57            '«',
58            '»',
59        ], [
60            '<u>',
61            '</u>',
62        ], $temptext);
63        echo "\n<div><a name=\"footnote", $this->num, '"></a>';
64        $renderer->write($this->num . '. ' . $temptext);
65        echo '</div>';
66
67        $renderer->setXy(0, $renderer->getY() + $this->getFootnoteHeight($renderer));
68    }
69
70    /**
71     * Calculates the Footnotes height
72     *
73     * @param ReportHtml $html
74     * @param float      $cellWidth The width of the cell to use it for text wraping
75     *
76     * @return float     Footnote height in points
77     */
78    public function getFootnoteHeight($html, float $cellWidth = 0): float
79    {
80        if ($html->getCurrentStyle() != $this->styleName) {
81            $html->setCurrentStyle($this->styleName);
82        }
83
84        if ($cellWidth > 0) {
85            $this->text = $html->textWrap($this->text, $cellWidth);
86        }
87        $this->text = $this->text . "\n\n";
88        $ct         = substr_count($this->text, "\n");
89        $fsize      = $html->getCurrentStyleHeight();
90
91        return ($fsize * $ct) * $html->cellHeightRatio;
92    }
93
94    /**
95     * Get the width of text
96     * Breaks up a text into lines if needed
97     *
98     * @param ReportHtml $renderer
99     *
100     * @return float|array
101     */
102    public function getWidth($renderer)
103    {
104        // Setup the style name
105        $renderer->setCurrentStyle('footnotenum');
106
107        // Check for the largest font size in the box
108        $fsize = $renderer->getCurrentStyleHeight();
109        if ($fsize > $renderer->largestFontHeight) {
110            $renderer->largestFontHeight = $fsize;
111        }
112
113        // Returns the Object if already numbered else false
114        if (empty($this->num)) {
115            $renderer->checkFootnote($this);
116        }
117
118        // Get the line width for the text in points + a little margin
119        $lw = $renderer->getStringWidth($this->numText);
120        // Line Feed counter - Number of lines in the text
121        $lfct = $renderer->countLines($this->numText);
122        // If there is still remaining wrap width...
123        if ($this->wrapWidthRemaining > 0) {
124            // Check with line counter too!
125            if ($lw >= $this->wrapWidthRemaining || $lfct > 1) {
126                $newtext            = '';
127                $wrapWidthRemaining = $this->wrapWidthRemaining;
128                $lines              = explode("\n", $this->numText);
129                // Go throught the text line by line
130                foreach ($lines as $line) {
131                    // Line width in points + a little margin
132                    $lw = $renderer->getStringWidth($line);
133                    // If the line has to be wraped
134                    if ($lw > $wrapWidthRemaining) {
135                        $words    = explode(' ', $line);
136                        $addspace = count($words);
137                        $lw       = 0;
138                        foreach ($words as $word) {
139                            $addspace--;
140                            $lw += $renderer->getStringWidth($word . ' ');
141                            if ($lw <= $wrapWidthRemaining) {
142                                $newtext .= $word;
143                                if ($addspace != 0) {
144                                    $newtext .= ' ';
145                                }
146                            } else {
147                                $lw = $renderer->getStringWidth($word . ' ');
148                                $newtext .= "\n$word";
149                                if ($addspace != 0) {
150                                    $newtext .= ' ';
151                                }
152                                // Reset the wrap width to the cell width
153                                $wrapWidthRemaining = $this->wrapWidthCell;
154                            }
155                        }
156                    } else {
157                        $newtext .= $line;
158                    }
159                    // Check the Line Feed counter
160                    if ($lfct > 1) {
161                        // Add a new line feed as long as it’s not the last line
162                        $newtext .= "\n";
163                        // Reset the line width
164                        $lw = 0;
165                        // Reset the wrap width to the cell width
166                        $wrapWidthRemaining = $this->wrapWidthCell;
167                    }
168                    $lfct--;
169                }
170                $this->numText = $newtext;
171                $lfct          = substr_count($this->numText, "\n");
172
173                return [
174                    $lw,
175                    1,
176                    $lfct,
177                ];
178            }
179        }
180        $l    = 0;
181        $lfct = substr_count($this->numText, "\n");
182        if ($lfct > 0) {
183            $l = 2;
184        }
185
186        return [
187            $lw,
188            $l,
189            $lfct,
190        ];
191    }
192}
193