xref: /webtrees/app/Report/ReportHtmlTextbox.php (revision ffd703ea1e658c7dcb5e5f1f9ef137a420f2d167)
1a25f0a04SGreg Roach<?php
2dd04c183SGreg Roachnamespace Fisharebest\Webtrees;
3a25f0a04SGreg Roach
4a25f0a04SGreg Roach/**
5a25f0a04SGreg Roach * webtrees: online genealogy
6a25f0a04SGreg Roach * Copyright (C) 2015 webtrees development team
7a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
8a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
9a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
10a25f0a04SGreg Roach * (at your option) any later version.
11a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
12a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
13a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14a25f0a04SGreg Roach * GNU General Public License for more details.
15a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
16a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
17a25f0a04SGreg Roach */
18a25f0a04SGreg Roach
19a25f0a04SGreg Roach/**
20a25f0a04SGreg Roach * Class ReportHtmlTextbox
21a25f0a04SGreg Roach */
22a25f0a04SGreg Roachclass ReportHtmlTextbox extends ReportBaseTextbox {
23a25f0a04SGreg Roach	/**
24a25f0a04SGreg Roach	 * @param ReportHtml $renderer
25a25f0a04SGreg Roach	 *
26a25f0a04SGreg Roach	 * @return void
27a25f0a04SGreg Roach	 */
28*ffd703eaSGreg Roach	public function render($renderer) {
29a25f0a04SGreg Roach		// checkFootnote
30a25f0a04SGreg Roach		$newelements = array();
31a25f0a04SGreg Roach		$lastelement = array();
32a25f0a04SGreg Roach		$footnote_element = array();
33a25f0a04SGreg Roach		// Element counter
34a25f0a04SGreg Roach		$cE = count($this->elements);
35a25f0a04SGreg Roach		//-- collapse duplicate elements
36a25f0a04SGreg Roach		for ($i = 0; $i < $cE; $i++) {
37a25f0a04SGreg Roach			$element = $this->elements[$i];
38a25f0a04SGreg Roach			if (is_object($element)) {
39a25f0a04SGreg Roach				if ($element instanceof ReportBaseText) {
40a25f0a04SGreg Roach					if (!empty($footnote_element)) {
41a25f0a04SGreg Roach						ksort($footnote_element);
42a25f0a04SGreg Roach						foreach ($footnote_element as $links) {
43a25f0a04SGreg Roach							$newelements[] = $links;
44a25f0a04SGreg Roach						}
45a25f0a04SGreg Roach						$footnote_element = array();
46a25f0a04SGreg Roach					}
47a25f0a04SGreg Roach					if (empty($lastelement)) {
48a25f0a04SGreg Roach						$lastelement = $element;
49a25f0a04SGreg Roach					} else {
50a25f0a04SGreg Roach						// Checking if the Text has the same style
51a25f0a04SGreg Roach						if ($element->getStyleName() == $lastelement->getStyleName()) {
52a25f0a04SGreg Roach							$lastelement->addText(str_replace("\n", "<br>", $element->getValue()));
53a25f0a04SGreg Roach						} elseif (!empty($lastelement)) {
54a25f0a04SGreg Roach							$newelements[] = $lastelement;
55a25f0a04SGreg Roach							$lastelement = $element;
56a25f0a04SGreg Roach						}
57a25f0a04SGreg Roach					}
58a25f0a04SGreg Roach				} // Collect the Footnote links
59a25f0a04SGreg Roach				elseif ($element instanceof ReportBaseFootnote) {
60a25f0a04SGreg Roach					// Check if the Footnote has been set with it’s link number
61a25f0a04SGreg Roach					$renderer->checkFootnote($element);
62a25f0a04SGreg Roach					// Save first the last element if any
63a25f0a04SGreg Roach					if (!empty($lastelement)) {
64a25f0a04SGreg Roach						$newelements[] = $lastelement;
65a25f0a04SGreg Roach						$lastelement = array();
66a25f0a04SGreg Roach					}
67a25f0a04SGreg Roach					// Save the Footnote with it’s link number as key for sorting later
68a25f0a04SGreg Roach					$footnote_element[$element->num] = $element;
69a25f0a04SGreg Roach				} //-- do not keep empty footnotes
70a25f0a04SGreg Roach				elseif (!($element instanceof ReportBaseFootnote) || trim($element->getValue()) != "") {
71a25f0a04SGreg Roach					if (!empty($footnote_element)) {
72a25f0a04SGreg Roach						ksort($footnote_element);
73a25f0a04SGreg Roach						foreach ($footnote_element as $links) {
74a25f0a04SGreg Roach							$newelements[] = $links;
75a25f0a04SGreg Roach						}
76a25f0a04SGreg Roach						$footnote_element = array();
77a25f0a04SGreg Roach					}
78a25f0a04SGreg Roach					if (!empty($lastelement)) {
79a25f0a04SGreg Roach						$newelements[] = $lastelement;
80a25f0a04SGreg Roach						$lastelement = array();
81a25f0a04SGreg Roach					}
82a25f0a04SGreg Roach					$newelements[] = $element;
83a25f0a04SGreg Roach				}
84a25f0a04SGreg Roach			} else {
85a25f0a04SGreg Roach				if (!empty($lastelement)) {
86a25f0a04SGreg Roach					$newelements[] = $lastelement;
87a25f0a04SGreg Roach					$lastelement = array();
88a25f0a04SGreg Roach				}
89a25f0a04SGreg Roach				if (!empty($footnote_element)) {
90a25f0a04SGreg Roach					ksort($footnote_element);
91a25f0a04SGreg Roach					foreach ($footnote_element as $links) {
92a25f0a04SGreg Roach						$newelements[] = $links;
93a25f0a04SGreg Roach					}
94a25f0a04SGreg Roach					$footnote_element = array();
95a25f0a04SGreg Roach				}
96a25f0a04SGreg Roach				$newelements[] = $element;
97a25f0a04SGreg Roach			}
98a25f0a04SGreg Roach		}
99a25f0a04SGreg Roach		if (!empty($lastelement)) {
100a25f0a04SGreg Roach			$newelements[] = $lastelement;
101a25f0a04SGreg Roach		}
102a25f0a04SGreg Roach		if (!empty($footnote_element)) {
103a25f0a04SGreg Roach			ksort($footnote_element);
104a25f0a04SGreg Roach			foreach ($footnote_element as $links) {
105a25f0a04SGreg Roach				$newelements[] = $links;
106a25f0a04SGreg Roach			}
107a25f0a04SGreg Roach		}
108a25f0a04SGreg Roach		$this->elements = $newelements;
109a25f0a04SGreg Roach		unset($footnote_element, $lastelement, $links, $newelements);
110a25f0a04SGreg Roach
111a25f0a04SGreg Roach		$cP = 0; // Class Padding
112a25f0a04SGreg Roach
113a25f0a04SGreg Roach		// Used with line breaks and cell height calculation within this box only
114a25f0a04SGreg Roach		$renderer->largestFontHeight = 0;
115a25f0a04SGreg Roach
116a25f0a04SGreg Roach		// Current position
117a25f0a04SGreg Roach		if ($this->left == ".") {
118a25f0a04SGreg Roach			$cX = $renderer->GetX();
119a25f0a04SGreg Roach		} else {
120a25f0a04SGreg Roach			$cX = $this->left;
121a25f0a04SGreg Roach			$renderer->SetX($cX);
122a25f0a04SGreg Roach		}
123a25f0a04SGreg Roach		// Current position (top)
124a25f0a04SGreg Roach		if ($this->top == ".") {
125a25f0a04SGreg Roach			$this->top = $renderer->GetY();
126a25f0a04SGreg Roach		} else {
127a25f0a04SGreg Roach			$renderer->SetY($this->top);
128a25f0a04SGreg Roach		}
129a25f0a04SGreg Roach
130a25f0a04SGreg Roach		// Check the width if set to page wide OR set by xml to larger then page wide
131a25f0a04SGreg Roach		if ($this->width == 0 || $this->width > $renderer->getRemainingWidth()) {
132a25f0a04SGreg Roach			$this->width = $renderer->getRemainingWidth();
133a25f0a04SGreg Roach		}
134a25f0a04SGreg Roach		// Setup the CellPadding
135a25f0a04SGreg Roach		if ($this->padding) {
136a25f0a04SGreg Roach			$cP = $renderer->cPadding;
137a25f0a04SGreg Roach		}
138a25f0a04SGreg Roach
139a25f0a04SGreg Roach		// For padding, we have to use less wrap width
140a25f0a04SGreg Roach		$cW = $this->width - ($cP * 2);
141a25f0a04SGreg Roach
142a25f0a04SGreg Roach		//-- calculate the text box height
143a25f0a04SGreg Roach		// Number of lines, will be converted to height
144a25f0a04SGreg Roach		$cHT = 0;
145a25f0a04SGreg Roach		// Element height (exept text)
146a25f0a04SGreg Roach		$eH = 0;
147a25f0a04SGreg Roach		// Footnote height (in points)
148a25f0a04SGreg Roach		$fH = 0;
149a25f0a04SGreg Roach		$w = 0;
150a25f0a04SGreg Roach		//-- $lw is an array
151a25f0a04SGreg Roach		// 0 => last line width
152a25f0a04SGreg Roach		// 1 => 1 if text was wrapped, 0 if text did not wrap
153a25f0a04SGreg Roach		// 2 => number of LF
154a25f0a04SGreg Roach		$lw = array();
155a25f0a04SGreg Roach		// Element counter
156a25f0a04SGreg Roach		$cE = count($this->elements);
157a25f0a04SGreg Roach		for ($i = 0; $i < $cE; $i++) {
158a25f0a04SGreg Roach			if (is_object($this->elements[$i])) {
159a25f0a04SGreg Roach				$ew = $this->elements[$i]->setWrapWidth($cW - $w - 2, $cW);
160a25f0a04SGreg Roach				if ($ew == $cW) {
161a25f0a04SGreg Roach					$w = 0;
162a25f0a04SGreg Roach				}
163a25f0a04SGreg Roach				$lw = $this->elements[$i]->getWidth($renderer);
164a25f0a04SGreg Roach				// Text is already gets the # LF
165a25f0a04SGreg Roach				$cHT += $lw[2];
166a25f0a04SGreg Roach				if ($lw[1] == 1) {
167a25f0a04SGreg Roach					$w = $lw[0];
168a25f0a04SGreg Roach				} elseif ($lw[1] == 2) {
169a25f0a04SGreg Roach					$w = 0;
170a25f0a04SGreg Roach				} else {
171a25f0a04SGreg Roach					$w += $lw[0];
172a25f0a04SGreg Roach				}
173a25f0a04SGreg Roach				if ($w > $cW) {
174a25f0a04SGreg Roach					$w = $lw[0];
175a25f0a04SGreg Roach				}
176a25f0a04SGreg Roach				// For anything else but text (images), get the height
177a25f0a04SGreg Roach				$eH += $this->elements[$i]->getHeight($renderer);
178a25f0a04SGreg Roach			} else {
179a25f0a04SGreg Roach				$fH += abs($renderer->getFootnotesHeight($cW));
180a25f0a04SGreg Roach			}
181a25f0a04SGreg Roach		}
182a25f0a04SGreg Roach		// Add up what’s the final height
183a25f0a04SGreg Roach		$cH = $this->height;
184a25f0a04SGreg Roach		// If any element exist
185a25f0a04SGreg Roach		if ($cE > 0) {
186a25f0a04SGreg Roach			// Check if this is text or some other element, like images
187a25f0a04SGreg Roach			if ($eH == 0) {
188a25f0a04SGreg Roach				// Number of LF but at least one line
189a25f0a04SGreg Roach				$cHT = ($cHT + 1) * $renderer->cellHeightRatio;
190a25f0a04SGreg Roach				// Calculate the cell hight with the largest font size used
191a25f0a04SGreg Roach				$cHT = $cHT * $renderer->largestFontHeight;
192a25f0a04SGreg Roach				if ($cH < $cHT) {
193a25f0a04SGreg Roach					$cH = $cHT;
194a25f0a04SGreg Roach				}
195a25f0a04SGreg Roach			} // This is any other element
196a25f0a04SGreg Roach			else {
197a25f0a04SGreg Roach				if ($cH < $eH) {
198a25f0a04SGreg Roach					$cH = $eH;
199a25f0a04SGreg Roach				}
200a25f0a04SGreg Roach				// Add Footnote height to the rest of the height
201a25f0a04SGreg Roach				$cH += $fH;
202a25f0a04SGreg Roach			}
203a25f0a04SGreg Roach		}
204a25f0a04SGreg Roach
205a25f0a04SGreg Roach		unset($lw, $cHT, $fH, $w);
206a25f0a04SGreg Roach
207a25f0a04SGreg Roach		// Finaly, check the last cells height
208a25f0a04SGreg Roach		if ($cH < $renderer->lastCellHeight) {
209a25f0a04SGreg Roach			$cH = $renderer->lastCellHeight;
210a25f0a04SGreg Roach		}
211a25f0a04SGreg Roach		// Update max Y incase of a pagebreak
212a25f0a04SGreg Roach		// We don't want to over write any images or other stuff
213a25f0a04SGreg Roach		$renderer->addMaxY($this->top + $cH);
214a25f0a04SGreg Roach
215a25f0a04SGreg Roach		// Start to print HTML
216a25f0a04SGreg Roach		echo "<div style=\"position:absolute;top:", $this->top, "pt;";
217a25f0a04SGreg Roach		// LTR (left) or RTL (right)
218a25f0a04SGreg Roach		echo $renderer->alignRTL, ":", $cX, "pt;";
219a25f0a04SGreg Roach		// Background color
220a25f0a04SGreg Roach		if ($this->fill) {
221a25f0a04SGreg Roach			if (!empty($this->bgcolor)) {
222a25f0a04SGreg Roach				echo " background-color:", $this->bgcolor, ";";
223a25f0a04SGreg Roach			}
224a25f0a04SGreg Roach		}
225a25f0a04SGreg Roach		// Print padding only when it’s set
226a25f0a04SGreg Roach		if ($this->padding) {
227a25f0a04SGreg Roach			// Use Cell around padding to support RTL also
228a25f0a04SGreg Roach			echo "padding:", $cP, "pt;";
229a25f0a04SGreg Roach		}
230a25f0a04SGreg Roach		// Border setup
231a25f0a04SGreg Roach		if ($this->border) {
232a25f0a04SGreg Roach			echo " border:solid black 1pt;";
233a25f0a04SGreg Roach			echo "width:", ($this->width - 1 - ($cP * 2)), "pt;height:", $cH - 1, "pt;";
234a25f0a04SGreg Roach		} else {
235a25f0a04SGreg Roach			echo "width:", ($this->width - ($cP * 2)), "pt;height:", $cH, "pt;";
236a25f0a04SGreg Roach		}
237a25f0a04SGreg Roach		echo "\">";
238a25f0a04SGreg Roach
239a25f0a04SGreg Roach		// Do a little "margin" trick before print
240a25f0a04SGreg Roach		// to get the correct current position => "."
241a25f0a04SGreg Roach		$cXT = $renderer->GetX();
242a25f0a04SGreg Roach		$cYT = $renderer->GetY();
243a25f0a04SGreg Roach		$renderer->SetXY(0, 0);
244a25f0a04SGreg Roach
245a25f0a04SGreg Roach		// Print the text elements
246a25f0a04SGreg Roach		foreach ($this->elements as $element) {
247a25f0a04SGreg Roach			if (is_object($element)) {
248a25f0a04SGreg Roach				$element->render($renderer, $cX, false);
249a25f0a04SGreg Roach			} elseif (is_string($element) && $element == "footnotetexts") {
250a25f0a04SGreg Roach				$renderer->Footnotes();
251a25f0a04SGreg Roach			} elseif (is_string($element) && $element == "addpage") {
252a25f0a04SGreg Roach				$renderer->AddPage();
253a25f0a04SGreg Roach			}
254a25f0a04SGreg Roach		}
255a25f0a04SGreg Roach		echo "</div>\n";
256a25f0a04SGreg Roach
257a25f0a04SGreg Roach		// Reset "margins"
258a25f0a04SGreg Roach		$renderer->SetXY($cXT, $cYT);
259a25f0a04SGreg Roach		// This will be mostly used to trick the multiple images last height
260a25f0a04SGreg Roach		if ($this->reseth) {
261a25f0a04SGreg Roach			$cH = 0;
262a25f0a04SGreg Roach		}
263a25f0a04SGreg Roach		// New line and some clean up
264a25f0a04SGreg Roach		if (!$this->newline) {
265a25f0a04SGreg Roach			$renderer->SetXY($cX + $this->width, $this->top);
266a25f0a04SGreg Roach			$renderer->lastCellHeight = $cH;
267a25f0a04SGreg Roach		} else {
268a25f0a04SGreg Roach			$renderer->SetXY(0, $this->top + $cH + ($cP * 2));
269a25f0a04SGreg Roach			$renderer->lastCellHeight = 0;
270a25f0a04SGreg Roach		}
271a25f0a04SGreg Roach	}
272a25f0a04SGreg Roach}
273