Explorar o código

:octocat: QRMatrix::M_*TYPE rework, separate masking

codemasher %!s(int64=5) %!d(string=hai) anos
pai
achega
307b6462f6

+ 16 - 15
examples/fpdf.php

@@ -3,6 +3,7 @@
 namespace chillerlan\QRCodeExamples;
 
 use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Common\EccLevel;
 
 require_once __DIR__ . '/../vendor/autoload.php';
@@ -17,29 +18,29 @@ $options = new QROptions([
     'imageBase64'  => false,
     'moduleValues' => [
         // finder
-        1536 => [0, 63, 255], // dark (true)
-        6    => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
+        QRMatrix::M_FINDER | QRMatrix::IS_DARK     => [0, 63, 255], // dark (true)
+        QRMatrix::M_FINDER                         => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
         // alignment
-        2560 => [255, 0, 255],
-        10   => [255, 255, 255],
+        QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK  => [255, 0, 255],
+        QRMatrix::M_ALIGNMENT                      => [255, 255, 255],
         // timing
-        3072 => [255, 0, 0],
-        12   => [255, 255, 255],
+        QRMatrix::M_TIMING | QRMatrix::IS_DARK     => [255, 0, 0],
+        QRMatrix::M_TIMING                         => [255, 255, 255],
         // format
-        3584 => [67, 191, 84],
-        14   => [255, 255, 255],
+        QRMatrix::M_FORMAT | QRMatrix::IS_DARK     => [67, 191, 84],
+        QRMatrix::M_FORMAT                         => [255, 255, 255],
         // version
-        4096 => [62, 174, 190],
-        16   => [255, 255, 255],
+        QRMatrix::M_VERSION | QRMatrix::IS_DARK    => [62, 174, 190],
+        QRMatrix::M_VERSION                        => [255, 255, 255],
         // data
-        1024 => [0, 0, 0],
-        4    => [255, 255, 255],
+        QRMatrix::M_DATA | QRMatrix::IS_DARK       => [0, 0, 0],
+        QRMatrix::M_DATA                           => [255, 255, 255],
         // darkmodule
-        512  => [0, 0, 0],
+        QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK => [0, 0, 0],
         // separator
-        8    => [255, 255, 255],
+        QRMatrix::M_SEPARATOR                      => [255, 255, 255],
         // quietzone
-        18   => [255, 255, 255],
+        QRMatrix::M_QUIETZONE                      => [255, 255, 255],
     ],
 ]);
 

+ 19 - 30
examples/html.php

@@ -11,6 +11,7 @@
 namespace chillerlan\QRCodeExamples;
 
 use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Common\EccLevel;
 
 require_once '../vendor/autoload.php';
@@ -25,20 +26,12 @@ header('Content-Type: text/html; charset=utf-8');
 	<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 	<title>QRCode test</title>
 	<style>
-		body{
-			margin: 5em;
-			padding: 0;
-		}
-
 		div.qrcode{
-			margin: 0;
-			padding: 0;
+            margin: 5em;
 		}
 
 		/* rows */
 		div.qrcode > div {
-			margin: 0;
-			padding: 0;
 			height: 10px;
 		}
 
@@ -48,14 +41,9 @@ header('Content-Type: text/html; charset=utf-8');
 			width: 10px;
 			height: 10px;
 		}
-
-		div.qrcode > div > span {
-			background-color: #ccc;
-		}
 	</style>
 </head>
 <body>
-	<div class="qrcode">
 <?php
 
 	$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
@@ -64,38 +52,39 @@ header('Content-Type: text/html; charset=utf-8');
 		'version'      => 5,
 		'outputType'   => QRCode::OUTPUT_MARKUP_HTML,
 		'eccLevel'     => EccLevel::L,
