Просмотр исходного кода

:octocat: lifting some logo space restrictions - overwrite function patterns as much as you wish, just don't blame me

smiley 2 лет назад
Родитель
Сommit
5152f929f9
2 измененных файлов с 24 добавлено и 35 удалено
  1. 17 23
      src/Data/QRMatrix.php
  2. 7 12
      tests/Data/QRMatrixTest.php

+ 17 - 23
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;
 				}
 

+ 7 - 12
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));