diff --git a/src/Renderer/Image/EpsImageBackEnd.php b/src/Renderer/Image/EpsImageBackEnd.php index 4269456..1e12230 100644 --- a/src/Renderer/Image/EpsImageBackEnd.php +++ b/src/Renderer/Image/EpsImageBackEnd.php @@ -21,6 +21,23 @@ final class EpsImageBackEnd implements ImageBackEndInterface { private const PRECISION = 3; + private const S_SAFE = "%1.".self::PRECISION."F"; + private const SS_SAFE = self::S_SAFE." ".self::S_SAFE; + private const SSS_SAFE = self::SS_SAFE." ".self::S_SAFE; + private const SSSS_SAFE = self::SS_SAFE." ".self::SS_SAFE; + private const SCALE_FORMAT = "%1\$1.".self::PRECISION."F %1\$1.".self::PRECISION."F s\n"; + private const TRANSLATE_FORMAT = self::SS_SAFE." t\n"; + private const MOVE_FORMAT = self::SS_SAFE." m"; + private const LINE_FORMAT = self::SS_SAFE." l"; + private const CURVE_FORMAT = self::SSS_SAFE." ".self::SSS_SAFE." c"; + private const GRADIENTH_FORMAT = " /Coords [ ".self::SSSS_SAFE." ]\n"; + private const GRADIENTV_FORMAT = " /Coords [ ".self::SSSS_SAFE." ]\n"; + private const GRADIENTD_FORMAT = " /Coords [ ".self::SSSS_SAFE." ]\n"; + private const GRADIENTID_FORMAT = " /Coords [ ".self::SSSS_SAFE." ]\n"; + private const GRADIENTR_FORMAT = " /Coords [ ".self::SS_SAFE." 0 ".self::SSS_SAFE." ]\n"; + private const RGBCOLOR_FORMAT = self::SSS_SAFE; + private const CMYKCOLOR_FORMAT = self::SSSS_SAFE; + private ?string $eps; @@ -72,7 +89,7 @@ public function scale(float $size) : void throw new RuntimeException('No image has been started'); } - $this->eps .= sprintf("%1\$s %1\$s s\n", round($size, self::PRECISION)); + $this->eps .= sprintf(self::SCALE_FORMAT, round($size, self::PRECISION)); } public function translate(float $x, float $y) : void @@ -81,7 +98,7 @@ public function translate(float $x, float $y) : void throw new RuntimeException('No image has been started'); } - $this->eps .= sprintf("%s %s t\n", round($x, self::PRECISION), round($y, self::PRECISION)); + $this->eps .= sprintf(self::TRANSLATE_FORMAT, round($x, self::PRECISION), round($y, self::PRECISION)); } public function rotate(int $degrees) : void @@ -173,13 +190,13 @@ private function drawPathOperations(Iterable $ops, &$fromX, &$fromY) : string case $op instanceof Move: $fromX = $toX = round($op->getX(), self::PRECISION); $fromY = $toY = round($op->getY(), self::PRECISION); - $pathData[] = sprintf('%s %s m', $toX, $toY); + $pathData[] = sprintf(self::MOVE_FORMAT, $toX, $toY); break; case $op instanceof Line: $fromX = $toX = round($op->getX(), self::PRECISION); $fromY = $toY = round($op->getY(), self::PRECISION); - $pathData[] = sprintf('%s %s l', $toX, $toY); + $pathData[] = sprintf(self::LINE_FORMAT, $toX, $toY); break; case $op instanceof EllipticArc: @@ -193,7 +210,7 @@ private function drawPathOperations(Iterable $ops, &$fromX, &$fromY) : string $y2 = round($op->getY2(), self::PRECISION); $fromX = $x3 = round($op->getX3(), self::PRECISION); $fromY = $y3 = round($op->getY3(), self::PRECISION); - $pathData[] = sprintf('%s %s %s %s %s %s c', $x1, $y1, $x2, $y2, $x3, $y3); + $pathData[] = sprintf(self::CURVE_FORMAT, $x1, $y1, $x2, $y2, $x3, $y3); break; case $op instanceof Close: @@ -268,7 +285,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa switch ($gradient->getType()) { case GradientType::HORIZONTAL(): $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", + self::GRADIENTH_FORMAT, round($x, self::PRECISION), round($y, self::PRECISION), round($x + $width, self::PRECISION), @@ -278,7 +295,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa case GradientType::VERTICAL(): $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", + self::GRADIENTV_FORMAT, round($x, self::PRECISION), round($y, self::PRECISION), round($x, self::PRECISION), @@ -288,7 +305,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa case GradientType::DIAGONAL(): $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", + self::GRADIENTD_FORMAT, round($x, self::PRECISION), round($y, self::PRECISION), round($x + $width, self::PRECISION), @@ -298,7 +315,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa case GradientType::INVERSE_DIAGONAL(): $this->eps .= sprintf( - " /Coords [ %s %s %s %s ]\n", + self::GRADIENTID_FORMAT, round($x, self::PRECISION), round($y + $height, self::PRECISION), round($x + $width, self::PRECISION), @@ -311,7 +328,7 @@ private function createGradientFill(Gradient $gradient, float $x, float $y, floa $centerY = ($y + $height) / 2; $this->eps .= sprintf( - " /Coords [ %s %s 0 %s %s %s ]\n", + self::GRADIENTR_FORMAT, round($centerX, self::PRECISION), round($centerY, self::PRECISION), round($centerX, self::PRECISION), @@ -351,12 +368,12 @@ private function getColorSetString(ColorInterface $color) : string private function getColorString(ColorInterface $color) : string { if ($color instanceof Rgb) { - return sprintf('%s %s %s', $color->getRed() / 255, $color->getGreen() / 255, $color->getBlue() / 255); + return sprintf(self::RGBCOLOR_FORMAT, $color->getRed() / 255, $color->getGreen() / 255, $color->getBlue() / 255); } if ($color instanceof Cmyk) { return sprintf( - '%s %s %s %s', + self::CMYKCOLOR_FORMAT, $color->getCyan() / 100, $color->getMagenta() / 100, $color->getYellow() / 100, @@ -365,7 +382,7 @@ private function getColorString(ColorInterface $color) : string } if ($color instanceof Gray) { - return sprintf('%s', $color->getGray() / 100); + return sprintf("%1.".self::PRECISION."F", $color->getGray() / 100); } return $this->getColorString($color->toCmyk()); diff --git a/src/Renderer/Image/SvgImageBackEnd.php b/src/Renderer/Image/SvgImageBackEnd.php index 227afa7..c40ebcc 100644 --- a/src/Renderer/Image/SvgImageBackEnd.php +++ b/src/Renderer/Image/SvgImageBackEnd.php @@ -19,8 +19,15 @@ final class SvgImageBackEnd implements ImageBackEndInterface { private const PRECISION = 3; + private const S_SAFE = '%.' . self::PRECISION . 'F'; + private const SS_SAFE = self::S_SAFE.' '.self::S_SAFE; + private const SSS_SAFE = self::S_SAFE.' '.self::S_SAFE; private const SCALE_FORMAT = 'scale(%.' . self::PRECISION . 'F)'; private const TRANSLATE_FORMAT = 'translate(%.' . self::PRECISION . 'F,%.' . self::PRECISION . 'F)'; + private const MOVE_FORMAT = 'M'.self::SS_SAFE; + private const LINE_FORMAT = 'L'.self::SS_SAFE; + private const ARC_FORMAT = 'A'.self::SSS_SAFE.' %u %u '.self::SS_SAFE; + private const CURVE_FORMAT = 'C'.self::SSS_SAFE.' '.self::SSS_SAFE; private ?XMLWriter $xmlWriter; @@ -212,7 +219,7 @@ private function startPathElement(Path $path) : void switch (true) { case $op instanceof Move: $pathData[] = sprintf( - 'M%s %s', + self::MOVE_FORMAT, round($op->getX(), self::PRECISION), round($op->getY(), self::PRECISION) ); @@ -220,7 +227,7 @@ private function startPathElement(Path $path) : void case $op instanceof Line: $pathData[] = sprintf( - 'L%s %s', + self::LINE_FORMAT, round($op->getX(), self::PRECISION), round($op->getY(), self::PRECISION) ); @@ -228,7 +235,7 @@ private function startPathElement(Path $path) : void case $op instanceof EllipticArc: $pathData[] = sprintf( - 'A%s %s %s %u %u %s %s', + self::ARC_FORMAT, round($op->getXRadius(), self::PRECISION), round($op->getYRadius(), self::PRECISION), round($op->getXAxisAngle(), self::PRECISION), @@ -241,7 +248,7 @@ private function startPathElement(Path $path) : void case $op instanceof Curve: $pathData[] = sprintf( - 'C%s %s %s %s %s %s', + self::CURVE_FORMAT, round($op->getX1(), self::PRECISION), round($op->getY1(), self::PRECISION), round($op->getX2(), self::PRECISION),