Skip to content

Commit 5152f92

Browse files
committed
:octocat: lifting some logo space restrictions - overwrite function patterns as much as you wish, just don't blame me
1 parent 911de7a commit 5152f92

File tree

2 files changed

+24
-35
lines changed

2 files changed

+24
-35
lines changed

src/Data/QRMatrix.php

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace chillerlan\QRCode\Data;
1212

1313
use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern, ReedSolomonEncoder, Version};
14-
use function array_fill, array_map, array_reverse, count, floor, intdiv;
14+
use function array_fill, array_map, array_reverse, count, intdiv;
1515

1616
/**
1717
* Holds an array representation of the final QR Code that contains numerical values for later output modifications;
@@ -636,8 +636,8 @@ public function invert():self{
636636
* Clears a space of $width * $height in order to add a logo or text.
637637
* If no $height is given, the space will be assumed a square of $width.
638638
*
639-
* Additionally, the logo space can be positioned within the QR Code - respecting the main functional patterns -
640-
* using $startX and $startY. If either of these are null, the logo space will be centered in that direction.
639+
* Additionally, the logo space can be positioned within the QR Code using $startX and $startY.
640+
* If either of these are null, the logo space will be centered in that direction.
641641
* ECC level "H" (30%) is required.
642642
*
643643
* The coordinates of $startX and $startY do not include the quiet zone:
@@ -661,20 +661,18 @@ public function setLogoSpace(int $width, int $height = null, int $startX = null,
661661
throw new QRCodeDataException('ECC level "H" required to add logo space');
662662
}
663663

664-
if($height === null){
665-
$height = $width;
666-
}
664+
$height ??= $width;
667665

668666
// if width and height happen to be negative or 0 (default value), just return - nothing to do
669667
if($width <= 0 || $height <= 0){
670668
return $this; // @codeCoverageIgnore
671669
}
672670

673671
// $this->moduleCount includes the quiet zone (if created), we need the QR size here
674-
$length = $this->version->getDimension();
672+
$dimension = $this->version->getDimension();
675673

676-
// throw if the size is exceeds the qrcode size
677-
if($width > $length || $height > $length){
674+
// throw if the size exceeds the qrcode size
675+
if($width > $dimension || $height > $dimension){
678676
throw new QRCodeDataException('logo dimensions exceed matrix size');
679677
}
680678

@@ -688,28 +686,24 @@ public function setLogoSpace(int $width, int $height = null, int $startX = null,
688686
}
689687

690688
// throw if the logo space exceeds the maximum error correction capacity
691-
if(($width * $height) > floor($length * $length * 0.2)){
689+
if(($width * $height) > (int)($dimension * $dimension * 0.25)){
692690
throw new QRCodeDataException('logo space exceeds the maximum error correction capacity');
693691
}
694692

695-
// quiet zone size
696-
$qz = (($this->moduleCount - $length) / 2);
697-
// skip quiet zone and the first 9 rows/columns (finder-, mode-, version- and timing patterns)
698-
$start = ($qz + 9);
699-
// skip quiet zone
700-
$end = ($this->moduleCount - $qz);
693+
$quietzone = (($this->moduleCount - $dimension) / 2);
694+
$end = ($this->moduleCount - $quietzone);
701695

702696
// determine start coordinates
703-
$startX = ((($startX !== null) ? $startX : ($length - $width) / 2) + $qz);
704-
$startY = ((($startY !== null) ? $startY : ($length - $height) / 2) + $qz);
705-
$endX = ($startX + $width);
706-
$endY = ($startY + $height);
697+
$startX ??= (($dimension - $width) / 2);
698+
$startY ??= (($dimension - $height) / 2);
699+
$endX = ($quietzone + $startX + $width);
700+
$endY = ($quietzone + $startY + $height);
707701

708702
// clear the space
709-
for($y = $startY; $y < $endY; $y++){
710-
for($x = $startX; $x < $endX; $x++){
703+
for($y = ($quietzone + $startY); $y < $endY; $y++){
704+
for($x = ($quietzone + $startX); $x < $endX; $x++){
711705
// out of bounds, skip
712-
if($x < $start || $y < $start ||$x >= $end || $y >= $end){
706+
if($x < $quietzone || $y < $quietzone ||$x >= $end || $y >= $end){
713707
continue;
714708
}
715709

tests/Data/QRMatrixTest.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ protected function dm(QRMatrix $matrix):void{
9898
return;
9999
}
100100

101-
self::debugMatrix($matrix);
101+
$this::debugMatrix($matrix);
102102
}
103103

104104
/**
@@ -411,7 +411,7 @@ public function testSetLogoSpaceOmitHeight():void{
411411

412412
$matrix = (new QRCode($o))->addByteSegment('testdata')->getQRMatrix();
413413

414-
self::debugMatrix($matrix);
414+
$this::debugMatrix($matrix);
415415

416416
$this::assertFalse($matrix->checkType(9, 9, QRMatrix::M_LOGO));
417417
$this::assertTrue($matrix->checkType(10, 10, QRMatrix::M_LOGO));
@@ -433,7 +433,7 @@ public function testSetLogoSpaceOrientation():void{
433433
// also testing size adjustment to uneven numbers
434434
$matrix->setLogoSpace(20, 14);
435435

436-
self::debugMatrix($matrix);
436+
$this::debugMatrix($matrix);
437437

438438
// NW corner
439439
$this::assertFalse($matrix->checkType(17, 20, QRMatrix::M_LOGO));
@@ -456,22 +456,17 @@ public function testSetLogoSpacePosition():void{
456456

457457
$matrix = (new QRCode($o))->addByteSegment('testdata')->getQRMatrix();
458458

459-
self::debugMatrix($matrix);
460-
461-
// logo space should not overwrite quiet zone & function patterns
462459
$matrix->setLogoSpace(21, 21, -10, -10);
460+
$this::debugMatrix($matrix);
463461
$this::assertSame(QRMatrix::M_QUIETZONE, $matrix->get(9, 9));
464-
$this::assertSame(QRMatrix::M_FINDER_DARK, $matrix->get(10, 10));
465-
$this::assertSame(QRMatrix::M_FINDER_DARK, $matrix->get(16, 16));
466-
$this::assertSame(QRMatrix::M_SEPARATOR, $matrix->get(17, 17));
467-
$this::assertSame(QRMatrix::M_FORMAT_DARK, $matrix->get(18, 18));
468-
$this::assertSame(QRMatrix::M_LOGO, $matrix->get(19, 19));
462+
$this::assertSame(QRMatrix::M_LOGO, $matrix->get(10, 10));
469463
$this::assertSame(QRMatrix::M_LOGO, $matrix->get(20, 20));
470464
$this::assertNotSame(QRMatrix::M_LOGO, $matrix->get(21, 21));
471465

472-
// Ii just realized that setLogoSpace() could be called multiple times
466+
// I just realized that setLogoSpace() could be called multiple times
473467
// on the same instance, and I'm not going to do anything about it :P
474468
$matrix->setLogoSpace(21, 21, 45, 45);
469+
$this::debugMatrix($matrix);
475470
$this::assertNotSame(QRMatrix::M_LOGO, $matrix->get(54, 54));
476471
$this::assertSame(QRMatrix::M_LOGO, $matrix->get(55, 55));
477472
$this::assertSame(QRMatrix::M_QUIETZONE, $matrix->get(67, 67));

0 commit comments

Comments
 (0)