Przeglądaj źródła

:octocat: fully support reflectance reversal

smiley 2 lat temu
rodzic
commit
efb829c4a6
2 zmienionych plików z 119 dodań i 70 usunięć
  1. 69 24
      src/Data/QRMatrix.php
  2. 50 46
      src/Output/QROutputInterface.php

+ 69 - 24
src/Data/QRMatrix.php

@@ -21,54 +21,77 @@ use function array_fill, array_map, array_reverse, count, floor, intdiv;
  */
 class QRMatrix{
 
+	/*
+	 * special values
+	 */
+
 	/** @var int */
-	public const IS_DARK          = 0b100000000000;
+	public const IS_DARK            = 0b100000000000;
 	/** @var int */
-	public const M_NULL           = 0b000000000000;
+	public const M_NULL             = 0b000000000000;
 	/** @var int */
-	public const M_DARKMODULE     = 0b100000000001;
+	public const M_LOGO             = 0b001000000000;
 	/** @var int */
-	public const M_DATA           = 0b000000000010;
+	public const M_LOGO_DARK        = 0b101000000000;
 	/** @var int */
-	public const M_DATA_DARK      = 0b100000000010;
+	public const M_TEST             = 0b011111111111;
 	/** @var int */
-	public const M_FINDER         = 0b000000000100;
+	public const M_TEST_DARK        = 0b111111111111;
+
+	/*
+	 * light values
+	 */
+
 	/** @var int */
-	public const M_FINDER_DARK    = 0b100000000100;
+	public const M_DATA             = 0b000000000010;
 	/** @var int */
-	public const M_SEPARATOR      = 0b000000001000;
+	public const M_FINDER           = 0b000000000100;
 	/** @var int */
-	public const M_SEPARATOR_DARK = 0b100000001000;
+	public const M_SEPARATOR        = 0b000000001000;
 	/** @var int */
-	public const M_ALIGNMENT      = 0b000000010000;
+	public const M_ALIGNMENT        = 0b000000010000;
 	/** @var int */
-	public const M_ALIGNMENT_DARK = 0b100000010000;
+	public const M_TIMING           = 0b000000100000;
 	/** @var int */
-	public const M_TIMING         = 0b000000100000;
+	public const M_FORMAT           = 0b000001000000;
 	/** @var int */
-	public const M_TIMING_DARK    = 0b100000100000;
+	public const M_VERSION          = 0b000010000000;
 	/** @var int */
-	public const M_FORMAT         = 0b000001000000;
+	public const M_QUIETZONE        = 0b000100000000;
+
+	/*
+	 * dark values
+	 */
+
 	/** @var int */
-	public const M_FORMAT_DARK    = 0b100001000000;
+	public const M_DARKMODULE       = 0b100000000001;
 	/** @var int */
-	public const M_VERSION        = 0b000010000000;
+	public const M_DATA_DARK        = 0b100000000010;
 	/** @var int */
-	public const M_VERSION_DARK   = 0b100010000000;
+	public const M_FINDER_DARK      = 0b100000000100;
 	/** @var int */
-	public const M_QUIETZONE      = 0b000100000000;
+	public const M_ALIGNMENT_DARK   = 0b100000010000;
 	/** @var int */
-	public const M_QUIETZONE_DARK = 0b100100000000;
+	public const M_TIMING_DARK      = 0b100000100000;
 	/** @var int */
-	public const M_LOGO           = 0b001000000000;
+	public const M_FORMAT_DARK      = 0b100001000000;
 	/** @var int */
-	public const M_LOGO_DARK      = 0b101000000000;
+	public const M_VERSION_DARK     = 0b100010000000;
 	/** @var int */
-	public const M_FINDER_DOT     = 0b110000000000;
+	public const M_FINDER_DOT       = 0b110000000000;
+
+	/*
+	 * values used for reversed reflectance
+	 */
+
+	/** @var int */
+	public const M_DARKMODULE_LIGHT = 0b000000000001;
 	/** @var int */
-	public const M_TEST           = 0b011111111111;
+	public const M_FINDER_DOT_LIGHT = 0b010000000000;
 	/** @var int */
-	public const M_TEST_DARK      = 0b111111111111;
+	public const M_SEPARATOR_DARK   = 0b100000001000;
+	/** @var int */
+	public const M_QUIETZONE_DARK   = 0b100100000000;
 
 	/**
 	 * Map of flag => coord
@@ -579,6 +602,28 @@ class QRMatrix{
 		return $this;
 	}
 
+	/**
+	 * Inverts the values of the whole matrix
+	 *
+	 * ISO/IEC 18004:2015 Section 6.2 - Reflectance reversal
+	 */
+	public function invert():self{
+
+		foreach($this->matrix as $y => $row){
+			foreach($row as $x => $val){
+
+				// skip null fields
+				if($val === $this::M_NULL){
+					continue;
+				}
+
+				$this->set($x, $y, ($val & $this::IS_DARK) !== $this::IS_DARK, $val);
+			}
+		}
+
+		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.

+ 50 - 46
src/Output/QROutputInterface.php

@@ -65,30 +65,32 @@ interface QROutputInterface{
 	 */
 	public const DEFAULT_MODULE_VALUES = [
 		// light
-		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,
+		QRMatrix::M_NULL             => false,
+		QRMatrix::M_DARKMODULE_LIGHT => 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_FINDER_DOT_LIGHT => false,
+		QRMatrix::M_TEST             => false,
 		// dark
-		QRMatrix::M_DARKMODULE     => true,
-		QRMatrix::M_DATA_DARK      => true,
-		QRMatrix::M_FINDER_DARK    => true,
-		QRMatrix::M_SEPARATOR_DARK => true,
-		QRMatrix::M_ALIGNMENT_DARK => true,
-		QRMatrix::M_TIMING_DARK    => true,
-		QRMatrix::M_FORMAT_DARK    => true,
-		QRMatrix::M_VERSION_DARK   => true,
-		QRMatrix::M_QUIETZONE_DARK => true,
-		QRMatrix::M_LOGO_DARK      => true,
-		QRMatrix::M_FINDER_DOT     => true,
-		QRMatrix::M_TEST_DARK      => true,
+		QRMatrix::M_DARKMODULE       => true,
+		QRMatrix::M_DATA_DARK        => true,
+		QRMatrix::M_FINDER_DARK      => true,
+		QRMatrix::M_SEPARATOR_DARK   => true,
+		QRMatrix::M_ALIGNMENT_DARK   => true,
+		QRMatrix::M_TIMING_DARK      => true,
+		QRMatrix::M_FORMAT_DARK      => true,
+		QRMatrix::M_VERSION_DARK     => true,
+		QRMatrix::M_QUIETZONE_DARK   => true,
+		QRMatrix::M_LOGO_DARK        => true,
+		QRMatrix::M_FINDER_DOT       => true,
+		QRMatrix::M_TEST_DARK        => true,
 	];
 
 	/**
@@ -98,30 +100,32 @@ interface QROutputInterface{
 	 */
 	public const LAYERNAMES = [
 		// light
-		QRMatrix::M_NULL           => 'null',
-		QRMatrix::M_DATA           => 'data',
-		QRMatrix::M_FINDER         => 'finder',
-		QRMatrix::M_SEPARATOR      => 'separator',
-		QRMatrix::M_ALIGNMENT      => 'alignment',
-		QRMatrix::M_TIMING         => 'timing',
-		QRMatrix::M_FORMAT         => 'format',
-		QRMatrix::M_VERSION        => 'version',
-		QRMatrix::M_QUIETZONE      => 'quietzone',
-		QRMatrix::M_LOGO           => 'logo',
-		QRMatrix::M_TEST           => 'test',
+		QRMatrix::M_NULL             => 'null',
+		QRMatrix::M_DARKMODULE_LIGHT => 'darkmodule-light',
+		QRMatrix::M_DATA             => 'data',
+		QRMatrix::M_FINDER           => 'finder',
+		QRMatrix::M_SEPARATOR        => 'separator',
+		QRMatrix::M_ALIGNMENT        => 'alignment',
+		QRMatrix::M_TIMING           => 'timing',
+		QRMatrix::M_FORMAT           => 'format',
+		QRMatrix::M_VERSION          => 'version',
+		QRMatrix::M_QUIETZONE        => 'quietzone',
+		QRMatrix::M_LOGO             => 'logo',
+		QRMatrix::M_FINDER_DOT_LIGHT => 'finder-dot-light',
+		QRMatrix::M_TEST             => 'test',
 		// dark
-		QRMatrix::M_DARKMODULE     => 'darkmodule',
-		QRMatrix::M_DATA_DARK      => 'data-dark',
-		QRMatrix::M_FINDER_DARK    => 'finder-dark',
-		QRMatrix::M_SEPARATOR_DARK => 'separator-dark',
-		QRMatrix::M_ALIGNMENT_DARK => 'alignment-dark',
-		QRMatrix::M_TIMING_DARK    => 'timing-dark',
-		QRMatrix::M_FORMAT_DARK    => 'format-dark',
-		QRMatrix::M_VERSION_DARK   => 'version-dark',
-		QRMatrix::M_QUIETZONE_DARK => 'quietzone-dark',
-		QRMatrix::M_LOGO_DARK      => 'logo-dark',
-		QRMatrix::M_FINDER_DOT     => 'finder-dot',
-		QRMatrix::M_TEST_DARK      => 'test-dark',
+		QRMatrix::M_DARKMODULE       => 'darkmodule',
+		QRMatrix::M_DATA_DARK        => 'data-dark',
+		QRMatrix::M_FINDER_DARK      => 'finder-dark',
+		QRMatrix::M_SEPARATOR_DARK   => 'separator-dark',
+		QRMatrix::M_ALIGNMENT_DARK   => 'alignment-dark',
+		QRMatrix::M_TIMING_DARK      => 'timing-dark',
+		QRMatrix::M_FORMAT_DARK      => 'format-dark',
+		QRMatrix::M_VERSION_DARK     => 'version-dark',
+		QRMatrix::M_QUIETZONE_DARK   => 'quietzone-dark',
+		QRMatrix::M_LOGO_DARK        => 'logo-dark',
+		QRMatrix::M_FINDER_DOT       => 'finder-dot',
+		QRMatrix::M_TEST_DARK        => 'test-dark',
 	];
 
 	/**