ByteMatrix.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. declare(strict_types = 1);
  3. namespace BaconQrCode\Encoder;
  4. use SplFixedArray;
  5. use Traversable;
  6. /**
  7. * Byte matrix.
  8. */
  9. final class ByteMatrix
  10. {
  11. /**
  12. * Bytes in the matrix, represented as array.
  13. *
  14. * @var SplFixedArray<SplFixedArray<int>>
  15. */
  16. private $bytes;
  17. /**
  18. * Width of the matrix.
  19. *
  20. * @var int
  21. */
  22. private $width;
  23. /**
  24. * Height of the matrix.
  25. *
  26. * @var int
  27. */
  28. private $height;
  29. public function __construct(int $width, int $height)
  30. {
  31. $this->height = $height;
  32. $this->width = $width;
  33. $this->bytes = new SplFixedArray($height);
  34. for ($y = 0; $y < $height; ++$y) {
  35. $this->bytes[$y] = SplFixedArray::fromArray(array_fill(0, $width, 0));
  36. }
  37. }
  38. /**
  39. * Gets the width of the matrix.
  40. */
  41. public function getWidth() : int
  42. {
  43. return $this->width;
  44. }
  45. /**
  46. * Gets the height of the matrix.
  47. */
  48. public function getHeight() : int
  49. {
  50. return $this->height;
  51. }
  52. /**
  53. * Gets the internal representation of the matrix.
  54. *
  55. * @return SplFixedArray<SplFixedArray<int>>
  56. */
  57. public function getArray() : SplFixedArray
  58. {
  59. return $this->bytes;
  60. }
  61. /**
  62. * @return Traversable<int>
  63. */
  64. public function getBytes() : Traversable
  65. {
  66. foreach ($this->bytes as $row) {
  67. foreach ($row as $byte) {
  68. yield $byte;
  69. }
  70. }
  71. }
  72. /**
  73. * Gets the byte for a specific position.
  74. */
  75. public function get(int $x, int $y) : int
  76. {
  77. return $this->bytes[$y][$x];
  78. }
  79. /**
  80. * Sets the byte for a specific position.
  81. */
  82. public function set(int $x, int $y, int $value) : void
  83. {
  84. $this->bytes[$y][$x] = $value;
  85. }
  86. /**
  87. * Clears the matrix with a specific value.
  88. */
  89. public function clear(int $value) : void
  90. {
  91. for ($y = 0; $y < $this->height; ++$y) {
  92. for ($x = 0; $x < $this->width; ++$x) {
  93. $this->bytes[$y][$x] = $value;
  94. }
  95. }
  96. }
  97. public function __clone()
  98. {
  99. $this->bytes = clone $this->bytes;
  100. foreach ($this->bytes as $index => $row) {
  101. $this->bytes[$index] = clone $row;
  102. }
  103. }
  104. /**
  105. * Returns a string representation of the matrix.
  106. */
  107. public function __toString() : string
  108. {
  109. $result = '';
  110. for ($y = 0; $y < $this->height; $y++) {
  111. for ($x = 0; $x < $this->width; $x++) {
  112. switch ($this->bytes[$y][$x]) {
  113. case 0:
  114. $result .= ' 0';
  115. break;
  116. case 1:
  117. $result .= ' 1';
  118. break;
  119. default:
  120. $result .= ' ';
  121. break;
  122. }
  123. }
  124. $result .= "\n";
  125. }
  126. return $result;
  127. }
  128. }