Sfoglia il codice sorgente

:octocat: allow positioning the logo space (#52)

codemasher 5 anni fa
parent
commit
16985c0ec1
1 ha cambiato i file con 25 aggiunte e 5 eliminazioni
  1. 25 5
      src/Data/QRMatrix.php

+ 25 - 5
src/Data/QRMatrix.php

@@ -571,7 +571,16 @@ final class QRMatrix{
 	}
 
 	/**
-	 * Clears a space of $width * $height in order to add a logo or text. ECC level "H" (30%) is required.
+	 * Clears a space of $width * $height in order to add a logo or text.
+	 *
+	 * 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.
+	 * ECC level "H" (30%) is required.
+	 *
+	 * Please note that adding a logo space minimizes the error correction capacity of the QR Code and
+	 * created images may become unreadable, especially when printed with a chance to receive damage.
+	 * Please test thoroughly before using this feature in production.
+	 *
 	 * This method should be called from within an output module (after the matrix has been filled with data).
 	 *
 	 * @link https://github.com/chillerlan/php-qrcode/issues/52
@@ -580,7 +589,7 @@ final class QRMatrix{
 	 *
 	 * @throws \chillerlan\QRCode\Data\QRCodeDataException
 	 */
-	public function setLogoSpace(int $width, int $height):QRMatrix{
+	public function setLogoSpace(int $width, int $height, int $startX = null, int $startY = null):QRMatrix{
 
 		// for logos we operate in ECC H (30%) only
 		if($this->eclevel !== 0b10){
@@ -604,12 +613,23 @@ final class QRMatrix{
 			throw new QRCodeDataException('logo space exceeds the maximum error correction capacity');
 		}
 
-		// clear the space
-		$startX = ($this->moduleCount - $width) / 2;
-		$startY = ($this->moduleCount - $height) / 2;
+		// quiet zone size
+		$qz     = ($this->moduleCount - $length) / 2;
+		$start  = $qz + 9;
+		$end    = $this->moduleCount - $qz;
+
+		// determine start coordinates, try not to interfere with functional patterns
+		$startX = ($startX !== null ? $startX : ($length - $width) / 2) + $qz;
+		$startY = ($startY !== null ? $startY : ($length - $height) / 2) + $qz;
 
+		// clear the space
 		foreach($this->matrix as $y => $row){
 			foreach($row as $x => $val){
+
+				if($x < $start || $y < $start ||$x >= $end || $y >= $end){
+					continue;
+				}
+
 				if($x >= $startX && $x < $startX + $width && $y >= $startY && $y < $startY + $height){
 					$this->set($x, $y, false, $this::M_LOGO);
 				}