MaskPattern.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. /**
  3. * Class MaskPattern
  4. *
  5. * @filesource MaskPattern.php
  6. * @created 19.01.2021
  7. * @package chillerlan\QRCode\Common
  8. * @author smiley <smiley@chillerlan.net>
  9. * @copyright 2021 smiley
  10. * @license MIT
  11. */
  12. namespace chillerlan\QRCode\Common;
  13. use chillerlan\QRCode\QRCodeException;
  14. use Closure;
  15. /**
  16. *
  17. */
  18. class MaskPattern{
  19. public const PATTERN_000 = 0b000;
  20. public const PATTERN_001 = 0b001;
  21. public const PATTERN_010 = 0b010;
  22. public const PATTERN_011 = 0b011;
  23. public const PATTERN_100 = 0b100;
  24. public const PATTERN_101 = 0b101;
  25. public const PATTERN_110 = 0b110;
  26. public const PATTERN_111 = 0b111;
  27. public const PATTERNS = [
  28. self::PATTERN_000,
  29. self::PATTERN_001,
  30. self::PATTERN_010,
  31. self::PATTERN_011,
  32. self::PATTERN_100,
  33. self::PATTERN_101,
  34. self::PATTERN_110,
  35. self::PATTERN_111,
  36. ];
  37. private int $maskPattern;
  38. /**
  39. * MaskPattern constructor.
  40. *
  41. * ISO/IEC 18004:2000 Section 8.8.1
  42. *
  43. * @throws \chillerlan\QRCode\QRCodeException
  44. */
  45. public function __construct(int $maskPattern){
  46. if((0b111 & $maskPattern) !== $maskPattern){
  47. throw new QRCodeException('invalid mask pattern'); // @codeCoverageIgnore
  48. }
  49. $this->maskPattern = $maskPattern;
  50. }
  51. public function getPattern():int{
  52. return $this->maskPattern;
  53. }
  54. /**
  55. * ISO/IEC 18004:2000 Section 8.8.1
  56. *
  57. * Note that some versions of the QR code standard have had errors in the section about mask patterns.
  58. * The information below has been corrected. (https://www.thonky.com/qr-code-tutorial/mask-patterns)
  59. */
  60. public function getMask():Closure{
  61. return [
  62. self::PATTERN_000 => fn($x, $y):int => ($x + $y) % 2,
  63. self::PATTERN_001 => fn($x, $y):int => $y % 2,
  64. self::PATTERN_010 => fn($x, $y):int => $x % 3,
  65. self::PATTERN_011 => fn($x, $y):int => ($x + $y) % 3,
  66. self::PATTERN_100 => fn($x, $y):int => ((int)($y / 2) + (int)($x / 3)) % 2,
  67. self::PATTERN_101 => fn($x, $y):int => (($x * $y) % 2) + (($x * $y) % 3),
  68. self::PATTERN_110 => fn($x, $y):int => ((($x * $y) % 2) + (($x * $y) % 3)) % 2,
  69. self::PATTERN_111 => fn($x, $y):int => ((($x * $y) % 3) + (($x + $y) % 2)) % 2,
  70. ][$this->maskPattern];
  71. }
  72. }