xref: /webtrees/app/Report/ReportHtmlCell.php (revision d80c4b28d3dd97de13a4ad436b779827c4469651)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Report;
21
22use function str_contains;
23use function str_replace;
24use function stripos;
25
26/**
27 * Class ReportHtmlCell
28 */
29class ReportHtmlCell extends ReportBaseCell
30{
31    /**
32     * HTML Cell renderer
33     *
34     * @param HtmlRenderer $renderer
35     *
36     * @return void
37     */
38    public function render($renderer): void
39    {
40        if (str_contains($this->text, '{{:ptp:}}')) {
41            return;
42        }
43        $temptext = str_replace('#PAGENUM#', (string) $renderer->pageNo(), $this->text);
44        // underline «title» part of Source item
45        $temptext = str_replace([
46            '«',
47            '»',
48        ], [
49            '<u>',
50            '</u>',
51        ], $temptext);
52
53        // Set up the text style
54        if ($renderer->getCurrentStyle() !== $this->styleName) {
55            $renderer->setCurrentStyle($this->styleName);
56        }
57
58        // If (Future-feature-enable/disable cell padding)
59        $cP = $renderer->cPadding;
60
61        // Adjust the positions
62        if ($this->left === ReportBaseElement::CURRENT_POSITION) {
63            $this->left = $renderer->getX();
64        } else {
65            $renderer->setX($this->left);
66        }
67
68        if ($this->top === ReportBaseElement::CURRENT_POSITION) {
69            $this->top = $renderer->getY();
70        } else {
71            $renderer->setY($this->top);
72        }
73
74        // Start collecting the HTML code
75        echo '<div class="', $this->styleName, '" style="position:absolute;top:', $this->top, 'pt;';
76        // Use Cell around padding to support RTL also
77        echo 'padding:', $cP, 'pt;';
78        // LTR (left) or RTL (right)
79        echo $renderer->alignRTL, ':', $this->left, 'pt;';
80
81        // Background color
82        if (!empty($this->bgcolor)) {
83            echo 'background-color:', $this->bgcolor, ';';
84        }
85
86        // Borders
87        $bpixX = 0;
88        $bpixY = 0;
89        if (!empty($this->border)) {
90            // Border all around
91            if ($this->border === '1') {
92                echo ' border:solid ', $this->bocolor ?: 'black', ' 1pt;';
93                $bpixX = 1;
94                $bpixY = 1;
95            } else {
96                if (str_contains($this->border, 'T')) {
97                    echo ' border-top:solid ', $this->bocolor ?: 'black', ' 1pt;';
98                    $bpixY = 1;
99                }
100                if (str_contains($this->border, 'B')) {
101                    echo ' border-bottom:solid ', $this->bocolor ?: 'black', ' 1pt;';
102                    $bpixY = 1;
103                }
104                if (str_contains($this->border, 'R')) {
105                    echo ' border-right:solid ', $this->bocolor ?: 'black', ' 1pt;';
106                    $bpixX = 1;
107                }
108                if (str_contains($this->border, 'L')) {
109                    echo ' border-left:solid ', $this->bocolor ?: 'black', ' 1pt;';
110                    $bpixX = 1;
111                }
112            }
113        }
114        // Check the width if set to page wide OR set by xml to larger then page wide
115        if ($this->width === 0.0 || $this->width > $renderer->getRemainingWidth()) {
116            $this->width = $renderer->getRemainingWidth();
117        }
118        // We have to calculate a different width for the padding, counting on both side
119        $cW = $this->width - $cP * 2.0;
120
121        // If there is any text
122        if (!empty($temptext)) {
123            // Wrap the text
124            $temptext = $renderer->textWrap($temptext, $cW);
125            $tmph     = $renderer->getTextCellHeight($temptext);
126            // Add some cell padding
127            $this->height += $cP;
128            if ($tmph > $this->height) {
129                $this->height = $tmph;
130            }
131        }
132        // Check the last cell height and adjust the current cell height if needed
133        if ($renderer->lastCellHeight > $this->height) {
134            $this->height = $renderer->lastCellHeight;
135        }
136        echo ' width:', $cW - $bpixX, 'pt;height:', $this->height - $bpixY, 'pt;';
137
138        // Text alignment
139        switch ($this->align) {
140            case 'C':
141                echo ' text-align:center;';
142                break;
143            case 'L':
144                echo ' text-align:left;';
145                break;
146            case 'R':
147                echo ' text-align:right;';
148                break;
149        }
150
151        // Print the collected HTML code
152        echo '">';
153
154        // Print URL
155        if (!empty($this->url)) {
156            echo '<a href="', $this->url, '">';
157        }
158        // Print any text if exists
159        if (!empty($temptext)) {
160            $renderer->write($temptext, $this->tcolor, false);
161        }
162        if (!empty($this->url)) {
163            echo '</a>';
164        }
165        // Finish the cell printing and start to clean up
166        echo "</div>\n";
167
168        // Where to place the next position
169        if ($this->newline === 0) {
170            // -> Next to this cell in the same line
171            $renderer->setXy($this->left + $this->width, $this->top);
172            $renderer->lastCellHeight = $this->height;
173        } elseif ($this->newline === 1) {
174            // -> On a new line at the margin - Default
175            $renderer->setXy(0, $renderer->getY() + $this->height + $cP * 2);
176            // Reset the last cell height for the next line
177            $renderer->lastCellHeight = 0;
178        } elseif ($this->newline === 2) {
179            // -> On a new line at the end of this cell
180            $renderer->setXy($renderer->getX() + $this->width, $renderer->getY() + $this->height + $cP * 2);
181            // Reset the last cell height for the next line
182            $renderer->lastCellHeight = 0;
183        }
184    }
185}
186