+		'cssClass'     => 'qrcode',
 		'moduleValues' => [
 			// finder
-			1536 => '#A71111', // dark (true)
-			6    => '#FFBFBF', // light (false)
+			QRMatrix::M_FINDER | QRMatrix::IS_DARK     => '#A71111', // dark (true)
+			QRMatrix::M_FINDER                         => '#FFBFBF', // light (false)
+			QRMatrix::M_FINDER_DOT | QRMatrix::IS_DARK => '#A71111', // finder dot, dark (true)
 			// alignment
-			2560 => '#A70364',
-			10   => '#FFC9C9',
+			QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK  => '#A70364',
+			QRMatrix::M_ALIGNMENT                      => '#FFC9C9',
 			// timing
-			3072 => '#98005D',
-			12   => '#FFB8E9',
+			QRMatrix::M_TIMING | QRMatrix::IS_DARK     => '#98005D',
+			QRMatrix::M_TIMING                         => '#FFB8E9',
 			// format
-			3584 => '#003804',
-			14   => '#00FB12',
+			QRMatrix::M_FORMAT | QRMatrix::IS_DARK     => '#003804',
+			QRMatrix::M_FORMAT                         => '#00FB12',
 			// version
-			4096 => '#650098',
-			16   => '#E0B8FF',
+			QRMatrix::M_VERSION | QRMatrix::IS_DARK    => '#650098',
+			QRMatrix::M_VERSION                        => '#E0B8FF',
 			// data
-			1024 => '#4A6000',
-			4    => '#ECF9BE',
+			QRMatrix::M_DATA | QRMatrix::IS_DARK       => '#4A6000',
+			QRMatrix::M_DATA                           => '#ECF9BE',
 			// darkmodule
-			512  => '#080063',
+			QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK => '#080063',
 			// separator
-			8    => '#AFBFBF',
+			QRMatrix::M_SEPARATOR                      => '#AFBFBF',
 			// quietzone
-			18   => '#FFFFFF',
+			QRMatrix::M_QUIETZONE                      => '#DDDDDD',
 		],
 	]);
 
 	echo (new QRCode($options))->render($data);
 
 ?>
-	</div>
 </body>
 </html>
 

+ 20 - 19
examples/image.php

@@ -11,6 +11,7 @@
 namespace chillerlan\QRCodeExamples;
 
 use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Common\EccLevel;
 
 require_once __DIR__.'/../vendor/autoload.php';
@@ -18,39 +19,39 @@ require_once __DIR__.'/../vendor/autoload.php';
 $data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
 
 $options = new QROptions([
-	'version'      => 10,
+	'version'      => 5,
 	'outputType'   => QRCode::OUTPUT_IMAGE_PNG,
 	'eccLevel'     => EccLevel::L,
 	'scale'        => 5,
 	'imageBase64'  => false,
 	'moduleValues' => [
 		// finder
-		1536 => [0, 63, 255], // dark (true)
-		6    => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
-		5632 => [241, 28, 163], // finder dot, dark (true)
+		QRMatrix::M_FINDER | QRMatrix::IS_DARK     => [0, 63, 255], // dark (true)
+		QRMatrix::M_FINDER                         => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
+		QRMatrix::M_FINDER_DOT | QRMatrix::IS_DARK => [241, 28, 163], // finder dot, dark (true)
 		// alignment
-		2560 => [255, 0, 255],
-		10   => [255, 255, 255],
+		QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK  => [255, 0, 255],
+		QRMatrix::M_ALIGNMENT                      => [255, 255, 255],
 		// timing
-		3072 => [255, 0, 0],
-		12   => [255, 255, 255],
+		QRMatrix::M_TIMING | QRMatrix::IS_DARK     => [255, 0, 0],
+		QRMatrix::M_TIMING                         => [255, 255, 255],
 		// format
-		3584 => [67, 99, 84],
-		14   => [255, 255, 255],
+		QRMatrix::M_FORMAT | QRMatrix::IS_DARK     => [67, 99, 84],
+		QRMatrix::M_FORMAT                         => [255, 255, 255],
 		// version
-		4096 => [62, 174, 190],
-		16   => [255, 255, 255],
+		QRMatrix::M_VERSION | QRMatrix::IS_DARK    => [62, 174, 190],
+		QRMatrix::M_VERSION                        => [255, 255, 255],
 		// data
-		1024 => [0, 0, 0],
-		4    => [255, 255, 255],
+		QRMatrix::M_DATA | QRMatrix::IS_DARK       => [0, 0, 0],
+		QRMatrix::M_DATA                           => [255, 255, 255],
 		// darkmodule
-		512  => [0, 0, 0],
+		QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK => [0, 0, 0],
 		// separator
-		8    => [255, 255, 255],
+		QRMatrix::M_SEPARATOR                      => [255, 255, 255],
 		// quietzone
-		18   => [255, 255, 255],
-		// logo (requires a call to QRMatrix::setLogoSpace())
-		20    => [255, 255, 255],
+		QRMatrix::M_QUIETZONE                      => [255, 255, 255],
+		// logo (requires a call to QRMatrix::setLogoSpace()), see QRImageWithLogo
+		QRMatrix::M_LOGO                           => [255, 255, 255],
 	],
 ]);
 

