xref: /webtrees/app/Report/ReportHtmlCell.php (revision 24f2a3af38709f9bf0a739b30264240d20ba34e8)
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)
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 ';
93                if (!empty($this->bocolor)) {
94                    echo $this->bocolor;
95                } else {
96                    echo 'black';
97                }
98                echo ' 1pt;';
99                $bpixX = 1;
100                $bpixY = 1;
101            } else {
102                if (stripos($this->border, 'T') !== false) {
103                    echo ' border-top:solid ';
104                    if (!empty($this->bocolor)) {
105                        echo $this->bocolor;
106                    } else {
107                        echo 'black';
108                    }
109                    echo ' 1pt;';
110                    $bpixY = 1;
111                }
112                if (stripos($this->border, 'B') !== false) {
113                    echo ' border-bottom:solid ';
114                    if (!empty($this->bocolor)) {
115                        echo $this->bocolor;
116                    } else {
117                        echo 'black';
118                    }
119                    echo ' 1pt;';
120                    $bpixY = 1;
121                }
122                if (stripos($this->border, 'R') !== false) {
123                    echo ' border-right:solid ';
124                    if (!empty($this->bocolor)) {
125                        echo $this->bocolor;
126                    } else {
127                        echo 'black';
128                    }
129                    echo ' 1pt;';
130                    $bpixX = 1;
131                }
132                if (stripos($this->border, 'L') !== false) {
133                    echo ' border-left:solid ';
134                    if (!empty($this->bocolor)) {
135                        echo $this->bocolor;
136                    } else {
137                        echo 'black';
138                    }
139                    echo ' 1pt;';
140                    $bpixX = 1;
141                }
142            }
143        }
144        // Check the width if set to page wide OR set by xml to larger then page wide
145        if ($this->width == 0 || $this->width > $renderer->getRemainingWidth()) {
146            $this->width = $renderer->getRemainingWidth();
147        }
148        // We have to calculate a different width for the padding, counting on both side
149        $cW = $this->width - ($cP * 2);
150
151        // If there is any text
152        if (!empty($temptext)) {
153            // Wrap the text
154            $temptext = $renderer->textWrap($temptext, $cW);
155            $tmph     = $renderer->getTextCellHeight($temptext);
156            // Add some cell padding
157            $this->height += $cP;
158            if ($tmph > $this->height) {
159                $this->height = $tmph;
160            }
161        }
162        // Check the last cell height and adjust the current cell height if needed
163        if ($renderer->lastCellHeight > $this->height) {
164            $this->height = $renderer->lastCellHeight;
165        }
166        echo ' width:', $cW - $bpixX, 'pt;height:', $this->height - $bpixY, 'pt;';
167
168        // Text alignment
169        switch ($this->align) {
170            case 'C':
171                echo ' text-align:center;';
172                break;
173            case 'L':
174                echo ' text-align:left;';
175                break;
176            case 'R':
177                echo ' text-align:right;';
178                break;
179        }
180
181        // Print the collected HTML code
182        echo '">';
183
184        // Print URL
185        if (!empty($this->url)) {
186            echo '<a href="', $this->url, '">';
187        }
188        // Print any text if exists
189        if (!empty($temptext)) {
190            $renderer->write($temptext, $this->tcolor, false);
191        }
192        if (!empty($this->url)) {
193            echo '</a>';
194        }
195        // Finish the cell printing and start to clean up
196        echo "</div>\n";
197
198        // Where to place the next position
199        if ($this->newline === 0) {
200            // -> Next to this cell in the same line
201            $renderer->setXy($this->left + $this->width, $this->top);
202            $renderer->lastCellHeight = $this->height;
203        } elseif ($this->newline === 1) {
204            // -> On a new line at the margin - Default
205            $renderer->setXy(0, $renderer->getY() + $this->height + ($cP * 2));
206            // Reset the last cell height for the next line
207            $renderer->lastCellHeight = 0;
208        } elseif ($this->newline === 2) {
209            // -> On a new line at the end of this cell
210            $renderer->setXy($renderer->getX() + $this->width, $renderer->getY() + $this->height + ($cP * 2));
211            // Reset the last cell height for the next line
212            $renderer->lastCellHeight = 0;
213        }
214    }
215}
216