Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved layout of reports #5055

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/Report/AbstractRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,9 @@ abstract public function createTextBox(
string $style,
bool $fill,
bool $padding,
bool $reseth
bool $reseth,
bool $abs_position,
float $top_position
): ReportBaseTextbox;

/**
Expand Down
27 changes: 18 additions & 9 deletions app/Report/HtmlRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function run(): void
//-- header divider
echo '</style>', PHP_EOL;
echo '<div id="headermargin" style="position: relative; top: auto; height: ', $this->header_margin, 'pt; width: ', $this->noMarginWidth, 'pt;"></div>';
echo '<div id="headerdiv" style="position: relative; top: auto; width: ', $this->noMarginWidth, 'pt;">';
echo '<div id="headerdiv" style="position: relative; top: auto; width: ', $this->noMarginWidth, 'pt;margin-bottom:10pt;text-align:center;">';
foreach ($this->headerElements as $element) {
if ($element instanceof ReportBaseElement) {
$element->render($this);
Expand All @@ -196,9 +196,8 @@ public function run(): void
}
//-- footer
echo '</div>';
echo '<script>document.getElementById("bodydiv").style.height="', $this->maxY, 'pt";</script>';
echo '<div id="bottommargin" style="position: relative; top: auto; height: ', $this->bottom_margin - $this->footer_margin, 'pt;width:', $this->noMarginWidth, 'pt;"></div>';
echo '<div id="footerdiv" style="position: relative; top: auto; width: ', $this->noMarginWidth, 'pt;height:auto;">';
echo '<div id="bottommargin" style="position: relative; z-index: -1; top: ' . $this->Y . 'pt; height: ', $this->bottom_margin - $this->footer_margin, 'pt;width:', $this->noMarginWidth, 'pt;"></div>';
echo '<div id="footerdiv" style="position: relative; top: ' . $this->Y . 'pt; width: ', $this->noMarginWidth, 'pt;height:auto;">';
$this->Y = 0;
$this->X = 0;
$this->maxY = 0;
Expand All @@ -212,8 +211,12 @@ public function run(): void
}
}
echo '</div>';
echo '<script>document.getElementById("footerdiv").style.height="', $this->maxY, 'pt";</script>';
echo '<div id="footermargin" style="position: relative; top: auto; height: ', $this->footer_margin, 'pt;width:', $this->noMarginWidth, 'pt;"></div>';
if ($this->show_generated_by) {
echo '<script>document.getElementsByClassName("genby")[0].style.height="15pt";';
echo 'document.getElementsByClassName("date")[0].style.top="15pt";';
echo '</script>';
}
echo '<div id="footermargin" style="position: relative; z-index: -1; top: auto; height: ', $this->footer_margin, 'pt;width:', $this->noMarginWidth, 'pt;"></div>';
}

/**
Expand Down Expand Up @@ -271,9 +274,11 @@ public function createTextBox(
string $style,
bool $fill,
bool $padding,
bool $reseth
bool $reseth,
bool $abs_position,
float $top_position
): ReportBaseTextbox {
return new ReportHtmlTextbox($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, $abs_position, $top_position);
}

/**
Expand Down Expand Up @@ -524,7 +529,9 @@ public function getStringWidth(string $text): float
{
$style = $this->getStyle($this->currentStyle);

return mb_strlen($text) * $style['size'] / 2;
// &#x..; is counted as 6 chars, not one. Many such chars will force too early line breaks
$txt2 = str_replace(['&#xA0;', '&#x2570;', '&nbsp;', '&mdash;'], ["#", "#", "#", "#"], $text);
return mb_strlen($txt2) * ($style['size'] / 2);
}

/**
Expand Down Expand Up @@ -715,10 +722,12 @@ public function write(string $text, string $color = '', bool $useclass = true):
"\n",
'> ',
' <',
"\xA0",
], [
'<br>',
'>&nbsp;',
'&nbsp;<',
'&nbsp;',
], $htmlcode);
echo $htmlcode;
}
Expand Down
11 changes: 7 additions & 4 deletions app/Report/PdfRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
*/
public function header(): void
{
$this->tcpdf->AddPage();

Check warning on line 77 in app/Report/PdfRenderer.php

View check run for this annotation

Codecov / codecov/patch

app/Report/PdfRenderer.php#L77

Added line #L77 was not covered by tests
foreach ($this->headerElements as $element) {
if ($element instanceof ReportBaseElement) {
$element->render($this);
Expand Down Expand Up @@ -363,8 +364,8 @@
'UTF-8',
self::DISK_CACHE
);

$this->tcpdf->setMargins($this->left_margin, $this->top_margin, $this->right_margin);
$this->tcpdf->setPrintFooter(true);
$this->tcpdf->setMargins($this->left_margin, $this->top_margin, $this->right_margin); // top-margin? 55.5? header-height?
$this->tcpdf->setHeaderMargin($this->header_margin);
$this->tcpdf->setFooterMargin($this->footer_margin);
$this->tcpdf->setAutoPageBreak(true, $this->bottom_margin);
Expand Down Expand Up @@ -454,9 +455,11 @@
string $style,
bool $fill,
bool $padding,
bool $reseth
bool $reseth,
bool $abs_position,
float $top_position
): ReportBaseTextbox {
return new ReportPdfTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth);
return new ReportPdfTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth, $abs_position, $top_position);
}