+ 18 - 16
examples/imagick.php

@@ -1,7 +1,7 @@
 <?php
 /**
  *
- * @filesource   image.php
+ * @filesource   imagick.php
  * @created      24.12.2017
  * @author       Smiley <smiley@chillerlan.net>
  * @copyright    2017 Smiley
@@ -11,6 +11,7 @@
 namespace chillerlan\QRCodeExamples;
 
 use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Common\EccLevel;
 
 require_once __DIR__.'/../vendor/autoload.php';
@@ -24,29 +25,30 @@ $options = new QROptions([
 	'scale'        => 5,
 	'moduleValues' => [
 		// finder
-		1536 => '#A71111', // dark (true)
-		6    => '#FFBFBF', // light (false)
+		QRMatrix::M_FINDER | QRMatrix::IS_DARK     => '#A71111', // dark (true)
+		QRMatrix::M_FINDER                         => '#FFBFBF', // light (false)
+		QRMatrix::M_FINDER_DOT | QRMatrix::IS_DARK => '#A71111', // finder dot, dark (true)
 		// alignment
-		2560 => '#A70364',
-		10   => '#FFC9C9',
+		QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK  => '#A70364',
+		QRMatrix::M_ALIGNMENT                      => '#FFC9C9',
 		// timing
-		3072 => '#98005D',
-		12   => '#FFB8E9',
+		QRMatrix::M_TIMING | QRMatrix::IS_DARK     => '#98005D',
+		QRMatrix::M_TIMING                         => '#FFB8E9',
 		// format
-		3584 => '#003804',
-		14   => '#00FB12',
+		QRMatrix::M_FORMAT | QRMatrix::IS_DARK     => '#003804',
+		QRMatrix::M_FORMAT                         => '#00FB12',
 		// version
-		4096 => '#650098',
-		16   => '#E0B8FF',
+		QRMatrix::M_VERSION | QRMatrix::IS_DARK    => '#650098',
+		QRMatrix::M_VERSION                        => '#E0B8FF',
 		// data
-		1024 => '#4A6000',
-		4    => '#ECF9BE',
+		QRMatrix::M_DATA | QRMatrix::IS_DARK       => '#4A6000',
+		QRMatrix::M_DATA                           => '#ECF9BE',
 		// darkmodule
-		512  => '#080063',
+		QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK => '#080063',
 		// separator
-		8    => '#DDDDDD',
+		QRMatrix::M_SEPARATOR                      => '#DDDDDD',
 		// quietzone
-		18   => '#DDDDDD',
+		QRMatrix::M_QUIETZONE                      => '#DDDDDD',
 	],
 ]);
 

+ 18 - 16
examples/svg.php

@@ -11,6 +11,7 @@
 namespace chillerlan\QRCodeExamples;
 
 use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Common\EccLevel;
 
 require_once __DIR__.'/../vendor/autoload.php';
@@ -39,29 +40,30 @@ $options = new QROptions([
 		<style>rect{shape-rendering:crispEdges}</style>',
 	'moduleValues' => [
 		// finder
-		1536 => 'url(#g1)', // dark (true)
-		6    => '#fff', // light (false)
+		QRMatrix::M_FINDER | QRMatrix::IS_DARK     => 'url(#g1)', // dark (true)
+		QRMatrix::M_FINDER                         => '#fff',     // light (false)
+		QRMatrix::M_FINDER_DOT | QRMatrix::IS_DARK => 'url(#g2)', // finder dot, dark (true)
 		// alignment
-		2560 => 'url(#g1)',
-		10   => '#fff',
+		QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK  => 'url(#g1)',
+		QRMatrix::M_ALIGNMENT                      => '#fff',
 		// timing
-		3072 => 'url(#g1)',
-		12   => '#fff',
+		QRMatrix::M_TIMING | QRMatrix::IS_DARK     => 'url(#g1)',
+		QRMatrix::M_TIMING                         => '#fff',
 		// format
-		3584 => 'url(#g1)',
-		14   => '#fff',
+		QRMatrix::M_FORMAT | QRMatrix::IS_DARK     => 'url(#g1)',
+		QRMatrix::M_FORMAT                         => '#fff',
 		// version
-		4096 => 'url(#g1)',
-		16   => '#fff',
+		QRMatrix::M_VERSION | QRMatrix::IS_DARK    => 'url(#g1)',
+		QRMatrix::M_VERSION                        => '#fff',
 		// data
-		1024 => 'url(#g2)',
-		4    => '#fff',
+		QRMatrix::M_DATA | QRMatrix::IS_DARK       => 'url(#g2)',
+		QRMatrix::M_DATA                           => '#fff',
 		// darkmodule
-		512  => 'url(#g1)',
+		QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK => 'url(#g1)',
 		// separator
-		8    => '#fff',
+		QRMatrix::M_SEPARATOR                      => '#fff',
 		// quietzone
-		18   => '#fff',
+		QRMatrix::M_QUIETZONE                      => '#fff',
 	],
 ]);
 
@@ -72,7 +74,7 @@ header('Content-type: image/svg+xml');
 if($gzip === true){
 	header('Vary: Accept-Encoding');
 	header('Content-Encoding: gzip');
-	$qrcode = gzencode($qrcode ,9);
+	$qrcode = gzencode($qrcode, 9);
 }
 echo $qrcode;
 

+ 17 - 15
examples/text.php

@@ -11,6 +11,7 @@
 namespace chillerlan\QRCodeExamples;
 
 use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Common\EccLevel;
 
 require_once __DIR__.'/../vendor/autoload.php';
@@ -34,29 +35,30 @@ $options = new QROptions([
 	'eccLevel'     => EccLevel::L,
 	'moduleValues' => [
 		// finder
-		1536 => 'A', // dark (true)
-		6    => 'a', // light (false)
+		QRMatrix::M_FINDER | QRMatrix::IS_DARK     => 'A', // dark (true)
+		QRMatrix::M_FINDER                         => 'a', // light (false)
+		QRMatrix::M_FINDER_DOT | QRMatrix::IS_DARK => 'ä', // finder dot, dark (true)
 		// alignment
-		2560 => 'B',
-		10   => 'b',
+		QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK  => 'B',
+		QRMatrix::M_ALIGNMENT                      => 'b',
 		// timing
-		3072 => 'C',
-		12   => 'c',
+		QRMatrix::M_TIMING | QRMatrix::IS_DARK     => 'C',
+		QRMatrix::M_TIMING                         => 'c',
 		// format
-		3584 => 'D',
-		14   => 'd',
+		QRMatrix::M_FORMAT | QRMatrix::IS_DARK     => 'D',
+		QRMatrix::M_FORMAT                         => 'd',
 		// version
-		4096 => 'E',
-		16   => 'e',
+		QRMatrix::M_VERSION | QRMatrix::IS_DARK    => 'E',
+		QRMatrix::M_VERSION                        => 'e',
 		// data
-		1024 => 'F',
-		4    => 'f',
+		QRMatrix::M_DATA | QRMatrix::IS_DARK       => 'F',
+		QRMatrix::M_DATA                           => 'f',
 		// darkmodule
-		512  => 'G',
+		QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK => 'G',
 		// separator
-		8    => 'h',
+		QRMatrix::M_SEPARATOR                      => 'h',
 		// quietzone
-		18   => 'i',
+		QRMatrix::M_QUIETZONE                      => 'i',
 	],
 ]);
 

+ 2 - 1
src/Data/QRData.php

@@ -105,7 +105,8 @@ final class QRData{
 
 		return (new QRMatrix($this->version, $this->eccLevel))
 			->init($maskPattern, $test)
-			->mapData($data, $maskPattern)
+			->mapData($data)
+			->mask($maskPattern)
 		;
 	}
 

+ 62 - 33
src/Data/QRMatrix.php

@@ -28,31 +28,33 @@ use function array_fill, array_push, array_unshift, floor, max, min, range;
 final class QRMatrix{
 
 	/** @var int */
