From bcd410a33b64ef388085e4b752e3da4fe6beb0ea Mon Sep 17 00:00:00 2001 From: smiley Date: Sun, 3 Sep 2023 19:46:14 +0200 Subject: [PATCH] :octocat: cleanup, align module() method between the several output classes where applicable --- src/Output/QREps.php | 10 +++--- src/Output/QRFpdf.php | 70 ++++++++++++++++++++++++------------- src/Output/QRGdImage.php | 36 ++++++++++--------- src/Output/QRImagick.php | 35 ++++++++++--------- src/Output/QRMarkupHTML.php | 32 ++++++++--------- 5 files changed, 105 insertions(+), 78 deletions(-) diff --git a/src/Output/QREps.php b/src/Output/QREps.php index 208825b77..8fad50f33 100644 --- a/src/Output/QREps.php +++ b/src/Output/QREps.php @@ -76,7 +76,7 @@ class QREps extends QROutputAbstract{ } /** - * Set the color format + * Set the color format string * * 4 values in the color array will be interpreted as CMYK, 3 as RGB * @@ -121,13 +121,13 @@ class QREps extends QROutputAbstract{ '%%EndProlog', ]; - if($this->options->bgColor !== null && self::moduleValueIsValid($this->options->bgColor)){ + if($this::moduleValueIsValid($this->options->bgColor)){ $eps[] = $this->prepareModuleValue($this->options->bgColor); $eps[] = sprintf('0 0 %1$s %1$s F', $this->length); } // create the path elements - $paths = $this->collectModules(fn(int $x, int $y):string => $this->module($x, $y)); + $paths = $this->collectModules(fn(int $x, int $y, int $M_TYPE):string => $this->module($x, $y, $M_TYPE)); foreach($paths as $M_TYPE => $path){ @@ -150,9 +150,9 @@ class QREps extends QROutputAbstract{ } /** - * returns a path segment for a single module + * Returns a path segment for a single module */ - protected function module(int $x, int $y):string{ + protected function module(int $x, int $y, int $M_TYPE):string{ if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){ return ''; diff --git a/src/Output/QRFpdf.php b/src/Output/QRFpdf.php index 9f2dede03..5eb769fda 100644 --- a/src/Output/QRFpdf.php +++ b/src/Output/QRFpdf.php @@ -25,6 +25,9 @@ use function array_values, class_exists, count, intval, is_array, is_numeric, ma */ class QRFpdf extends QROutputAbstract{ + protected FPDF $fpdf; + protected ?array $prevColor = null; + /** * QRFpdf constructor. * @@ -73,6 +76,7 @@ class QRFpdf extends QROutputAbstract{ * @param array $value * * @inheritDoc + * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ protected function prepareModuleValue($value):array{ $values = []; @@ -86,6 +90,10 @@ class QRFpdf extends QROutputAbstract{ $values[] = max(0, min(255, intval($val))); } + if(count($values) !== 3){ + throw new QRCodeOutputException('invalid color value'); + } + return $values; } @@ -96,50 +104,42 @@ class QRFpdf extends QROutputAbstract{ return ($isDark) ? [0, 0, 0] : [255, 255, 255]; } + /** + * Initializes an FPDF instance + */ + protected function initFPDF():FPDF{ + return new FPDF('P', $this->options->fpdfMeasureUnit, [$this->length, $this->length]); + } + /** * @inheritDoc * * @return string|\FPDF */ public function dump(string $file = null){ - - $fpdf = new FPDF('P', $this->options->fpdfMeasureUnit, [$this->length, $this->length]); - $fpdf->AddPage(); + $this->fpdf = $this->initFPDF(); + $this->fpdf->AddPage(); if($this::moduleValueIsValid($this->options->bgColor)){ $bgColor = $this->prepareModuleValue($this->options->bgColor); /** @phan-suppress-next-line PhanParamTooFewUnpack */ - $fpdf->SetFillColor(...$bgColor); - $fpdf->Rect(0, 0, $this->length, $this->length, 'F'); + $this->fpdf->SetFillColor(...$bgColor); + $this->fpdf->Rect(0, 0, $this->length, $this->length, 'F'); } - $prevColor = null; + $this->prevColor = null; - for($y = 0; $y < $this->moduleCount; $y++){ - for($x = 0; $x < $this->moduleCount; $x++){ - - if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){ - continue; - } - - $color = $this->getModuleValueAt($x, $y); - - if($color !== null && $color !== $prevColor){ - /** @phan-suppress-next-line PhanParamTooFewUnpack */ - $fpdf->SetFillColor(...$color); - $prevColor = $color; - } - - $fpdf->Rect(($x * $this->scale), ($y * $this->scale), $this->scale, $this->scale, 'F'); + foreach($this->matrix->getMatrix() as $y => $row){ + foreach($row as $x => $M_TYPE){ + $this->module($x, $y, $M_TYPE); } - } if($this->options->returnResource){ - return $fpdf; + return $this->fpdf; } - $pdfData = $fpdf->Output('S'); + $pdfData = $this->fpdf->Output('S'); $this->saveToFile($pdfData, $file); @@ -150,4 +150,24 @@ class QRFpdf extends QROutputAbstract{ return $pdfData; } + /** + * Renders a single module + */ + protected function module(int $x, int $y, int $M_TYPE):void{ + + if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){ + return; + } + + $color = $this->getModuleValue($M_TYPE); + + if($color !== null && $color !== $this->prevColor){ + /** @phan-suppress-next-line PhanParamTooFewUnpack */ + $this->fpdf->SetFillColor(...$color); + $this->prevColor = $color; + } + + $this->fpdf->Rect(($x * $this->scale), ($y * $this->scale), $this->scale, $this->scale, 'F'); + } + } diff --git a/src/Output/QRGdImage.php b/src/Output/QRGdImage.php index 20b7fa7e9..ea8d472c6 100644 --- a/src/Output/QRGdImage.php +++ b/src/Output/QRGdImage.php @@ -22,7 +22,7 @@ use function array_values, count, extension_loaded, imagecolorallocate, imagecol /** * Converts the matrix into GD images, raw or base64 output (requires ext-gd) * - * @see http://php.net/manual/book.image.php + * @see https://php.net/manual/book.image.php */ class QRGdImage extends QROutputAbstract{ @@ -228,9 +228,9 @@ class QRGdImage extends QROutputAbstract{ * Creates the QR image */ protected function drawImage():void{ - for($y = 0; $y < $this->moduleCount; $y++){ - for($x = 0; $x < $this->moduleCount; $x++){ - $this->setPixel($x, $y); + foreach($this->matrix->getMatrix() as $y => $row){ + foreach($row as $x => $M_TYPE){ + $this->module($x, $y, $M_TYPE); } } } @@ -238,31 +238,35 @@ class QRGdImage extends QROutputAbstract{ /** * Creates a single QR pixel with the given settings */ - protected function setPixel(int $x, int $y):void{ + protected function module(int $x, int $y, int $M_TYPE):void{ if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){ return; } - $color = $this->getModuleValueAt($x, $y); + $color = $this->getModuleValue($M_TYPE); - $this->options->drawCircularModules && !$this->matrix->checkTypeIn($x, $y, $this->options->keepAsSquare) - ? imagefilledellipse( + if($this->options->drawCircularModules && !$this->matrix->checkTypeIn($x, $y, $this->options->keepAsSquare)){ + imagefilledellipse( $this->image, (($x * $this->scale) + intdiv($this->scale, 2)), (($y * $this->scale) + intdiv($this->scale, 2)), (int)(2 * $this->options->circleRadius * $this->scale), (int)(2 * $this->options->circleRadius * $this->scale), $color - ) - : imagefilledrectangle( - $this->image, - ($x * $this->scale), - ($y * $this->scale), - (($x + 1) * $this->scale), - (($y + 1) * $this->scale), - $color ); + + return; + } + + imagefilledrectangle( + $this->image, + ($x * $this->scale), + ($y * $this->scale), + (($x + 1) * $this->scale), + (($y + 1) * $this->scale), + $color + ); } /** diff --git a/src/Output/QRImagick.php b/src/Output/QRImagick.php index f1e94c9e4..8e19d449d 100644 --- a/src/Output/QRImagick.php +++ b/src/Output/QRImagick.php @@ -21,8 +21,8 @@ use const FILEINFO_MIME_TYPE; /** * ImageMagick output module (requires ext-imagick) * - * @see http://php.net/manual/book.imagick.php - * @see http://phpimagick.com + * @see https://php.net/manual/book.imagick.php + * @see https://phpimagick.com */ class QRImagick extends QROutputAbstract{ @@ -97,7 +97,6 @@ class QRImagick extends QROutputAbstract{ /** * @inheritDoc - * @throws \ImagickPixelException */ protected function prepareModuleValue($value):ImagickPixel{ return new ImagickPixel($value); @@ -186,9 +185,9 @@ class QRImagick extends QROutputAbstract{ $this->imagickDraw = new ImagickDraw; $this->imagickDraw->setStrokeWidth(0); - for($y = 0; $y < $this->moduleCount; $y++){ - for($x = 0; $x < $this->moduleCount; $x++){ - $this->setPixel($x, $y); + foreach($this->matrix->getMatrix() as $y => $row){ + foreach($row as $x => $M_TYPE){ + $this->module($x, $y, $M_TYPE); } } @@ -198,27 +197,31 @@ class QRImagick extends QROutputAbstract{ /** * draws a single pixel at the given position */ - protected function setPixel(int $x, int $y):void{ + protected function module(int $x, int $y, int $M_TYPE):void{ if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){ return; } - $this->imagickDraw->setFillColor($this->getModuleValueAt($x, $y)); + $this->imagickDraw->setFillColor($this->getModuleValue($M_TYPE)); - $this->options->drawCircularModules && !$this->matrix->checkTypeIn($x, $y, $this->options->keepAsSquare) - ? $this->imagickDraw->circle( + if($this->options->drawCircularModules && !$this->matrix->checkTypeIn($x, $y, $this->options->keepAsSquare)){ + $this->imagickDraw->circle( (($x + 0.5) * $this->scale), (($y + 0.5) * $this->scale), (($x + 0.5 + $this->options->circleRadius) * $this->scale), (($y + 0.5) * $this->scale) - ) - : $this->imagickDraw->rectangle( - ($x * $this->scale), - ($y * $this->scale), - (($x + 1) * $this->scale), - (($y + 1) * $this->scale) ); + + return; + } + + $this->imagickDraw->rectangle( + ($x * $this->scale), + ($y * $this->scale), + (($x + 1) * $this->scale), + (($y + 1) * $this->scale) + ); } } diff --git a/src/Output/QRMarkupHTML.php b/src/Output/QRMarkupHTML.php index c7776ab9b..cf6f8b3bb 100644 --- a/src/Output/QRMarkupHTML.php +++ b/src/Output/QRMarkupHTML.php @@ -10,7 +10,7 @@ namespace chillerlan\QRCode\Output; -use function sprintf; +use function implode, sprintf; /** * HTML output (a cheap markup substitute when SVG is not available or not an option) @@ -21,29 +21,29 @@ class QRMarkupHTML extends QRMarkup{ * @inheritDoc */ protected function createMarkup(bool $saveToFile):string{ - $html = empty($this->options->cssClass) - ? '
' - : sprintf('
', $this->getCssClass()); + $rows = []; - $html .= $this->options->eol; + foreach($this->matrix->getMatrix() as $row){ + $element = ''; + $modules = array_map(fn(int $M_TYPE):string => sprintf($element, $this->getModuleValue($M_TYPE)), $row); - for($y = 0; $y < $this->moduleCount; $y++){ - $html .= '
'; - - for($x = 0; $x < $this->moduleCount; $x++){ - $html .= sprintf('', $this->getModuleValueAt($x, $y)); - } - - $html .= '
'.$this->options->eol; + $rows[] = sprintf('
%s
%s', implode('', $modules), $this->options->eol); } - $html .= '
'.$this->options->eol; + $html = sprintf( + '
%3$s%2$s
%3$s', + $this->getCssClass(), + implode('', $rows), + $this->options->eol + ); // wrap the snippet into a body when saving to file if($saveToFile){ $html = sprintf( - 'QR Code%s', - $this->options->eol.$html + '%2$s%2$s%2$s'. + 'QR Code%2$s%1$s%2$s', + $html, + $this->options->eol ); }