diff --git a/src/Data/QRMatrix.php b/src/Data/QRMatrix.php index b77cad87c..0f291b031 100755 --- a/src/Data/QRMatrix.php +++ b/src/Data/QRMatrix.php @@ -508,6 +508,7 @@ 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. @@ -524,13 +525,17 @@ class QRMatrix{ * * @throws \chillerlan\QRCode\Data\QRCodeDataException */ - public function setLogoSpace(int $width, int $height, int $startX = null, int $startY = null):self{ + public function setLogoSpace(int $width, int $height = null, int $startX = null, int $startY = null):self{ // for logos we operate in ECC H (30%) only if($this->eccLevel->getLevel() !== EccLevel::H){ throw new QRCodeDataException('ECC level "H" required to add logo space'); } + if($height === null){ + $height = $width; + } + // if width and height happen to be negative or 0 (default value), just return - nothing to do if($width <= 0 || $height <= 0){ return $this; // @codeCoverageIgnore diff --git a/src/Decoder/BitMatrix.php b/src/Decoder/BitMatrix.php index a19791191..fda1b4721 100644 --- a/src/Decoder/BitMatrix.php +++ b/src/Decoder/BitMatrix.php @@ -429,7 +429,7 @@ final class BitMatrix extends QRMatrix{ * @codeCoverageIgnore * @throws \chillerlan\QRCode\Data\QRCodeDataException */ - public function setLogoSpace(int $width, int $height, int $startX = null, int $startY = null):self{ + public function setLogoSpace(int $width, int $height = null, int $startX = null, int $startY = null):self{ throw new QRCodeDataException('not supported'); } diff --git a/src/QRCode.php b/src/QRCode.php index 2fca74a12..096a36336 100755 --- a/src/QRCode.php +++ b/src/QRCode.php @@ -231,9 +231,18 @@ class QRCode{ // add matrix modifications after mask pattern evaluation and before handing over to output if($this->options->addLogoSpace){ + $logoSpaceWidth = $this->options->logoSpaceWidth; + $logoSpaceHeight = $this->options->logoSpaceHeight; + + // check whether one of the dimensions was omitted + if($logoSpaceWidth === null || $logoSpaceHeight === null){ + $logoSpaceWidth = $logoSpaceWidth ?? $logoSpaceHeight ?? 0; + $logoSpaceHeight = null; + } + $matrix->setLogoSpace( - $this->options->logoSpaceWidth, - $this->options->logoSpaceHeight, + $logoSpaceWidth, + $logoSpaceHeight, $this->options->logoSpaceStartX, $this->options->logoSpaceStartY ); diff --git a/src/QROptionsTrait.php b/src/QROptionsTrait.php index 39d7a9318..cf6bd6dd0 100644 --- a/src/QROptionsTrait.php +++ b/src/QROptionsTrait.php @@ -333,13 +333,17 @@ trait QROptionsTrait{ /** * width of the logo space + * + * if only either $logoSpaceWidth or $logoSpaceHeight is given, the logo space is assumed a square of that size */ - protected int $logoSpaceWidth = 0; + protected ?int $logoSpaceWidth = null; /** * height of the logo space + * + * if only either $logoSpaceWidth or $logoSpaceHeight is given, the logo space is assumed a square of that size */ - protected int $logoSpaceHeight = 0; + protected ?int $logoSpaceHeight = null; /** * optional horizontal start position of the logo space (top left corner) @@ -476,21 +480,26 @@ trait QROptionsTrait{ /** * clamp the logo space values between 0 and maximum length (177 modules at version 40) */ - protected function clampLogoSpaceValue(int $value):int{ + protected function clampLogoSpaceValue(?int $value):?int{ + + if($value === null){ + return null; + } + return (int)max(0, min(177, $value)); } /** * clamp/set logo space width */ - protected function set_logoSpaceWidth(int $value):void{ + protected function set_logoSpaceWidth(?int $value):void{ $this->logoSpaceWidth = $this->clampLogoSpaceValue($value); } /** * clamp/set logo space height */ - protected function set_logoSpaceHeight(int $value):void{ + protected function set_logoSpaceHeight(?int $value):void{ $this->logoSpaceHeight = $this->clampLogoSpaceValue($value); } @@ -498,14 +507,14 @@ trait QROptionsTrait{ * clamp/set horizontal logo space start */ protected function set_logoSpaceStartX(?int $value):void{ - $this->logoSpaceStartX = $value === null ? null : $this->clampLogoSpaceValue($value); + $this->logoSpaceStartX = $this->clampLogoSpaceValue($value); } /** * clamp/set vertical logo space start */ protected function set_logoSpaceStartY(?int $value):void{ - $this->logoSpaceStartY = $value === null ? null : $this->clampLogoSpaceValue($value); + $this->logoSpaceStartY = $this->clampLogoSpaceValue($value); } /** diff --git a/tests/Data/QRMatrixTest.php b/tests/Data/QRMatrixTest.php index 5629b2e3f..2b63bc6a6 100755 --- a/tests/Data/QRMatrixTest.php +++ b/tests/Data/QRMatrixTest.php @@ -352,6 +352,28 @@ final class QRMatrixTest extends TestCase{ $this->matrix->setQuietZone(42); } + /** + * Tests if the logo space is drawn square if one of the dimensions is omitted + */ + public function testSetLogoSpaceOmitHeight():void{ + $o = new QROptions; + $o->version = 2; + $o->eccLevel = EccLevel::H; + $o->addQuietzone = false; + $o->addLogoSpace = true; + $o->logoSpaceHeight = 5; + + $matrix = (new QRCode($o))->addByteSegment('testdata')->getMatrix(); + + self::debugMatrix($matrix); + + $this::assertFalse($matrix->checkType(9, 9, QRMatrix::M_LOGO)); + $this::assertTrue($matrix->checkType(10, 10, QRMatrix::M_LOGO)); + + $this::assertTrue($matrix->checkType(14, 14, QRMatrix::M_LOGO)); + $this::assertFalse($matrix->checkType(15, 15, QRMatrix::M_LOGO)); + } + /** * Tests the auto orientation of the logo space */