-	public const M_NULL       = 0x00;
+	public const M_NULL       = 0b000000000000;
 	/** @var int */
-	public const M_DARKMODULE = 0x02;
+	public const M_DARKMODULE = 0b000000000001;
 	/** @var int */
-	public const M_DATA       = 0x04;
+	public const M_DATA       = 0b000000000010;
 	/** @var int */
-	public const M_FINDER     = 0x06;
+	public const M_FINDER     = 0b000000000100;
 	/** @var int */
-	public const M_SEPARATOR  = 0x08;
+	public const M_SEPARATOR  = 0b000000001000;
 	/** @var int */
-	public const M_ALIGNMENT  = 0x0a;
+	public const M_ALIGNMENT  = 0b000000010000;
 	/** @var int */
-	public const M_TIMING     = 0x0c;
+	public const M_TIMING     = 0b000000100000;
 	/** @var int */
-	public const M_FORMAT     = 0x0e;
+	public const M_FORMAT     = 0b000001000000;
 	/** @var int */
-	public const M_VERSION    = 0x10;
+	public const M_VERSION    = 0b000010000000;
 	/** @var int */
-	public const M_QUIETZONE  = 0x12;
+	public const M_QUIETZONE  = 0b000100000000;
 	/** @var int */
-	public const M_LOGO       = 0x14;
+	public const M_LOGO       = 0b001000000000;
 	/** @var int */
