From 33ebd313ea54fe101f8e2639d61c896b1578f80d Mon Sep 17 00:00:00 2001 From: nicolaasuni Date: Mon, 15 Apr 2024 22:31:39 +0100 Subject: [PATCH] Add border position option --- VERSION | 2 +- examples/index.php | 58 ++++++++++++++++++- src/Cell.php | 139 +++++++++++++++++++++++++++++++++++++++------ src/Text.php | 2 + 4 files changed, 181 insertions(+), 20 deletions(-) diff --git a/VERSION b/VERSION index cc22b78..7eec922 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.60 +8.0.61 diff --git a/examples/index.php b/examples/index.php index f53e6aa..e4cd94d 100644 --- a/examples/index.php +++ b/examples/index.php @@ -1140,7 +1140,7 @@ ]; $txtcell1 = $pdf->getTextCell( - 'CELL', // string $txt, + 'DEFAULT', // string $txt, 20, // float $posx = 0, 100, // float $posy = 0, 0, // float $width = 0, @@ -1165,6 +1165,62 @@ ); $pdf->page->addContent($txtcell1); +$pdf->setDefaultCellBorderPos($pdf::BORDERPOS_EXTERNAL); +$txtcell2 = $pdf->getTextCell( + 'EXTERNAL', // string $txt, + 49, // float $posx = 0, + 100, // float $posy = 0, + 0, // float $width = 0, + 0, // float $height = 0, + 0, // float $offset = 0, + 0, // float $linespace = 0, + 'C', // string $valign = 'C', + 'C', // string $halign = 'C', + null, // ?array $cell = null, + $style_cell, // array $styles = [], + 0, // float $strokewidth = 0, + 0, // float $wordspacing = 0, + 0, // float $leading = 0, + 0, // float $rise = 0, + true, // bool $jlast = true, + true, // bool $fill = true, + false, // bool $stroke = false, + false, // bool $clip = false, + true, // bool $drawcell = true, + '', // string $forcedir = '', + null // ?array $shadow = null, +); +$pdf->page->addContent($txtcell2); + +$pdf->setDefaultCellBorderPos($pdf::BORDERPOS_INTERNAL); +$txtcell2 = $pdf->getTextCell( + 'INTERNAL', // string $txt, + 80, // float $posx = 0, + 100, // float $posy = 0, + 0, // float $width = 0, + 0, // float $height = 0, + 0, // float $offset = 0, + 0, // float $linespace = 0, + 'C', // string $valign = 'C', + 'C', // string $halign = 'C', + null, // ?array $cell = null, + $style_cell, // array $styles = [], + 0, // float $strokewidth = 0, + 0, // float $wordspacing = 0, + 0, // float $leading = 0, + 0, // float $rise = 0, + true, // bool $jlast = true, + true, // bool $fill = true, + false, // bool $stroke = false, + false, // bool $clip = false, + true, // bool $drawcell = true, + '', // string $forcedir = '', + null // ?array $shadow = null, +); +$pdf->page->addContent($txtcell2); + + +$pdf->setDefaultCellBorderPos($pdf::BORDERPOS_DEFAULT); $txtcell2 = $pdf->getTextCell( $txt3, // string $txt, diff --git a/src/Cell.php b/src/Cell.php index 490c459..08c60fb 100644 --- a/src/Cell.php +++ b/src/Cell.php @@ -44,10 +44,29 @@ * 'B': float, * 'L': float, * }, + * 'borderpos': float, * } */ abstract class Cell extends \Com\Tecnick\Pdf\Base { + /** + * The default relative position of the cell origin when + * the border is centered on the cell edge. + */ + public const BORDERPOS_DEFAULT = 0; + + /** + * The relative position of the cell origin when + * the border is external to the cell edge. + */ + public const BORDERPOS_EXTERNAL = -0.5; //-1/2 + + /** + * The relative position of the cell origin when + * the border is internal to the cell edge. + */ + public const BORDERPOS_INTERNAL = 0.5; // 1/2 + /** * Default values for cell. * @@ -66,6 +85,7 @@ abstract class Cell extends \Com\Tecnick\Pdf\Base 'B' => 0, 'L' => 0, ], + 'borderpos' => self::BORDERPOS_DEFAULT, ]; /** @@ -115,6 +135,28 @@ public function setDefaultCellPadding( $this->defcell['padding']['L'] = $this->toPoints($left); } + /** + * Sets the default cell border position. + * + * @param float $borderpos The border position to set: + * BORDERPOS_DEFAULT + * BORDERPOS_EXTERNAL + * BORDERPOS_INTERNAL + */ + public function setDefaultCellBorderPos(float $borderpos): void + { + if ( + ($borderpos == self::BORDERPOS_DEFAULT) + || ($borderpos == self::BORDERPOS_EXTERNAL) + || ($borderpos == self::BORDERPOS_INTERNAL) + ) { + $this->defcell['borderpos'] = $borderpos; + return; + } + + $this->defcell['borderpos'] = self::BORDERPOS_DEFAULT; + } + /** * Increase the cell padding to account for the border tickness. * @@ -135,12 +177,14 @@ protected function adjustMinCellPadding( $styles = $this->graph->getCurrentStyleArray(); } + $border_ratio = round(self::BORDERPOS_INTERNAL + $cell['borderpos'], 1); + $minT = 0; $minR = 0; $minB = 0; $minL = 0; if (! empty($styles['all']['lineWidth'])) { - $minT = $this->toPoints((float) $styles['all']['lineWidth']); + $minT = $this->toPoints((float) $styles['all']['lineWidth'] * $border_ratio); $minR = $minT; $minB = $minT; $minL = $minT; @@ -151,10 +195,10 @@ protected function adjustMinCellPadding( && isset($styles[2]['lineWidth']) && isset($styles[3]['lineWidth']) ) { - $minT = $this->toPoints((float) $styles[0]['lineWidth']); - $minR = $this->toPoints((float) $styles[1]['lineWidth']); - $minB = $this->toPoints((float) $styles[2]['lineWidth']); - $minL = $this->toPoints((float) $styles[3]['lineWidth']); + $minT = $this->toPoints((float) $styles[0]['lineWidth'] * $border_ratio); + $minR = $this->toPoints((float) $styles[1]['lineWidth'] * $border_ratio); + $minB = $this->toPoints((float) $styles[2]['lineWidth'] * $border_ratio); + $minL = $this->toPoints((float) $styles[3]['lineWidth'] * $border_ratio); } else { return $cell; } @@ -240,9 +284,9 @@ protected function cellMinWidth( default: case 'L': // Left case 'R': // Right - return ($txtwidth + $cell['padding']['L'] + $cell['padding']['R']); + return ceil($txtwidth + $cell['padding']['L'] + $cell['padding']['R']); case 'C': // Center - return ($txtwidth + (2 * max($cell['padding']['L'], $cell['padding']['R']))); + return ceil($txtwidth + (2 * max($cell['padding']['L'], $cell['padding']['R']))); } } @@ -578,6 +622,7 @@ protected function setPageContext(): void * @param float $pwidth Cell width in internal points. * @param float $pheight Cell height in internal points. * @param array $styles Optional to overwrite the styles (see: getCurrentStyleArray). + * @param ?TCellDef $cell Optional to overwrite cell parameters for padding, margin etc. * * @return string */ @@ -586,34 +631,92 @@ protected function drawCell( float $pnty, float $pwidth, float $pheight, - array $styles = [] + array $styles = [], + ?array $cell = null ) { - $mode = empty($styles['all']['fillColor']) ? 's' : 'b'; + + $drawfill = (!empty($styles['all']['fillColor'])); + $drawborder = ( + !empty($styles['all']['lineWidth']) + || !empty($styles[0]['lineWidth']) + || !empty($styles[1]['lineWidth']) + || !empty($styles[2]['lineWidth']) + || !empty($styles[3]['lineWidth']) + ); + + if (!$drawfill && !$drawborder) { + return ''; + } + + if ($cell === null) { + $cell = $this->defcell; + } + + $styleall = (empty($styles['all']) ? [] : $styles['all']); $out = $this->graph->getStartTransform(); + $stoptr = $this->graph->getStopTransform(); - if (count($styles) <= 1) { + if ( + $drawfill + && $drawborder + && ($cell['borderpos'] == self::BORDERPOS_DEFAULT) + && (count($styles) <= 1) + ) { + // single default border style for all sides $out .= $this->graph->getBasicRect( $this->toUnit($pntx), $this->toYUnit($pnty), $this->toUnit($pwidth), $this->toUnit($pheight), - $mode, - (empty($styles['all']) ? [] : $styles['all']), + 'b', // close, fill, and then stroke the path + $styleall, ); - } else { - $out .= $this->graph->getRect( + + return $out . $stoptr; + } + + if ($drawfill) { + $out .= $this->graph->getBasicRect( $this->toUnit($pntx), $this->toYUnit($pnty), $this->toUnit($pwidth), $this->toUnit($pheight), - $mode, - $styles, + 'f', // fill the path + $styleall, ); } - $out .= $this->graph->getStopTransform(); + if (!$drawborder) { + return $out . $stoptr; + } - return $out; + $adj = (isset($styles['all']['lineWidth']) + ? $this->toPoints((float) $styles['all']['lineWidth'] * $cell['borderpos']) + : 0); + $adjx = (isset($styles['3']['lineWidth']) + ? $this->toPoints((float) $styles['3']['lineWidth'] * $cell['borderpos']) + : $adj); + $adjy = isset($styles['0']['lineWidth']) + ? $this->toPoints((float) $styles['0']['lineWidth'] * $cell['borderpos']) + : $adj; + $adjw = $adjx + (isset($styles['1']['lineWidth']) + ? $this->toPoints((float) $styles['1']['lineWidth'] * $cell['borderpos']) + : $adj); + $adjh = $adjy + (isset($styles['2']['lineWidth']) + ? $this->toPoints((float) $styles['2']['lineWidth'] * $cell['borderpos']) + : $adj); + + // different border styles for each side + $out .= $this->graph->getRect( + $this->toUnit($pntx + $adjx), + $this->toYUnit($pnty - $adjy), + $this->toUnit($pwidth - $adjw), + $this->toUnit($pheight - $adjh), + 's', // close and stroke the path + $styles, + ); + + return $out . $stoptr; } } diff --git a/src/Text.php b/src/Text.php index 68e9235..42b7408 100644 --- a/src/Text.php +++ b/src/Text.php @@ -213,6 +213,7 @@ public function getTextCell( $cell_pwidth, $cell_pheight, $styles, + $cell, ); return $cell_out . $txt_out; @@ -403,6 +404,7 @@ public function addTextCell( $cell_pwidth, $cell_pheight, $styles, + $cell, ) . $out; }