/**
Expand Down
17 changes: 16 additions & 1 deletion app/Report/ReportBaseTextbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ class ReportBaseTextbox extends ReportBaseElement
// Resets this box last height after it’s done
public bool $reseth;

// position of the TextBox: true=absolute or false=relative:
public bool $abs_position;

// Value of top position
public float $top_position;

// Spec position for pdf textbox
public bool $html_only_position;

/**
* TextBox - Element - Base
*
Expand All @@ -86,6 +95,8 @@ class ReportBaseTextbox extends ReportBaseElement
* @param bool $fill
* @param bool $padding
* @param bool $reseth
* @param bool $abs_position
* @param float $top_position
*/
public function __construct(
float $width,
Expand All @@ -99,7 +110,9 @@ public function __construct(
string $style,
bool $fill,
bool $padding,
bool $reseth
bool $reseth,
bool $abs_position,
float $top_position
) {
$this->border = $border;
$this->bgcolor = $bgcolor;
Expand All @@ -113,6 +126,8 @@ public function __construct(
$this->width = $width;
$this->padding = $padding;
$this->reseth = $reseth;
$this->abs_position = $abs_position;
$this->top_position = $top_position;
}

/**
Expand Down
8 changes: 7 additions & 1 deletion app/Report/ReportHtmlImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,13 @@
echo '<img src="', $this->file, '" style="width:', $this->width, 'pt;height:', $this->height, "pt;\" alt=\"\">\n</div>\n";
break;
default:
echo '<img src="', $this->file, '" style="position:absolute;', $renderer->alignRTL, ':', $this->x, 'pt;top:', $this->y, 'pt;width:', $this->width, 'pt;height:', $this->height, "pt;\" alt=\"\">\n";
// max-height limit distorts where the height exceeds 40pt when width is set to 30pt.
// Such images should be cropped instead
$maxh = "";
if ($this->width <= 30) {
$maxh = "max-height:40pt;";

Check warning on line 69 in app/Report/ReportHtmlImage.php

View check run for this annotation

Codecov / codecov/patch

app/Report/ReportHtmlImage.php#L67-L69

Added lines #L67 - L69 were not covered by tests
}
echo '<img src="', $this->file, '" style="position:absolute;', $renderer->alignRTL, ':', $this->x, 'pt;top:', $this->y, 'pt;width:', $this->width, 'pt;',$maxh, ' alt="">\n';

Check warning on line 71 in app/Report/ReportHtmlImage.php

View check run for this annotation

Codecov / codecov/patch

app/Report/ReportHtmlImage.php#L71

Added line #L71 was not covered by tests
}

$lastpicpage = $renderer->pageNo();
Expand Down
3 changes: 3 additions & 0 deletions app/Report/ReportHtmlText.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ public function render($renderer, bool $attrib = true): void
public function getHeight($renderer): float
{
$ct = substr_count($this->text, "\n");
if (substr($this->text, -1) == "\n") {
$ct -= 1;
}
if ($ct > 0) {
$ct += 1;
}
Expand Down
75 changes: 55 additions & 20 deletions app/Report/ReportHtmlTextbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@
*/
public function render($renderer): void
{
static $lastBoxYfinal;
// checkFootnote
$newelements = [];
$lastelement = [];
$lastelement = null;
$footnote_element = [];
// Element counter
$cE = count($this->elements);
Expand All @@ -58,22 +59,23 @@
}
$footnote_element = [];
}
if (empty($lastelement)) {
if (!isset($lastelement)) {
$lastelement = $element;
} elseif ($element->getStyleName() === $lastelement->getStyleName()) {
// Checking if the Text has the same style
} elseif (($element instanceof ReportBaseText && $lastelement instanceof ReportBaseText) && ($element->getStyleName() === $lastelement->getStyleName())) {
$lastelement->addText(str_replace("\n", '<br>', $element->getValue()));
} else {
$newelements[] = $lastelement;
$lastelement = $element;
}
} elseif ($element instanceof ReportHtmlImage) {
$lastelement = $element;

Check warning on line 71 in app/Report/ReportHtmlTextbox.php

View check run for this annotation

Codecov / codecov/patch

app/Report/ReportHtmlTextbox.php#L71

Added line #L71 was not covered by tests
} elseif ($element instanceof ReportHtmlFootnote) {
// Check if the Footnote has been set with it’s link number
$renderer->checkFootnote($element);
// Save first the last element if any
if (!empty($lastelement)) {
if (isset($lastelement)) {
$newelements[] = $lastelement;
$lastelement = [];
$lastelement = null;
}
// Save the Footnote with it’s link number as key for sorting later
$footnote_element[$element->num] = $element;
Expand All @@ -86,16 +88,16 @@
}
$footnote_element = [];
}
if (!empty($lastelement)) {
if (isset($lastelement)) {
$newelements[] = $lastelement;
$lastelement = [];
$lastelement = null;

Check warning on line 93 in app/Report/ReportHtmlTextbox.php

View check run for this annotation

Codecov / codecov/patch

app/Report/ReportHtmlTextbox.php#L93

Added line #L93 was not covered by tests
}
$newelements[] = $element;
}
} else {
if (!empty($lastelement)) {
if (isset($lastelement)) {
$newelements[] = $lastelement;
$lastelement = [];
$lastelement = null;
}
if (!empty($footnote_element)) {
ksort($footnote_element);
Expand All @@ -107,7 +109,7 @@
$newelements[] = $element;
}
}
if (!empty($lastelement)) {
if (isset($lastelement)) {
$newelements[] = $lastelement;
}
if (!empty($footnote_element)) {
Expand All @@ -132,11 +134,22 @@
$renderer->setX($cX);
}
// If current position (top)
if ($this->top === ReportBaseElement::CURRENT_POSITION) {
$this->top = $renderer->getY();
} else {
$renderer->setY($this->top);
$align_Y = false;
$first_Y = $renderer->getY();
$topstr = "";
if ($this->abs_position) {
if ($this->top == ReportBaseElement::CURRENT_POSITION) {
$this->top = $first_Y;
}
}
if (!$this->abs_position) {
if ($this->top_position !== ReportBaseElement::CURRENT_POSITION) {
$this->top = $this->top_position;
}
$topstr = "top:" . $this->top . "pt;";
$align_Y = true;
}
$renderer->setY($this->top);

// Check the width if set to page wide OR set by xml to larger then page width (margin)
if ($this->width === 0.0 || $this->width > $renderer->getRemainingWidth()) {
Expand Down Expand Up @@ -192,7 +205,8 @@
}

// Add up what’s the final height
$cH = $this->height;
//$cH = $this->height;
$cH = 0;
// If any element exist
if ($cE > 0) {
// Check if this is text or some other element, like images
Expand Down Expand Up @@ -225,7 +239,12 @@
$renderer->addMaxY($this->top + $cH);

// Start to print HTML
echo '<div style="position:absolute;top:', $this->top, 'pt;';
if (!$align_Y) {
echo '<div style="position:absolute;top:', $this->top, 'pt;';
} else {
echo '<div style="position:relative;top:', $this->top, 'pt;';
}
//echo '<div style="position:relative;';
// LTR (left) or RTL (right)
echo $renderer->alignRTL, ':', $cX, 'pt;';
// Background color
Expand All @@ -237,12 +256,23 @@
// Use Cell around padding to support RTL also
echo 'padding:', $cP, 'pt;';
}
//if ($this->html_only_position) { // allow a small margin between images if text is short
// echo "margin-bottom:5pt;";
//}
// Border setup
if ($this->border) {
echo ' border:solid black 1pt;';
echo 'width:', $this->width - 1 - $cP * 2, 'pt;height:', $cH - 1, 'pt;';
if (!$align_Y) {
echo 'width:', $this->width - 1 - $cP * 2, 'pt;height:', $cH - 1, 'pt;';
} else {
echo 'width:', $this->width - 1 - $cP * 2, 'pt;height:auto;';
} // height:',$this->height,'pt;'; //,$topstr;
} else {
echo 'width:', $this->width - $cP * 2, 'pt;height:', $cH, 'pt;';
if (!$align_Y) {
echo 'width:', $this->width - $cP * 2, 'pt;height:', $cH, 'pt;';
} else {
echo 'width:', $this->width - $cP * 2, 'pt;height:auto;';
} //height:',$this->height,'pt;'; //,$topstr;
}
echo '">';

Expand Down Expand Up @@ -270,15 +300,20 @@
$renderer->setXy($cXT, $cYT);
// This will be mostly used to trick the multiple images last height
if ($this->reseth) {
$this->top = $first_Y; //- $cH;
$cH = 0;
}
// New line and some clean up
if (!$this->newline) {
$renderer->setXy($cX + $this->width, $this->top);
$renderer->lastCellHeight = $cH;
} else {
$renderer->setXy(0, $this->top + $cH + $cP * 2);
//$renderer->setXy(0, $this->top + $cH + $cP * 2);
$renderer->setXy(0, $first_Y + $cH + $cP * 2);
$renderer->lastCellHeight = 0;
}
// This will make images in textboxes to ignore images in previous textboxes
// Without this trick the $lastpicbottom in the previos textbox will be used in ReportHtmlImage
$renderer->pageN++;
}
}
Loading
Loading