-	public const M_FINDER_DOT = 0x16;
+	public const M_FINDER_DOT = 0b010000000000;
 	/** @var int */
-	public const M_TEST       = 0xff;
+	public const M_TEST       = 0b011111111111;
+	/** @var int */
+	public const IS_DARK      = 0b100000000000;
 
 	/**
 	 * the used mask pattern, set via QRMatrix::mapData()
@@ -123,7 +125,7 @@ final class QRMatrix{
 			$matrix[$y] = [];
 
 			foreach($row as $x => $val){
-				$matrix[$y][$x] = ($val >> 8) > 0;
+				$matrix[$y][$x] = ($val & $this::IS_DARK) === $this::IS_DARK;
 			}
 		}
 
@@ -170,29 +172,43 @@ final class QRMatrix{
 	/**
 	 * Sets the $M_TYPE value for the module at position [$x, $y]
 	 *
-	 *   true  => $M_TYPE << 8
+	 *   true  => $M_TYPE | 0x800
 	 *   false => $M_TYPE
 	 */
 	public function set(int $x, int $y, bool $value, int $M_TYPE):QRMatrix{
-		$this->matrix[$y][$x] = $M_TYPE << ($value ? 8 : 0);
+		$this->matrix[$y][$x] = $M_TYPE | ($value ? $this::IS_DARK : 0);
 
 		return $this;
 	}
 
 	/**
-	 * Checks whether a module is true (dark) or false (light)
+	 * Flips the value of the module
+	 */
+	public function flip(int $x, int $y):QRMatrix{
+		$this->matrix[$y][$x] ^= $this::IS_DARK;
+
+		return $this;
+	}
+
+	/**
+	 * Checks whether a module is of the given $M_TYPE
 	 *
-	 *   true  => $value >> 8 === $M_TYPE
-	 *            $value >> 8 > 0
+	 *   true => $value & $M_TYPE === $M_TYPE
+	 */
+	public function checkType(int $x, int $y, int $M_TYPE):bool{
+		return ($this->matrix[$y][$x] & $M_TYPE) === $M_TYPE;
+	}
+
+	/**
+	 * Checks whether a module is true (dark) or false (light)
 	 *
-	 *   false => $value === $M_TYPE
-	 *            $value >> 8 === 0
+	 *   true  => $value & 0x800 === 0x800
+	 *   false => $value & 0x800 === 0
 	 */
 	public function check(int $x, int $y):bool{
-		return ($this->matrix[$y][$x] >> 8) > 0;
+		return $this->checkType($x, $y, $this::IS_DARK);
 	}
 
-
 	/**
 	 * Sets the "dark module", that is always on the same position 1x1px away from the bottom left finder
 	 */
