xref: /webtrees/app/Report/ReportPdfText.php (revision b6db7c1f82484c632c75d5225ce767d398ddc27f)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 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 */
16namespace Fisharebest\Webtrees\Report;
17
18use Fisharebest\Webtrees\Functions\FunctionsRtl;
19
20/**
21 * Class ReportPdfText
22 */
23class ReportPdfText extends ReportBaseText
24{
25    /**
26     * PDF Text renderer
27     *
28     * @param ReportTcpdf $renderer
29     */
30    public function render($renderer)
31    {
32        // Set up the style
33        if ($renderer->getCurrentStyle() != $this->styleName) {
34            $renderer->setCurrentStyle($this->styleName);
35        }
36        $temptext = str_replace('#PAGENUM#', $renderer->PageNo(), $this->text);
37        // underline «title» part of Source item
38        $temptext = str_replace([
39            '«',
40            '»',
41        ], [
42            '<u>',
43            '</u>',
44        ], $temptext);
45
46        // Paint the text color or they might use inherited colors by the previous function
47        $match = [];
48        if (preg_match('/#?(..)(..)(..)/', $this->color, $match)) {
49            $r = hexdec($match[1]);
50            $g = hexdec($match[2]);
51            $b = hexdec($match[3]);
52            $renderer->SetTextColor($r, $g, $b);
53        } else {
54            $renderer->SetTextColor(0, 0, 0);
55        }
56        $temptext = FunctionsRtl::spanLtrRtl($temptext);
57        $temptext = str_replace(
58            [
59                '<br><span dir="rtl" >',
60                '<br><span dir="ltr" >',
61                '> ',
62                ' <',
63            ],
64            [
65                '<span dir="rtl" ><br>',
66                '<span dir="ltr" ><br>',
67                '>&nbsp;',
68                '&nbsp;<',
69            ],
70            $temptext
71        );
72        $renderer->writeHTML(
73            $temptext,
74            false,
75            false,
76            true,
77            false,
78            ''
79        ); //change height - line break etc. - the form is mirror on rtl pages
80        // Reset the text color to black or it will be inherited
81        $renderer->SetTextColor(0, 0, 0);
82    }
83
84    /**
85     * Returns the height in points of the text element
86     *
87     * The height is already calculated in getWidth()
88     *
89     * @param ReportTcpdf $pdf
90     *
91     * @return float 0
92     */
93    public function getHeight($pdf)
94    {
95        return 0;
96    }
97
98    /**
99     * Splits the text into lines if necessary to fit into a giving cell
100     *
101     * @param ReportTcpdf $pdf
102     *
103     * @return array
104     */
105    public function getWidth($pdf)
106    {
107        // Setup the style name, a font must be selected to calculate the width
108        if ($pdf->getCurrentStyle() != $this->styleName) {
109            $pdf->setCurrentStyle($this->styleName);
110        }
111        // Check for the largest font size in the box
112        $fsize = $pdf->getCurrentStyleHeight();
113        if ($fsize > $pdf->largestFontHeight) {
114            $pdf->largestFontHeight = $fsize;
115        }
116
117        // Get the line width
118        $lw = $pdf->GetStringWidth($this->text);
119        // Line Feed counter - Number of lines in the text
120        $lfct = substr_count($this->text, "\n") + 1;
121        // If there is still remaining wrap width...
122        if ($this->wrapWidthRemaining > 0) {
123            // Check with line counter too!
124            // but floor the $wrapWidthRemaining first to keep it bugfree!
125            $wrapWidthRemaining = (int)($this->wrapWidthRemaining);
126            if ($lw >= $wrapWidthRemaining || $lfct > 1) {
127                $newtext = '';
128                $lines   = explode("\n", $this->text);
129                // Go throught the text line by line
130                foreach ($lines as $line) {
131                    // Line width in points + a little margin
132                    $lw = $pdf->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 += $pdf->GetStringWidth($word . ' ');
141                            if ($lw <= $wrapWidthRemaining) {
142                                $newtext .= $word;
143                                if ($addspace != 0) {
144                                    $newtext .= ' ';
145                                }
146                            } else {
147                                $lw      = $pdf->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 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->text = $newtext;
171                $lfct       = substr_count($this->text, "\n");
172
173                return [
174                    $lw,
175                    1,
176                    $lfct,
177                ];
178            }
179        }
180        $l    = 0;
181        $lfct = substr_count($this->text, "\n");
182        if ($lfct > 0) {
183            $l = 2;
184        }
185
186        return [
187            $lw,
188            $l,
189            $lfct,
190        ];
191    }
192}
193