From 9ac8e765c2793b9246d8836d4beccb00405a82b1 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Sun, 7 Nov 2021 11:37:42 +0000 Subject: [PATCH] Geometry refactoring --- src/Geometry/Resizer.php | 114 ++++++++++++++++++--------------- src/Geometry/Size.php | 7 ++ tests/Geometry/ResizerTest.php | 14 ++-- tests/Geometry/SizeTest.php | 43 +++++++++++++ 4 files changed, 119 insertions(+), 59 deletions(-) diff --git a/src/Geometry/Resizer.php b/src/Geometry/Resizer.php index d804194c..6132d58c 100644 --- a/src/Geometry/Resizer.php +++ b/src/Geometry/Resizer.php @@ -11,7 +11,7 @@ class Resizer * * @var SizeInterface */ - protected $size; + protected $original; /** * Target size @@ -20,20 +20,20 @@ class Resizer */ protected $target; - public function __construct(SizeInterface $size) + /** + * Create new instance + * + * @param SizeInterface $size + */ + public function __construct(SizeInterface $original) { - $this->size = $size; + $this->original = $original; $this->target = new Size(0, 0); } - public static function fromSize(SizeInterface $size): self + protected function copyOriginal(): SizeInterface { - return new self($size); - } - - public function getSize(): SizeInterface - { - return $this->size; + return new Size($this->original->getWidth(), $this->original->getHeight()); } protected function hasTargetWidth(): bool @@ -81,14 +81,32 @@ class Resizer public function setTargetSize(SizeInterface $size): self { - $this->target = $size; + $this->target = new Size($size->getWidth(), $size->getHeight()); return $this; } + protected function getProportionalWidth(): int + { + if (! $this->hasTargetHeight()) { + return $this->original->getWidth(); + } + + return (int) round($this->target->getHeight() * $this->original->getAspectRatio()); + } + + protected function getProportionalHeight(): int + { + if (! $this->hasTargetWidth()) { + return $this->original->getHeight(); + } + + return (int) round($this->target->getWidth() / $this->original->getAspectRatio()); + } + public function resize(): SizeInterface { - $resized = clone $this->size; + $resized = $this->copyOriginal(); if ($this->hasTargetWidth()) { $resized->setWidth($this->target->getWidth()); @@ -103,92 +121,82 @@ class Resizer public function resizeDown(): SizeInterface { + $resized = $this->copyOriginal(); + if ($this->hasTargetWidth()) { - $this->target->setWidth( - min($this->target->getWidth(), $this->size->getWidth()) + $resized->setWidth( + min($this->target->getWidth(), $this->original->getWidth()) ); } if ($this->hasTargetHeight()) { - $this->target->setHeight( - min($this->target->getHeight(), $this->size->getHeight()) + $resized->setHeight( + min($this->target->getHeight(), $this->original->getHeight()) ); } - return $this->resize(); + return $resized; } public function scale(): SizeInterface { + $resized = $this->copyOriginal(); + if ($this->hasTargetWidth() && $this->hasTargetHeight()) { - $this->target->setWidth(min( + $resized->setWidth(min( $this->getProportionalWidth(), $this->target->getWidth() )); - $this->target->setHeight(min( + $resized->setHeight(min( $this->getProportionalHeight(), $this->target->getHeight() )); } elseif ($this->hasTargetWidth()) { - $this->target->setHeight($this->getProportionalHeight()); + $resized->setWidth($this->target->getWidth()); + $resized->setHeight($this->getProportionalHeight()); } elseif ($this->hasTargetHeight()) { - $this->target->setWidth($this->getProportionalWidth()); + $resized->setWidth($this->getProportionalWidth()); + $resized->setHeight($this->target->getHeight()); } - return $this->resize(); + return $resized; } public function scaleDown(): SizeInterface { + $resized = $this->copyOriginal(); + if ($this->hasTargetWidth() && $this->hasTargetHeight()) { - $this->target->setWidth(min( + $resized->setWidth(min( $this->getProportionalWidth(), $this->target->getWidth(), - $this->size->getWidth() + $this->original->getWidth() )); - $this->target->setHeight(min( + $resized->setHeight(min( $this->getProportionalHeight(), $this->target->getHeight(), - $this->size->getHeight() + $this->original->getHeight() )); } elseif ($this->hasTargetWidth()) { - $this->target->setWidth(min( + $resized->setWidth(min( $this->target->getWidth(), - $this->size->getWidth() + $this->original->getWidth() )); - $this->target->setHeight(min( + $resized->setHeight(min( $this->getProportionalHeight(), - $this->size->getHeight() + $this->original->getHeight() )); } elseif ($this->hasTargetHeight()) { - $this->target->setWidth(min( + $resized->setWidth(min( $this->getProportionalWidth(), - $this->size->getWidth() + $this->original->getWidth() )); - $this->target->setHeight(min( + $resized->setHeight(min( $this->target->getHeight(), - $this->size->getHeight() + $this->original->getHeight() )); } - return $this->resize(); - } - - protected function getProportionalWidth(): int - { - if (! $this->hasTargetHeight()) { - return $this->size->getWidth(); - } - - return (int) round($this->target->getHeight() * $this->size->getAspectRatio()); - } - - protected function getProportionalHeight(): int - { - if (! $this->hasTargetWidth()) { - return $this->size->getHeight(); - } - - return (int) round($this->target->getWidth() / $this->size->getAspectRatio()); + return $resized; } } diff --git a/src/Geometry/Size.php b/src/Geometry/Size.php index c1adef14..70aee3e1 100644 --- a/src/Geometry/Size.php +++ b/src/Geometry/Size.php @@ -38,6 +38,13 @@ class Size implements SizeInterface return $this->pivot; } + public function setPivot(PointInterface $pivot): self + { + $this->pivot = $pivot; + + return $this; + } + public function setWidth(int $width): SizeInterface { $this->width = $width; diff --git a/tests/Geometry/ResizerTest.php b/tests/Geometry/ResizerTest.php index 5395aaff..9c84ee91 100644 --- a/tests/Geometry/ResizerTest.php +++ b/tests/Geometry/ResizerTest.php @@ -8,6 +8,13 @@ use PHPUnit\Framework\TestCase; class ResizerTest extends TestCase { + public function testConstructor(): void + { + $size = new Size(300, 200); + $resizer = new Resizer($size); + $this->assertInstanceOf(Resizer::class, $resizer); + } + public function testSetTargetSizeByArray() { $resizer = new Resizer(new Size(300, 200)); @@ -63,22 +70,16 @@ class ResizerTest extends TestCase $resizer = new Resizer($size); $resizer->width(150); $result = $resizer->resize(); - $original = $resizer->getSize(); $this->assertEquals(150, $result->getWidth()); $this->assertEquals(200, $result->getHeight()); - $this->assertEquals(300, $original->getWidth()); - $this->assertEquals(200, $original->getHeight()); $size = new Size(300, 200); $resizer = new Resizer($size); $resizer->width(20); $resizer->height(10); $result = $resizer->resize(); - $original = $resizer->getSize(); $this->assertEquals(20, $result->getWidth()); $this->assertEquals(10, $result->getHeight()); - $this->assertEquals(300, $original->getWidth()); - $this->assertEquals(200, $original->getHeight()); } public function testResizeDown() @@ -367,4 +368,5 @@ class ResizerTest extends TestCase $this->assertEquals(13, $result->getWidth()); $this->assertEquals(10, $result->getHeight()); } + } diff --git a/tests/Geometry/SizeTest.php b/tests/Geometry/SizeTest.php index 47090238..37ab296a 100644 --- a/tests/Geometry/SizeTest.php +++ b/tests/Geometry/SizeTest.php @@ -143,4 +143,47 @@ class SizeTest extends TestCase $this->assertInstanceOf(Size::class, $result); } + + public function testRelativePosition(): void + { + $container = new Size(800, 600); + $input = new Size(200, 100); + $container->align('top-left'); + $input->align('top-left'); + $pos = $container->relativePosition($input); + $this->assertEquals(0, $pos->getX()); + $this->assertEquals(0, $pos->getY()); + + $container = new Size(800, 600); + $input = new Size(200, 100); + $container->align('center'); + $input->align('top-left'); + $pos = $container->relativePosition($input); + $this->assertEquals(400, $pos->getX()); + $this->assertEquals(300, $pos->getY()); + + $container = new Size(800, 600); + $input = new Size(200, 100); + $container->align('bottom-right'); + $input->align('top-right'); + $pos = $container->relativePosition($input); + $this->assertEquals(600, $pos->getX()); + $this->assertEquals(600, $pos->getY()); + + $container = new Size(800, 600); + $input = new Size(200, 100); + $container->align('center'); + $input->align('center'); + $pos = $container->relativePosition($input); + $this->assertEquals(300, $pos->getX()); + $this->assertEquals(250, $pos->getY()); + + $container = new Size(100, 200); + $input = new Size(100, 100); + $container->align('center'); + $input->align('center'); + $pos = $container->relativePosition($input); + $this->assertEquals(0, $pos->getX()); + $this->assertEquals(50, $pos->getY()); + } }