From 5152f929f96ac0ef1162e236eb940ae7d83a2112 Mon Sep 17 00:00:00 2001 From: smiley Date: Fri, 6 Oct 2023 01:04:53 +0200 Subject: [PATCH] :octocat: lifting some logo space restrictions - overwrite function patterns as much as you wish, just don't blame me --- src/Data/QRMatrix.php | 40 ++++++++++++++++--------------------- tests/Data/QRMatrixTest.php | 19 +++++++----------- 2 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/Data/QRMatrix.php b/src/Data/QRMatrix.php index df34af5e3..a468dce9e 100755 --- a/src/Data/QRMatrix.php +++ b/src/Data/QRMatrix.php @@ -11,7 +11,7 @@ namespace chillerlan\QRCode\Data; use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern, ReedSolomonEncoder, Version}; -use function array_fill, array_map, array_reverse, count, floor, intdiv; +use function array_fill, array_map, array_reverse, count, intdiv; /** * Holds an array representation of the final QR Code that contains numerical values for later output modifications; @@ -636,8 +636,8 @@ class QRMatrix{ * Clears a space of $width * $height in order to add a logo or text. * If no $height is given, the space will be assumed a square of $width. * - * Additionally, the logo space can be positioned within the QR Code - respecting the main functional patterns - - * using $startX and $startY. If either of these are null, the logo space will be centered in that direction. + * Additionally, the logo space can be positioned within the QR Code using $startX and $startY. + * If either of these are null, the logo space will be centered in that direction. * ECC level "H" (30%) is required. * * The coordinates of $startX and $startY do not include the quiet zone: @@ -661,9 +661,7 @@ class QRMatrix{ throw new QRCodeDataException('ECC level "H" required to add logo space'); } - if($height === null){ - $height = $width; - } + $height ??= $width; // if width and height happen to be negative or 0 (default value), just return - nothing to do if($width <= 0 || $height <= 0){ @@ -671,10 +669,10 @@ class QRMatrix{ } // $this->moduleCount includes the quiet zone (if created), we need the QR size here - $length = $this->version->getDimension(); + $dimension = $this->version->getDimension(); - // throw if the size is exceeds the qrcode size - if($width > $length || $height > $length){ + // throw if the size exceeds the qrcode size + if($width > $dimension || $height > $dimension){ throw new QRCodeDataException('logo dimensions exceed matrix size'); } @@ -688,28 +686,24 @@ class QRMatrix{ } // throw if the logo space exceeds the maximum error correction capacity - if(($width * $height) > floor($length * $length * 0.2)){ + if(($width * $height) > (int)($dimension * $dimension * 0.25)){ throw new QRCodeDataException('logo space exceeds the maximum error correction capacity'); } - // quiet zone size - $qz = (($this->moduleCount - $length) / 2); - // skip quiet zone and the first 9 rows/columns (finder-, mode-, version- and timing patterns) - $start = ($qz + 9); - // skip quiet zone - $end = ($this->moduleCount - $qz); + $quietzone = (($this->moduleCount - $dimension) / 2); + $end = ($this->moduleCount - $quietzone); // determine start coordinates - $startX = ((($startX !== null) ? $startX : ($length - $width) / 2) + $qz); - $startY = ((($startY !== null) ? $startY : ($length - $height) / 2) + $qz); - $endX = ($startX + $width); - $endY = ($startY + $height); + $startX ??= (($dimension - $width) / 2); + $startY ??= (($dimension - $height) / 2); + $endX = ($quietzone + $startX + $width); + $endY = ($quietzone + $startY + $height); // clear the space - for($y = $startY; $y < $endY; $y++){ - for($x = $startX; $x < $endX; $x++){ + for($y = ($quietzone + $startY); $y < $endY; $y++){ + for($x = ($quietzone + $startX); $x < $endX; $x++){ // out of bounds, skip - if($x < $start || $y < $start ||$x >= $end || $y >= $end){ + if($x < $quietzone || $y < $quietzone ||$x >= $end || $y >= $end){ continue; } diff --git a/tests/Data/QRMatrixTest.php b/tests/Data/QRMatrixTest.php index 7e9660c6a..3bef65794 100755 --- a/tests/Data/QRMatrixTest.php +++ b/tests/Data/QRMatrixTest.php @@ -98,7 +98,7 @@ final class QRMatrixTest extends TestCase{ return; } - self::debugMatrix($matrix); + $this::debugMatrix($matrix); } /** @@ -411,7 +411,7 @@ final class QRMatrixTest extends TestCase{ $matrix = (new QRCode($o))->addByteSegment('testdata')->getQRMatrix(); - self::debugMatrix($matrix); + $this::debugMatrix($matrix); $this::assertFalse($matrix->checkType(9, 9, QRMatrix::M_LOGO)); $this::assertTrue($matrix->checkType(10, 10, QRMatrix::M_LOGO)); @@ -433,7 +433,7 @@ final class QRMatrixTest extends TestCase{ // also testing size adjustment to uneven numbers $matrix->setLogoSpace(20, 14); - self::debugMatrix($matrix); + $this::debugMatrix($matrix); // NW corner $this::assertFalse($matrix->checkType(17, 20, QRMatrix::M_LOGO)); @@ -456,22 +456,17 @@ final class QRMatrixTest extends TestCase{ $matrix = (new QRCode($o))->addByteSegment('testdata')->getQRMatrix(); - self::debugMatrix($matrix); - - // logo space should not overwrite quiet zone & function patterns $matrix->setLogoSpace(21, 21, -10, -10); + $this::debugMatrix($matrix); $this::assertSame(QRMatrix::M_QUIETZONE, $matrix->get(9, 9)); - $this::assertSame(QRMatrix::M_FINDER_DARK, $matrix->get(10, 10)); - $this::assertSame(QRMatrix::M_FINDER_DARK, $matrix->get(16, 16)); - $this::assertSame(QRMatrix::M_SEPARATOR, $matrix->get(17, 17)); - $this::assertSame(QRMatrix::M_FORMAT_DARK, $matrix->get(18, 18)); - $this::assertSame(QRMatrix::M_LOGO, $matrix->get(19, 19)); + $this::assertSame(QRMatrix::M_LOGO, $matrix->get(10, 10)); $this::assertSame(QRMatrix::M_LOGO, $matrix->get(20, 20)); $this::assertNotSame(QRMatrix::M_LOGO, $matrix->get(21, 21)); - // Ii just realized that setLogoSpace() could be called multiple times + // I just realized that setLogoSpace() could be called multiple times // on the same instance, and I'm not going to do anything about it :P $matrix->setLogoSpace(21, 21, 45, 45); + $this::debugMatrix($matrix); $this::assertNotSame(QRMatrix::M_LOGO, $matrix->get(54, 54)); $this::assertSame(QRMatrix::M_LOGO, $matrix->get(55, 55)); $this::assertSame(QRMatrix::M_QUIETZONE, $matrix->get(67, 67));