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