diff --git a/src/Data/QRMatrix.php b/src/Data/QRMatrix.php index 5522cff6d..479204443 100755 --- a/src/Data/QRMatrix.php +++ b/src/Data/QRMatrix.php @@ -45,8 +45,8 @@ final class QRMatrix{ public const M_VERSION = 0x10; /** @var int */ public const M_QUIETZONE = 0x12; - -# public const M_LOGO = 0x14; // @todo + /** @var int */ + public const M_LOGO = 0x14; /** @var int */ public const M_TEST = 0xff; @@ -562,6 +562,60 @@ final class QRMatrix{ return $this; } + /** + * Clears a space of $width * $height in order to add a logo or text. ECC level "H" (30%) is required. + * This method should be called from within an output module (after the matrix has been filled with data). + * + * @throws \chillerlan\QRCode\Data\QRCodeDataException + */ + public function setLogoSpace(int $width, int $height):QRMatrix{ + + // for logos we operate in ECC H (30%) only + if($this->eclevel !== 0b10){ + throw new QRCodeDataException('ECC level "H" required to add logo space'); + } + + // we need uneven sizes, adjust if needed + if(($width % 2) === 0){ + $width++; + } + + if(($height % 2) === 0){ + $height++; + } + + $dataModules = 0; + + // count the data modules + foreach($this->matrix as $y => $row){ + foreach($row as $x => $val){ + if($val === $this::M_DATA || $val >> 8 === $this::M_DATA){ + $dataModules++; + } + } + } + + // throw if the logo space exceeds the maximum error correction capacity + // @todo: this might need some adjustment + if($width * $height > floor($dataModules * 0.3)){ + throw new QRCodeDataException('logo space exceeds the maximum error correction capacity'); + } + + // clear the space + $startX = ($this->moduleCount - $width) / 2; + $startY = ($this->moduleCount - $height) / 2; + + foreach($this->matrix as $y => $row){ + foreach($row as $x => $val){ + if($x >= $startX && $x < $startX + $width && $y >= $startY && $y < $startY + $height){ + $this->set($x, $y, false, $this::M_LOGO); + } + } + } + + return $this; + } + /** * Maps the binary $data array from QRDataInterface::maskECC() on the matrix, * masking the data using $maskPattern (ISO/IEC 18004:2000 Section 8.8) diff --git a/src/Output/QROutputInterface.php b/src/Output/QROutputInterface.php index 9dd95ec28..72405b816 100644 --- a/src/Output/QROutputInterface.php +++ b/src/Output/QROutputInterface.php @@ -30,6 +30,7 @@ interface QROutputInterface{ QRMatrix::M_FORMAT => false, // 14 QRMatrix::M_VERSION => false, // 16 QRMatrix::M_QUIETZONE => false, // 18 + QRMatrix::M_LOGO => false, // 20 QRMatrix::M_TEST => false, // 255 // dark QRMatrix::M_DARKMODULE << 8 => true, // 512