. */ namespace Fisharebest\Webtrees\Report; use Fisharebest\Webtrees\Controller\SimpleController; use Fisharebest\Webtrees\Functions\FunctionsRtl; use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Media; /** * Class ReportHtml */ class ReportHtml extends ReportBase { /** * Cell padding * * @var int */ public $cPadding = 2; /** * Cell height ratio * * @var float */ public $cellHeightRatio = 1.8; /** * Current horizontal position * * @var float */ public $X = 0.0; /** * Current vertical position * * @var float */ public $Y = 0.0; /** * Currently used style name * * @var string */ public $currentStyle = ''; /** * Page number counter * * @var int */ public $pageN = 1; /** * Store the page width without left and right margins * * In HTML, we don't need this * * @var float */ public $noMarginWidth = 0.0; /** * Last cell height * * @var float */ public $lastCellHeight = 0.0; /** * LTR or RTL alignement; "left" on LTR, "right" on RTL * Used in
* * @var string */ public $alignRTL = 'left'; /** * LTR or RTL entity * * @var string */ public $entityRTL = '‎'; /** * Largest Font Height is used by TextBox etc. * * Use this to calculate a the text height. * This makes sure that the text fits into the cell/box when different font sizes are used * * @var int */ public $largestFontHeight = 0; /** * Keep track of the highest Y position * * Used with Header div / Body div / Footer div / "addpage" / The bottom of the last image etc. * * @var float */ public $maxY = 0; /** @var ReportBaseElement[] Array of elements in the header */ public $headerElements = array(); /** @var ReportBaseElement[] Array of elements in the page header */ public $pageHeaderElements = array(); /** @var ReportBaseElement[] Array of elements in the footer */ public $footerElements = array(); /** @var ReportBaseElement[] Array of elements in the body */ public $bodyElements = array(); /** @var ReportBaseFootnote[] Array of elements in the footer notes */ public $printedfootnotes = array(); /** * HTML Setup - ReportHtml */ public function setup() { parent::setup(); // Setting up the correct dimensions if Portrait (default) or Landscape if ($this->orientation == "landscape") { $tmpw = $this->pagew; $this->pagew = $this->pageh; $this->pageh = $tmpw; } // Store the pagewidth without margins $this->noMarginWidth = (int) ($this->pagew - $this->leftmargin - $this->rightmargin); // If RTL if ($this->rtl) { $this->alignRTL = "right"; $this->entityRTL = "‏"; } // Change the default HTML font name $this->defaultFont = "Arial"; if ($this->showGenText) { // The default style name for Generated by.... is 'genby' $element = new ReportHtmlCell(0, 10, 0, 'C', '', 'genby', 1, '.', '.', 0, 0, '', '', true); $element->addText($this->generatedby); $element->setUrl(parent::WT_URL); $this->footerElements[] = $element; } } /** * Add an element. * * @param $element */ public function addElement($element) { if ($this->processing == "B") { $this->bodyElements[] = $element; } elseif ($this->processing == "H") { $this->headerElements[] = $element; } elseif ($this->processing == "F") { $this->footerElements[] = $element; } } /** * Generate the page header */ public function runPageHeader() { foreach ($this->pageHeaderElements as $element) { if (is_object($element)) { $element->render($this); } elseif (is_string($element) && $element == "footnotetexts") { $this->footnotes(); } elseif (is_string($element) && $element == "addpage") { $this->addPage(); } } } /** * Generate footnotes */ public function footnotes() { $this->currentStyle = ""; if (!empty($this->printedfootnotes)) { foreach ($this->printedfootnotes as $element) { $element->renderFootnote($this); } } } /** * Run the report. */ public function run() { $controller = new SimpleController; $controller ->setPageTitle($this->title) ->pageHeader(); // Setting up the styles echo '', PHP_EOL; echo '
'; echo '
'; foreach ($this->headerElements as $element) { if (is_object($element)) { $element->render($this); } elseif (is_string($element) && $element == "footnotetexts") { $this->footnotes(); } elseif (is_string($element) && $element == "addpage") { $this->addPage(); } } //-- body echo '
'; echo ''; echo '
'; $this->Y = 0; $this->maxY = 0; $this->runPageHeader(); foreach ($this->bodyElements as $element) { if (is_object($element)) { $element->render($this); } elseif (is_string($element) && $element == "footnotetexts") { $this->footnotes(); } elseif (is_string($element) && $element == "addpage") { $this->addPage(); } } //-- footer echo '
'; echo ''; echo '
'; echo '
'; $this->Y = 0; $this->X = 0; $this->maxY = 0; foreach ($this->footerElements as $element) { if (is_object($element)) { $element->render($this); } elseif (is_string($element) && $element == "footnotetexts") { $this->footnotes(); } elseif (is_string($element) && $element == "addpage") { $this->addPage(); } } echo '
'; echo ''; echo '
'; } /** * Create a new Cell object - ReportHtml * * @param int $width cell width (expressed in points) * @param int $height cell height (expressed in points) * @param mixed $border Border style * @param string $align Text alignement * @param string $bgcolor Background color code * @param string $style The name of the text style * @param int $ln Indicates where the current position should go after the call * @param mixed $top Y-position * @param mixed $left X-position * @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0. * @param int $stretch Stretch carachter mode * @param string $bocolor Border color * @param string $tcolor Text color * @param bool $reseth * * @return object ReportHtmlCell */ public function createCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth) { return new ReportHtmlCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth); } /** * Create a text box. * * @param $width * @param $height * @param $border * @param $bgcolor * @param $newline * @param $left * @param $top * @param $pagecheck * @param $style * @param $fill * @param $padding * @param $reseth * * @return ReportHtmlTextbox */ public function createTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth) { return new ReportHtmlTextbox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth); } /** * Create a text element. * * @param $style * @param $color * * @return ReportHtmlText */ public function createText($style, $color) { return new ReportHtmlText($style, $color); } /** * Create a footnote. * * @param string $style * * @return ReportHtmlFootnote */ public function createFootnote($style = "") { return new ReportHtmlFootnote($style); } /** * Create a page header. * * @return ReportHtmlPageheader */ public function createPageHeader() { return new ReportHtmlPageheader; } /** * Create an image. * * @param $file * @param $x * @param $y * @param $w * @param $h * @param $align * @param $ln * * @return ReportHtmlImage */ public function createImage($file, $x, $y, $w, $h, $align, $ln) { return new ReportHtmlImage($file, $x, $y, $w, $h, $align, $ln); } /** * Create an image. * * @param Media $mediaobject * @param $x * @param $y * @param $w * @param $h * @param $align * @param $ln * * @return ReportHtmlImage */ public function createImageFromObject(Media $mediaobject, $x, $y, $w, $h, $align, $ln) { return new ReportHtmlImage($mediaobject->getHtmlUrlDirect('thumb'), $x, $y, $w, $h, $align, $ln); } /** * Create a line. * * @param $x1 * @param $y1 * @param $x2 * @param $y2 * * @return ReportHtmlLine */ public function createLine($x1, $y1, $x2, $y2) { return new ReportHtmlLine($x1, $y1, $x2, $y2); } /** * Create an HTML element. * * @param $tag * @param $attrs * * @return ReportHtmlHtml */ public function createHTML($tag, $attrs) { return new ReportHtmlHtml($tag, $attrs); } /** * Clear the Header - ReportHtml */ public function clearHeader() { $this->headerElements = array(); } /** * Update the Page Number and set a new Y if max Y is larger - ReportHtml */ public function addPage() { $this->pageN++; // Add a little margin to max Y "between pages" $this->maxY += 10; // If Y is still heigher by any reason... if ($this->maxY < $this->Y) { // ... update max Y $this->maxY = $this->Y; } // else update Y so that nothing will be overwritten, like images or cells... else { $this->Y = $this->maxY; } } /** * Uppdate max Y to keep track it incase of a pagebreak - ReportHtml * * @param float $y */ public function addMaxY($y) { if ($this->maxY < $y) { $this->maxY = $y; } } /** * Add a page header. * * @param $element * * @return int */ public function addPageHeader($element) { $this->pageHeaderElements[] = $element; return count($this->headerElements) - 1; } /** * Checks the Footnote and numbers them - ReportHtml * * @param object $footnote * * @return bool false if not numbered before | object if already numbered */ public function checkFootnote($footnote) { $ct = count($this->printedfootnotes); $i = 0; $val = $footnote->getValue(); while ($i < $ct) { if ($this->printedfootnotes[$i]->getValue() == $val) { // If this footnote already exist then set up the numbers for this object $footnote->setNum($i + 1); $footnote->setAddlink($i + 1); return $this->printedfootnotes[$i]; } $i++; } // If this Footnote has not been set up yet $footnote->setNum($ct + 1); $footnote->setAddlink($ct + 1); $this->printedfootnotes[] = $footnote; return false; } /** * Clear the Page Header - ReportHtml */ public function clearPageHeader() { $this->pageHeaderElements = array(); } /** * Count the number of lines - ReportHtml * * @param string $str * * @return int Number of lines. 0 if empty line */ public function countLines($str) { if ($str == "") { return 0; } return (substr_count($str, "\n") + 1); } /** * Get the current style. * * @return string */ public function getCurrentStyle() { return $this->currentStyle; } /** * Get the current style height. * * @return int */ public function getCurrentStyleHeight() { if (empty($this->currentStyle)) { return $this->defaultFontSize; } $style = $this->getStyle($this->currentStyle); return $style["size"]; } /** * Get the current footnotes height. * * @param $cellWidth * * @return int */ public function getFootnotesHeight($cellWidth) { $h = 0; foreach ($this->printedfootnotes as $element) { $h += $element->getFootnoteHeight($this, $cellWidth); } return $h; } /** * Get the maximum width from current position to the margin - ReportHtml * * @return float */ public function getRemainingWidth() { return $this->noMarginWidth - $this->X; } /** * Get the page height. * * @return float */ public function getPageHeight() { return $this->pageh - $this->topmargin; } /** * Get the width of a string. * * @param $text * * @return int */ public function getStringWidth($text) { $style = $this->getStyle($this->currentStyle); return mb_strlen($text) * ($style['size'] / 2); } /** * Get a text height in points - ReportHtml * * @param $str * * @return int */ public function getTextCellHeight($str) { // Count the number of lines to calculate the height $nl = $this->countLines($str); // Calculate the cell height return ceil(($this->getCurrentStyleHeight() * $this->cellHeightRatio) * $nl); } /** * Get the current X position - ReportHtml * * @return float */ public function getX() { return $this->X; } /** * Get the current Y position - ReportHtml * * @return float */ public function getY() { return $this->Y; } /** * Get the current page number - ReportHtml * * @return int */ public function pageNo() { return $this->pageN; } /** * Set the current style. * * @param $s */ public function setCurrentStyle($s) { $this->currentStyle = $s; } /** * Set the X position - ReportHtml * * @param float $x */ public function setX($x) { $this->X = $x; } /** * Set the Y position - ReportHtml * * Also updates Max Y position * * @param float $y */ public function setY($y) { $this->Y = $y; if ($this->maxY < $y) { $this->maxY = $y; } } /** * Set the X and Y position - ReportHtml * * Also updates Max Y position * * @param float $x * @param float $y */ public function setXy($x, $y) { $this->setX($x); $this->setY($y); } /** * Wrap text - ReportHtml * * @param string $str Text to wrap * @param int $width Width in points the text has to fit into * * @return string */ public function textWrap($str, $width) { // Calculate the line width $lw = (int) ($width / ($this->getCurrentStyleHeight() / 2)); // Wordwrap each line $lines = explode("\n", $str); // Line Feed counter $lfct = count($lines); $wraptext = ''; foreach ($lines as $line) { $wtext = FunctionsRtl::utf8WordWrap($line, $lw, "\n", true); $wraptext .= $wtext; // Add a new line as long as it’s not the last line if ($lfct > 1) { $wraptext .= "\n"; } $lfct--; } return $wraptext; } /** * Write text - ReportHtml * * @param string $text Text to print * @param string $color HTML RGB color code (Ex: #001122) * @param bool $useclass */ public function write($text, $color = '', $useclass = true) { $style = $this->getStyle($this->getCurrentStyle()); $htmlcode = ''; $htmlcode = str_replace(array("\n", '> ', ' <'), array('
', '> ', ' <'), $htmlcode); echo $htmlcode; } }