@@ -331,7 +347,7 @@ final class QRMatrix{
 		if($bits !== null){
 
 			for($i = 0; $i < 18; $i++){
-				$a = (int)floor($i / 3);
+				$a = (int)($i / 3);
 				$b = $i % 3 + $this->moduleCount - 8 - 3;
 				$v = !$test && (($bits >> $i) & 1) === 1;
 
@@ -495,18 +511,15 @@ final class QRMatrix{
 	 * @see \chillerlan\QRCode\Data\QRData::maskECC()
 	 *
 	 * @param \SplFixedArray<int> $data
-	 * @param int                 $maskPattern
 	 *
 	 * @return \chillerlan\QRCode\Data\QRMatrix
 	 */
-	public function mapData(SplFixedArray $data, int $maskPattern):QRMatrix{
-		$this->maskPattern = $maskPattern;
+	public function mapData(SplFixedArray $data):QRMatrix{
 		$byteCount         = $data->count();
 		$y                 = $this->moduleCount - 1;
 		$inc               = -1;
 		$byteIndex         = 0;
 		$bitIndex          = 7;
-		$mask              = $this->getMask($this->maskPattern);
 
 		for($i = $y; $i > 0; $i -= 2){
 
@@ -525,11 +538,7 @@ final class QRMatrix{
 							$v = (($data[$byteIndex] >> $bitIndex) & 1) === 1;
 						}
 
-						if($mask($x, $y) === 0){
-							$v = !$v;
-						}
-
-						$this->matrix[$y][$x] = $this::M_DATA << ($v ? 8 : 0);
+						$this->matrix[$y][$x] = $this::M_DATA | ($v ? $this::IS_DARK : 0);
 						$bitIndex--;
 
 						if($bitIndex === -1){
@@ -555,6 +564,26 @@ final class QRMatrix{
 		return $this;
 	}
 
+	/**
+	 * Applies the mask pattern
+	 *
+	 * ISO/IEC 18004:2000 Section 8.8.1
+	 */
+	public function mask(int $maskPattern):QRMatrix{
+		$this->maskPattern = $maskPattern;
+		$mask              = $this->getMask($this->maskPattern);
+
+		foreach($this->matrix as $y => &$row){
+			foreach($row as $x => &$val){
+				if($mask($x, $y) === 0 && ($val & $this::M_DATA) === $this::M_DATA){
+					$val ^= $this::IS_DARK;
+				}
+			}
+		}
+
+		return $this;
+	}
+
 	/**
 	 * ISO/IEC 18004:2000 Section 8.8.1
 	 *

+ 20 - 20
src/Output/QROutputInterface.php

@@ -21,27 +21,27 @@ interface QROutputInterface{
 
 	const DEFAULT_MODULE_VALUES = [
 		// light
-		QRMatrix::M_NULL            => false, // 0
-		QRMatrix::M_DATA            => false, // 4
-		QRMatrix::M_FINDER          => false, // 6
-		QRMatrix::M_SEPARATOR       => false, // 8
-		QRMatrix::M_ALIGNMENT       => false, // 10
-		QRMatrix::M_TIMING          => false, // 12
-		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
+		QRMatrix::M_NULL                           => false,
+		QRMatrix::M_DATA                           => false,
+		QRMatrix::M_FINDER                         => false,
+		QRMatrix::M_SEPARATOR                      => false,
+		QRMatrix::M_ALIGNMENT                      => false,
+		QRMatrix::M_TIMING                         => false,
+		QRMatrix::M_FORMAT                         => false,
+		QRMatrix::M_VERSION                        => false,
+		QRMatrix::M_QUIETZONE                      => false,
+		QRMatrix::M_LOGO                           => false,
+		QRMatrix::M_TEST                           => false,
 		// dark
-		QRMatrix::M_DARKMODULE << 8 => true,  // 512
-		QRMatrix::M_DATA << 8       => true,  // 1024
-		QRMatrix::M_FINDER << 8     => true,  // 1536
-		QRMatrix::M_ALIGNMENT << 8  => true,  // 2560
-		QRMatrix::M_TIMING << 8     => true,  // 3072
-		QRMatrix::M_FORMAT << 8     => true,  // 3584
-		QRMatrix::M_VERSION << 8    => true,  // 4096
-		QRMatrix::M_FINDER_DOT << 8 => true,  // 5632
-		QRMatrix::M_TEST << 8       => true,  // 65280
+		QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK => true,
+		QRMatrix::M_DATA | QRMatrix::IS_DARK       => true,
+		QRMatrix::M_FINDER | QRMatrix::IS_DARK     => true,
+		QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK  => true,
+		QRMatrix::M_TIMING | QRMatrix::IS_DARK     => true,
+		QRMatrix::M_FORMAT | QRMatrix::IS_DARK     => true,
+		QRMatrix::M_VERSION | QRMatrix::IS_DARK    => true,
+		QRMatrix::M_FINDER_DOT | QRMatrix::IS_DARK => true,
+		QRMatrix::M_TEST | QRMatrix::IS_DARK       => true,
 	];
 
 	/**

+ 41 - 18
tests/Data/QRMatrixTest.php

@@ -87,11 +87,11 @@ final class QRMatrixTest extends TestCase{
 	 */
 	public function testGetSetCheck():void{
 		$this->matrix->set(10, 10, true, QRMatrix::M_TEST);
-		$this::assertSame(65280, $this->matrix->get(10, 10));
+		$this::assertSame(QRMatrix::M_TEST | QRMatrix::IS_DARK, $this->matrix->get(10, 10));
 		$this::assertTrue($this->matrix->check(10, 10));
 
 		$this->matrix->set(20, 20, false, QRMatrix::M_TEST);
-		$this::assertSame(255, $this->matrix->get(20, 20));
+		$this::assertSame(QRMatrix::M_TEST, $this->matrix->get(20, 20));
 		$this::assertFalse($this->matrix->check(20, 20));
 	}
 
@@ -119,7 +119,7 @@ final class QRMatrixTest extends TestCase{
 	public function testSetDarkModule(int $version):void{
 		$matrix = $this->getMatrix($version)->setDarkModule();
 
-		$this::assertSame(QRMatrix::M_DARKMODULE << 8, $matrix->get(8, $matrix->size() - 8));
+		$this::assertSame(QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK, $matrix->get(8, $matrix->size() - 8));
 	}
 
 	/**
@@ -130,9 +130,9 @@ final class QRMatrixTest extends TestCase{
 	public function testSetFinderPattern(int $version):void{
 		$matrix = $this->getMatrix($version)->setFinderPattern();
 
-		$this::assertSame(QRMatrix::M_FINDER << 8, $matrix->get(0, 0));
-		$this::assertSame(QRMatrix::M_FINDER << 8, $matrix->get(0, $matrix->size() - 1));
-		$this::assertSame(QRMatrix::M_FINDER << 8, $matrix->get($matrix->size() - 1, 0));
+		$this::assertSame(QRMatrix::M_FINDER | QRMatrix::IS_DARK, $matrix->get(0, 0));
+		$this::assertSame(QRMatrix::M_FINDER | QRMatrix::IS_DARK, $matrix->get(0, $matrix->size() - 1));
+		$this::assertSame(QRMatrix::M_FINDER | QRMatrix::IS_DARK, $matrix->get($matrix->size() - 1, 0));
 	}
 
 	/**
@@ -174,12 +174,12 @@ final class QRMatrixTest extends TestCase{
 		foreach($alignmentPattern as $py){
 			foreach($alignmentPattern as $px){
 
-				if($matrix->get($px, $py) === QRMatrix::M_FINDER << 8){
-					$this::assertSame(QRMatrix::M_FINDER << 8, $matrix->get($px, $py), 'skipped finder pattern');
+				if($matrix->get($px, $py) === (QRMatrix::M_FINDER | QRMatrix::IS_DARK)){
+					$this::assertSame(QRMatrix::M_FINDER | QRMatrix::IS_DARK, $matrix->get($px, $py), 'skipped finder pattern');
 					continue;
 				}
 
-				$this::assertSame(QRMatrix::M_ALIGNMENT << 8, $matrix->get($px, $py));
+				$this::assertSame(QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK, $matrix->get($px, $py));
 			}
 		}
 
@@ -204,13 +204,13 @@ final class QRMatrixTest extends TestCase{
 			if($i % 2 === 0){
 				$p1 = $matrix->get(6, $i);
 
-				if($p1 === QRMatrix::M_ALIGNMENT << 8){
-					$this::assertSame(QRMatrix::M_ALIGNMENT << 8, $p1, 'skipped alignment pattern');
+				if($p1 === (QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK)){
+					$this::assertSame(QRMatrix::M_ALIGNMENT | QRMatrix::IS_DARK, $p1, 'skipped alignment pattern');
 					continue;
 				}
 
-				$this::assertSame(QRMatrix::M_TIMING << 8, $p1);
-				$this::assertSame(QRMatrix::M_TIMING << 8, $matrix->get($i, 6));
+				$this::assertSame(QRMatrix::M_TIMING | QRMatrix::IS_DARK, $p1);
+				$this::assertSame(QRMatrix::M_TIMING | QRMatrix::IS_DARK, $matrix->get($i, 6));
 			}
 		}
 	}
@@ -274,8 +274,8 @@ final class QRMatrixTest extends TestCase{
 		$this::assertSame(QRMatrix::M_QUIETZONE, $matrix->get(0, 0));
 		$this::assertSame(QRMatrix::M_QUIETZONE, $matrix->get($size - 1, $size - 1));
 
-		$this::assertSame(QRMatrix::M_TEST << 8, $matrix->get($q, $q));
-		$this::assertSame(QRMatrix::M_TEST << 8, $matrix->get($size - 1 - $q, $size - 1 - $q));
+		$this::assertSame(QRMatrix::M_TEST | QRMatrix::IS_DARK, $matrix->get($q, $q));
+		$this::assertSame(QRMatrix::M_TEST | QRMatrix::IS_DARK, $matrix->get($size - 1 - $q, $size - 1 - $q));
 	}
 
 	/**
@@ -319,10 +319,10 @@ final class QRMatrixTest extends TestCase{
 		// logo space should not overwrite quiet zone & function patterns
 		$m->setLogoSpace(21, 21, -10, -10);
 		$this::assertSame(QRMatrix::M_QUIETZONE, $m->get(9, 9));
-		$this::assertSame(QRMatrix::M_FINDER << 8, $m->get(10, 10));
-		$this::assertSame(QRMatrix::M_FINDER << 8, $m->get(16, 16));
+		$this::assertSame(QRMatrix::M_FINDER | QRMatrix::IS_DARK, $m->get(10, 10));
+		$this::assertSame(QRMatrix::M_FINDER | QRMatrix::IS_DARK, $m->get(16, 16));
 		$this::assertSame(QRMatrix::M_SEPARATOR, $m->get(17, 17));
-		$this::assertSame(QRMatrix::M_FORMAT << 8, $m->get(18, 18));
+		$this::assertSame(QRMatrix::M_FORMAT | QRMatrix::IS_DARK, $m->get(18, 18));
 		$this::assertSame(QRMatrix::M_LOGO, $m->get(19, 19));
 		$this::assertSame(QRMatrix::M_LOGO, $m->get(20, 20));
 		$this::assertNotSame(QRMatrix::M_LOGO, $m->get(21, 21));
@@ -353,4 +353,27 @@ final class QRMatrixTest extends TestCase{
 		(new QRCode($o))->addByteSegment('testdata')->getMatrix()->setLogoSpace(50, 50);
 	}
 
+	/**
+	 * Tests flipping the value of a module
+	 */
+	public function testFlip():void{
+		// using the dark module here because i'm lazy
+		$matrix = $this->getMatrix(10)->setDarkModule();
+		$x = 8;
+		$y = $matrix->size() - 8;
+
+		// cover checkType()
+		$this::assertTrue($matrix->checkType($x, $y, QRMatrix::M_DARKMODULE));
+		// verify the current state (dark)
+		$this::assertSame(QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK, $matrix->get($x, $y));
+		// flip
+		$matrix->flip($x, $y);
+		// verify flip
+		$this::assertSame(QRMatrix::M_DARKMODULE, $matrix->get($x, $y));
+		// flip again
+		$matrix->flip($x, $y);
+		// verify flip
+		$this::assertSame(QRMatrix::M_DARKMODULE | QRMatrix::IS_DARK, $matrix->get($x, $y));
+	}
+
 }

+ 3 - 3
tests/Output/QRMarkupTest.php

@@ -12,7 +12,7 @@
 
 namespace chillerlan\QRCodeTest\Output;
 
-use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\{Data\QRMatrix, QRCode, QROptions};
 use chillerlan\QRCode\Output\{QROutputInterface, QRMarkup};
 
 /**
@@ -46,8 +46,8 @@ class QRMarkupTest extends QROutputTestAbstract{
 		$this->options->imageBase64  = false;
 		$this->options->moduleValues = [
 			// data
-			1024 => '#4A6000',
-			4    => '#ECF9BE',
+			QRMatrix::M_DATA | QRMatrix::IS_DARK => '#4A6000',
+			QRMatrix::M_DATA                     => '#ECF9BE',
 		];
 
 		$this->outputInterface = $this->getOutputInterface($this->options);

+ 6 - 4
tests/Output/QRStringTest.php

@@ -12,9 +12,11 @@
 
 namespace chillerlan\QRCodeTest\Output;
 
-use chillerlan\QRCodeExamples\MyCustomOutput;
-use chillerlan\QRCode\{Common\EccLevel, QRCode, QROptions};
+use chillerlan\QRCode\{QRCode, QROptions};
+use chillerlan\QRCode\Common\EccLevel;
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Output\{QROutputInterface, QRString};
+use chillerlan\QRCodeExamples\MyCustomOutput;
 
 /**
  * Tests the QRString output module
@@ -47,8 +49,8 @@ class QRStringTest extends QROutputTestAbstract{
 
 		$this->options->moduleValues = [
 			// data
-			1024 => 'A',
-			4    => 'B',
+			QRMatrix::M_DATA | QRMatrix::IS_DARK => 'A',
+			QRMatrix::M_DATA                     => 'B',
 		];
 
 		$this->outputInterface = $this->getOutputInterface($this->options);

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
tests/Output/samples/json


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
tests/Output/samples/svg


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio