diff --git a/src/Data/QRMatrix.php b/src/Data/QRMatrix.php index 1970d14fe..33c5d7094 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, count, floor; +use function array_fill, array_map, array_reverse, count, floor; /** * Holds an array representation of the final QR Code that contains numerical values for later output modifications; @@ -569,6 +569,16 @@ class QRMatrix{ return $this; } + /** + * Rotates the matrix by 90 degrees clock wise + */ + public function rotate90():self{ + /** @phan-suppress-next-line PhanParamTooFewInternalUnpack */ + $this->matrix = array_map((fn(int ...$a):array => array_reverse($a)), ...$this->matrix); + + return $this; + } + /** * 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. diff --git a/src/Decoder/BitMatrix.php b/src/Decoder/BitMatrix.php index 9e5d58fe4..ea2e321b5 100644 --- a/src/Decoder/BitMatrix.php +++ b/src/Decoder/BitMatrix.php @@ -13,7 +13,7 @@ namespace chillerlan\QRCode\Decoder; use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Version}; use chillerlan\QRCode\Data\{QRCodeDataException, QRMatrix}; -use function array_fill, array_map, array_reverse, count; +use function array_fill, array_reverse, count; use const PHP_INT_MAX, PHP_INT_SIZE; /** @@ -95,12 +95,10 @@ final class BitMatrix extends QRMatrix{ $this->mirror = !$this->mirror; // mirror vertically - $matrix = array_reverse($this->matrix); + $this->matrix = array_reverse($this->matrix); // rotate by 90 degrees clockwise - /** @phan-suppress-next-line PhanParamTooFewInternalUnpack */ - $this->matrix = array_map(fn(...$a):array => array_reverse($a), ...$matrix); - - return $this; + /** @phan-suppress-next-line PhanTypeMismatchReturnSuperType */ + return $this->rotate90(); } /** diff --git a/tests/Data/QRMatrixTest.php b/tests/Data/QRMatrixTest.php index 37385dc3d..1b0d87ec6 100755 --- a/tests/Data/QRMatrixTest.php +++ b/tests/Data/QRMatrixTest.php @@ -367,6 +367,43 @@ final class QRMatrixTest extends TestCase{ $this->matrix->setQuietZone(42); } + /** + * Tests rotating the matrix by 90 degrees CW + * + * @dataProvider matrixProvider + */ + public function testRotate90(QRMatrix $matrix):void{ + $matrix->initFunctionalPatterns(); + + // matrix size + $size = $matrix->getSize(); + // quiet zone size + $qz = (($size - $matrix->getVersion()->getDimension()) / 2); + + // initial dark module position + $this::assertSame(QRMatrix::M_DARKMODULE, $matrix->get((8 + $qz), ($size - 8 - $qz))); + + // first rotation + $matrix->rotate90(); + $this->dm($matrix); + $this::assertSame(QRMatrix::M_DARKMODULE, $matrix->get((7 + $qz), (8 + $qz))); + + // second rotation + $matrix->rotate90(); + $this->dm($matrix); + $this::assertSame(QRMatrix::M_DARKMODULE, $matrix->get(($size - 9 - $qz), (7 + $qz))); + + // third rotation + $matrix->rotate90(); + $this->dm($matrix); + $this::assertSame(QRMatrix::M_DARKMODULE, $matrix->get(($size - 8 - $qz), ($size - 9 - $qz))); + + // fourth rotation + $matrix->rotate90(); + $this->dm($matrix); + $this::assertSame(QRMatrix::M_DARKMODULE, $matrix->get((8 + $qz), ($size - 8 - $qz))); + } + /** * Tests if the logo space is drawn square if one of the dimensions is omitted */