xref: /webtrees/app/Report/ReportHtmlFootnote.php (revision 41cfb9e2204e7a7e8919e48098071f28e9a0fc54)
1a25f0a04SGreg Roach<?php
23976b470SGreg Roach
3a25f0a04SGreg Roach/**
4a25f0a04SGreg Roach * webtrees: online genealogy
589f7189bSGreg Roach * Copyright (C) 2021 webtrees development team
6a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
7a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
8a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
9a25f0a04SGreg Roach * (at your option) any later version.
10a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
11a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13a25f0a04SGreg Roach * GNU General Public License for more details.
14a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
16a25f0a04SGreg Roach */
17fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Report;
21a25f0a04SGreg Roach
22b6f35a76SGreg Roachuse function count;
23b6f35a76SGreg Roachuse function explode;
24b6f35a76SGreg Roachuse function str_replace;
25b6f35a76SGreg Roachuse function substr_count;
26b6f35a76SGreg Roach
27a25f0a04SGreg Roach/**
2867c69ce5SGreg Roach * Class ReportHtmlFootnote
29a25f0a04SGreg Roach */
30c1010edaSGreg Roachclass ReportHtmlFootnote extends ReportBaseFootnote
31c1010edaSGreg Roach{
32a25f0a04SGreg Roach    /**
33a25f0a04SGreg Roach     * HTML Footnotes number renderer
34a25f0a04SGreg Roach     *
35b6f35a76SGreg Roach     * @param HtmlRenderer $renderer
36c7ff4153SGreg Roach     *
37c7ff4153SGreg Roach     * @return void
38a25f0a04SGreg Roach     */
39c1010edaSGreg Roach    public function render($renderer)
40c1010edaSGreg Roach    {
417a6ee1acSGreg Roach        $renderer->setCurrentStyle('footnotenum');
427a6ee1acSGreg Roach        echo '<a href="#footnote', $this->num, '"><sup>';
43a25f0a04SGreg Roach        $renderer->write($renderer->entityRTL . $this->num);
44a25f0a04SGreg Roach        echo "</sup></a>\n";
45a25f0a04SGreg Roach    }
46a25f0a04SGreg Roach
47a25f0a04SGreg Roach    /**
48a25f0a04SGreg Roach     * Write the Footnote text
49a25f0a04SGreg Roach     * Uses style name "footnote" by default
50a25f0a04SGreg Roach     *
51b6f35a76SGreg Roach     * @param HtmlRenderer $renderer
5218d7a90dSGreg Roach     *
5318d7a90dSGreg Roach     * @return void
54a25f0a04SGreg Roach     */
55b6f35a76SGreg Roach    public function renderFootnote($renderer): void
56c1010edaSGreg Roach    {
57b6f35a76SGreg Roach        if ($renderer->getCurrentStyle() !== $this->styleName) {
5867c69ce5SGreg Roach            $renderer->setCurrentStyle($this->styleName);
59a25f0a04SGreg Roach        }
60a25f0a04SGreg Roach
6167c69ce5SGreg Roach        $temptext = str_replace('#PAGENUM#', (string) $renderer->pageNo(), $this->text);
62a25f0a04SGreg Roach        // underline «title» part of Source item
63c1010edaSGreg Roach        $temptext = str_replace([
64c1010edaSGreg Roach            '«',
65c1010edaSGreg Roach            '»',
66c1010edaSGreg Roach        ], [
67c1010edaSGreg Roach            '<u>',
68c1010edaSGreg Roach            '</u>',
69c1010edaSGreg Roach        ], $temptext);
70b6f35a76SGreg Roach        echo '<div><a id="footnote', $this->num, '"></a>';
7167c69ce5SGreg Roach        $renderer->write($this->num . '. ' . $temptext);
727a6ee1acSGreg Roach        echo '</div>';
73a25f0a04SGreg Roach
7467c69ce5SGreg Roach        $renderer->setXy(0, $renderer->getY() + $this->getFootnoteHeight($renderer));
75a25f0a04SGreg Roach    }
76a25f0a04SGreg Roach
77a25f0a04SGreg Roach    /**
78a25f0a04SGreg Roach     * Calculates the Footnotes height
79a25f0a04SGreg Roach     *
80b6f35a76SGreg Roach     * @param HtmlRenderer $html
81589feda3SGreg Roach     * @param float        $cellWidth The width of the cell to use it for text wraping
82a25f0a04SGreg Roach     *
83589feda3SGreg Roach     * @return float     Footnote height in points
84a25f0a04SGreg Roach     */
85589feda3SGreg Roach    public function getFootnoteHeight($html, float $cellWidth = 0): float
86c1010edaSGreg Roach    {
87b6f35a76SGreg Roach        if ($html->getCurrentStyle() !== $this->styleName) {
88a25f0a04SGreg Roach            $html->setCurrentStyle($this->styleName);
89a25f0a04SGreg Roach        }
90a25f0a04SGreg Roach
91a25f0a04SGreg Roach        if ($cellWidth > 0) {
92a25f0a04SGreg Roach            $this->text = $html->textWrap($this->text, $cellWidth);
93a25f0a04SGreg Roach        }
94e364afe4SGreg Roach
95e364afe4SGreg Roach        $this->text .= "\n\n";
96a25f0a04SGreg Roach        $ct         = substr_count($this->text, "\n");
97a25f0a04SGreg Roach        $fsize      = $html->getCurrentStyleHeight();
98cbc1590aSGreg Roach
99a25f0a04SGreg Roach        return ($fsize * $ct) * $html->cellHeightRatio;
100a25f0a04SGreg Roach    }
101a25f0a04SGreg Roach
102a25f0a04SGreg Roach    /**
103a25f0a04SGreg Roach     * Get the width of text
104a25f0a04SGreg Roach     * Breaks up a text into lines if needed
105a25f0a04SGreg Roach     *
106b6f35a76SGreg Roach     * @param HtmlRenderer $renderer
107a25f0a04SGreg Roach     *
108*41cfb9e2SGreg Roach     * @return array{0:float,1:int,2:float|int}
109a25f0a04SGreg Roach     */
110*41cfb9e2SGreg Roach    public function getWidth($renderer): array
111c1010edaSGreg Roach    {
112a25f0a04SGreg Roach        // Setup the style name
11367c69ce5SGreg Roach        $renderer->setCurrentStyle('footnotenum');
114a25f0a04SGreg Roach
115a25f0a04SGreg Roach        // Check for the largest font size in the box
11667c69ce5SGreg Roach        $fsize = $renderer->getCurrentStyleHeight();
11767c69ce5SGreg Roach        if ($fsize > $renderer->largestFontHeight) {
11867c69ce5SGreg Roach            $renderer->largestFontHeight = $fsize;
119a25f0a04SGreg Roach        }
120a25f0a04SGreg Roach
121a25f0a04SGreg Roach        // Returns the Object if already numbered else false
122a25f0a04SGreg Roach        if (empty($this->num)) {
12367c69ce5SGreg Roach            $renderer->checkFootnote($this);
124a25f0a04SGreg Roach        }
125a25f0a04SGreg Roach
126a25f0a04SGreg Roach        // Get the line width for the text in points + a little margin
12767c69ce5SGreg Roach        $lw = $renderer->getStringWidth($this->numText);
128a25f0a04SGreg Roach        // Line Feed counter - Number of lines in the text
12967c69ce5SGreg Roach        $lfct = $renderer->countLines($this->numText);
130a25f0a04SGreg Roach        // If there is still remaining wrap width...
131a25f0a04SGreg Roach        if ($this->wrapWidthRemaining > 0) {
132a25f0a04SGreg Roach            // Check with line counter too!
133102a585eSGreg Roach            if ($lw >= $this->wrapWidthRemaining || $lfct > 1) {
1347a6ee1acSGreg Roach                $newtext            = '';
135a25f0a04SGreg Roach                $wrapWidthRemaining = $this->wrapWidthRemaining;
136a25f0a04SGreg Roach                $lines              = explode("\n", $this->numText);
137a25f0a04SGreg Roach                // Go throught the text line by line
138a25f0a04SGreg Roach                foreach ($lines as $line) {
139a25f0a04SGreg Roach                    // Line width in points + a little margin
14067c69ce5SGreg Roach                    $lw = $renderer->getStringWidth($line);
141a25f0a04SGreg Roach                    // If the line has to be wraped
142a25f0a04SGreg Roach                    if ($lw > $wrapWidthRemaining) {
1437a6ee1acSGreg Roach                        $words    = explode(' ', $line);
144a25f0a04SGreg Roach                        $addspace = count($words);
145a25f0a04SGreg Roach                        $lw       = 0;
146a25f0a04SGreg Roach                        foreach ($words as $word) {
147a25f0a04SGreg Roach                            $addspace--;
14867c69ce5SGreg Roach                            $lw += $renderer->getStringWidth($word . ' ');
149a25f0a04SGreg Roach                            if ($lw <= $wrapWidthRemaining) {
150a25f0a04SGreg Roach                                $newtext .= $word;
151b6f35a76SGreg Roach                                if ($addspace !== 0) {
1527a6ee1acSGreg Roach                                    $newtext .= ' ';
153a25f0a04SGreg Roach                                }
154a25f0a04SGreg Roach                            } else {
15567c69ce5SGreg Roach                                $lw = $renderer->getStringWidth($word . ' ');
156a25f0a04SGreg Roach                                $newtext .= "\n$word";
157b6f35a76SGreg Roach                                if ($addspace !== 0) {
1587a6ee1acSGreg Roach                                    $newtext .= ' ';
159a25f0a04SGreg Roach                                }
160a25f0a04SGreg Roach                                // Reset the wrap width to the cell width
161a25f0a04SGreg Roach                                $wrapWidthRemaining = $this->wrapWidthCell;
162a25f0a04SGreg Roach                            }
163a25f0a04SGreg Roach                        }
164a25f0a04SGreg Roach                    } else {
165a25f0a04SGreg Roach                        $newtext .= $line;
166a25f0a04SGreg Roach                    }
167a25f0a04SGreg Roach                    // Check the Line Feed counter
168a25f0a04SGreg Roach                    if ($lfct > 1) {
169a25f0a04SGreg Roach                        // Add a new line feed as long as it’s not the last line
170a25f0a04SGreg Roach                        $newtext .= "\n";
171a25f0a04SGreg Roach                        // Reset the line width
172a25f0a04SGreg Roach                        $lw = 0;
173a25f0a04SGreg Roach                        // Reset the wrap width to the cell width
174a25f0a04SGreg Roach                        $wrapWidthRemaining = $this->wrapWidthCell;
175a25f0a04SGreg Roach                    }
176a25f0a04SGreg Roach                    $lfct--;
177a25f0a04SGreg Roach                }
178a25f0a04SGreg Roach                $this->numText = $newtext;
179a25f0a04SGreg Roach                $lfct          = substr_count($this->numText, "\n");
180cbc1590aSGreg Roach
181c1010edaSGreg Roach                return [
182c1010edaSGreg Roach                    $lw,
183c1010edaSGreg Roach                    1,
184c1010edaSGreg Roach                    $lfct,
185c1010edaSGreg Roach                ];
186a25f0a04SGreg Roach            }
187a25f0a04SGreg Roach        }
188a25f0a04SGreg Roach        $l    = 0;
189a25f0a04SGreg Roach        $lfct = substr_count($this->numText, "\n");
190a25f0a04SGreg Roach        if ($lfct > 0) {
191a25f0a04SGreg Roach            $l = 2;
192a25f0a04SGreg Roach        }
193cbc1590aSGreg Roach
194c1010edaSGreg Roach        return [
195c1010edaSGreg Roach            $lw,
196c1010edaSGreg Roach            $l,
197c1010edaSGreg Roach            $lfct,
198c1010edaSGreg Roach        ];
199a25f0a04SGreg Roach    }
200a25f0a04SGreg Roach}
201