diff --git a/src/Renderer/Module/EdgeIterator/EdgeIterator.php b/src/Renderer/Module/EdgeIterator/EdgeIterator.php index 01f692c..91d3850 100644 --- a/src/Renderer/Module/EdgeIterator/EdgeIterator.php +++ b/src/Renderer/Module/EdgeIterator/EdgeIterator.php @@ -122,10 +122,11 @@ private function xorEdge(Edge $path) : void } $x = $points[$i][0]; - $minY = min($y1, $y); + $offset = $this->width * min($y1, $y); - for ($j = $x; $j < $maxX; ++$j) { - $this->flip($j, $minY); + // The cells flipped here are always inside of the matrix, so they need no bounds checks + for ($j = $offset + $x, $end = $offset + $maxX; $j < $end; ++$j) { + $this->bytes[$j] = 1 === $this->bytes[$j] ? 0 : 1; } $y1 = $y; @@ -150,11 +151,4 @@ private function pointOf(int $i) : array $y = intdiv($i, $this->width); return [$i - $y * $this->width, $y]; } - - private function flip(int $x, int $y) : void - { - $this->bytes[$this->width * $y + $x] = ( - $this->isSet($x, $y) ? 0 : 1 - ); - } } diff --git a/src/Renderer/Module/SquareModule.php b/src/Renderer/Module/SquareModule.php index 8cf1d0b..9bb1725 100644 --- a/src/Renderer/Module/SquareModule.php +++ b/src/Renderer/Module/SquareModule.php @@ -30,13 +30,16 @@ public function createPath(ByteMatrix $matrix) : Path foreach (new EdgeIterator($matrix) as $edge) { $points = $edge->getSimplifiedPoints(); $length = count($points); - $path = $path->move($points[0][0], $points[0][1]); + + // Each operation added to a path copies the ones before it, so every edge is built as a short path of its + // own first, rather than one operation at a time onto the whole path + $edgePath = (new Path())->move($points[0][0], $points[0][1]); for ($i = 1; $i < $length; ++$i) { - $path = $path->line($points[$i][0], $points[$i][1]); + $edgePath = $edgePath->line($points[$i][0], $points[$i][1]); } - $path = $path->close(); + $path = $path->append($edgePath->close()); } return $path;