mirror of
https://github.com/Intervention/image.git
synced 2025-08-27 07:44:30 +02:00
Implement FontWriter Modifier
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
namespace Intervention\Image\Drivers\Gd;
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
use Intervention\Image\Drivers\Abstract\AbstractFont;
|
use Intervention\Image\Drivers\Abstract\AbstractFont;
|
||||||
|
use Intervention\Image\Geometry\Point;
|
||||||
|
use Intervention\Image\Geometry\Polygon;
|
||||||
use Intervention\Image\Geometry\Size;
|
use Intervention\Image\Geometry\Size;
|
||||||
|
|
||||||
class Font extends AbstractFont
|
class Font extends AbstractFont
|
||||||
@@ -15,9 +17,9 @@ class Font extends AbstractFont
|
|||||||
/**
|
/**
|
||||||
* Calculate size of bounding box of current text
|
* Calculate size of bounding box of current text
|
||||||
*
|
*
|
||||||
* @return Size
|
* @return Polygon
|
||||||
*/
|
*/
|
||||||
public function getBoxSize(): Size
|
public function getBoxSize(): Polygon
|
||||||
{
|
{
|
||||||
if (!$this->hasFilename()) {
|
if (!$this->hasFilename()) {
|
||||||
// calculate box size from gd font
|
// calculate box size from gd font
|
||||||
@@ -27,18 +29,26 @@ class Font extends AbstractFont
|
|||||||
$box->setWidth($chars * $this->getGdFontWidth());
|
$box->setWidth($chars * $this->getGdFontWidth());
|
||||||
$box->setHeight($this->getGdFontHeight());
|
$box->setHeight($this->getGdFontHeight());
|
||||||
}
|
}
|
||||||
return $box;
|
return $box->toPolygon();
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate box size from font file
|
// calculate box size from font file with angle 0
|
||||||
$box = imageftbbox(
|
$box = imageftbbox(
|
||||||
$this->getSize(),
|
$this->getSize(),
|
||||||
$this->getAngle(),
|
0,
|
||||||
$this->getFilename(),
|
$this->getFilename(),
|
||||||
$this->getText()
|
$this->getText()
|
||||||
);
|
);
|
||||||
|
|
||||||
return new Size(abs($box[0] - $box[2]), abs($box[1] - $box[7]));
|
// build polygon from points
|
||||||
|
$polygon = new Polygon();
|
||||||
|
$polygon->addPoint(new Point($box[6], $box[7]));
|
||||||
|
$polygon->addPoint(new Point($box[4], $box[5]));
|
||||||
|
$polygon->addPoint(new Point($box[2], $box[3]));
|
||||||
|
$polygon->addPoint(new Point($box[0], $box[1]));
|
||||||
|
|
||||||
|
|
||||||
|
return $polygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGdFont(): int
|
public function getGdFont(): int
|
||||||
|
@@ -19,13 +19,12 @@ class TextWriter implements ModifierInterface
|
|||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$position = $this->getAlignedPosition();
|
$position = $this->getAlignedPosition();
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
if ($this->font->hasFilename()) {
|
if ($this->font->hasFilename()) {
|
||||||
imagettftext(
|
imagettftext(
|
||||||
$frame->getCore(),
|
$frame->getCore(),
|
||||||
$this->font->getSize(),
|
$this->font->getSize(),
|
||||||
$this->font->getAngle(),
|
$this->font->getAngle() * (-1),
|
||||||
$position->getX(),
|
$position->getX(),
|
||||||
$position->getY(),
|
$position->getY(),
|
||||||
$this->font->getColor()->toInt(),
|
$this->font->getColor()->toInt(),
|
||||||
@@ -47,34 +46,18 @@ class TextWriter implements ModifierInterface
|
|||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getAlignedPosition(): Point
|
public function getAlignedPosition(): Point
|
||||||
{
|
{
|
||||||
$position = $this->position;
|
$poly = $this->font->getBoxSize();
|
||||||
$box = $this->font->getBoxSize();
|
$poly->setPivotPoint($this->position);
|
||||||
|
|
||||||
// adjust x pos
|
$poly->align($this->font->getAlign());
|
||||||
switch ($this->font->getAlign()) {
|
$poly->valign($this->font->getValign());
|
||||||
case 'center':
|
|
||||||
$position->setX($position->getX() - round($box->getWidth() / 2));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'right':
|
if ($this->font->getAngle() != 0) {
|
||||||
$position->setX($position->getX() - $box->getWidth());
|
$poly->rotate($this->font->getAngle());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust y pos
|
return $poly->last();
|
||||||
switch ($this->font->getValign()) {
|
|
||||||
case 'top':
|
|
||||||
$position->setY($position->getY() + $box->getHeight());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'middle':
|
|
||||||
case 'center':
|
|
||||||
$position->setY($position->getY() + round($box->getHeight() / 2));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $position;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ use Imagick;
|
|||||||
use ImagickDraw;
|
use ImagickDraw;
|
||||||
use Intervention\Image\Drivers\Abstract\AbstractFont;
|
use Intervention\Image\Drivers\Abstract\AbstractFont;
|
||||||
use Intervention\Image\Exceptions\FontException;
|
use Intervention\Image\Exceptions\FontException;
|
||||||
|
use Intervention\Image\Geometry\Polygon;
|
||||||
use Intervention\Image\Geometry\Size;
|
use Intervention\Image\Geometry\Size;
|
||||||
|
|
||||||
class Font extends AbstractFont
|
class Font extends AbstractFont
|
||||||
@@ -13,7 +14,7 @@ class Font extends AbstractFont
|
|||||||
public function toImagickDraw(): ImagickDraw
|
public function toImagickDraw(): ImagickDraw
|
||||||
{
|
{
|
||||||
if (!$this->hasFilename()) {
|
if (!$this->hasFilename()) {
|
||||||
throw new FontException('No font file.');
|
throw new FontException('No font file specified.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$draw = new ImagickDraw();
|
$draw = new ImagickDraw();
|
||||||
@@ -50,14 +51,13 @@ class Font extends AbstractFont
|
|||||||
/**
|
/**
|
||||||
* Calculate box size of current font
|
* Calculate box size of current font
|
||||||
*
|
*
|
||||||
* @return Size
|
* @return Polygon
|
||||||
*/
|
*/
|
||||||
public function getBoxSize(): Size
|
public function getBoxSize(): Polygon
|
||||||
{
|
{
|
||||||
$foo = null;
|
|
||||||
// no text - no box size
|
// no text - no box size
|
||||||
if (mb_strlen($this->getText()) === 0) {
|
if (mb_strlen($this->getText()) === 0) {
|
||||||
return new Size(0, 0);
|
return (new Size(0, 0))->toPolygon();
|
||||||
}
|
}
|
||||||
|
|
||||||
$dimensions = (new Imagick())->queryFontMetrics(
|
$dimensions = (new Imagick())->queryFontMetrics(
|
||||||
@@ -65,9 +65,9 @@ class Font extends AbstractFont
|
|||||||
$this->getText()
|
$this->getText()
|
||||||
);
|
);
|
||||||
|
|
||||||
return new Size(
|
return (new Size(
|
||||||
intval(abs($dimensions['textWidth'])),
|
intval(round(abs($dimensions['boundingBox']['x1'] - $dimensions['boundingBox']['x2']))),
|
||||||
intval(abs($dimensions['textHeight']))
|
intval(round(abs($dimensions['boundingBox']['y1'] - $dimensions['boundingBox']['y2']))),
|
||||||
);
|
))->toPolygon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,15 +18,13 @@ class TextWriter implements ModifierInterface
|
|||||||
|
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
$draw = $this->font->toImagickDraw();
|
|
||||||
$position = $this->getAlignedPosition();
|
$position = $this->getAlignedPosition();
|
||||||
|
|
||||||
foreach ($image as $frame) {
|
foreach ($image as $frame) {
|
||||||
$frame->getCore()->annotateImage(
|
$frame->getCore()->annotateImage(
|
||||||
$draw,
|
$this->font->toImagickDraw(),
|
||||||
$position->getX(),
|
$position->getX(),
|
||||||
$position->getY(),
|
$position->getY(),
|
||||||
$this->font->getAngle(),
|
$this->font->getAngle() * (-1),
|
||||||
$this->font->getText()
|
$this->font->getText()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -42,12 +40,12 @@ class TextWriter implements ModifierInterface
|
|||||||
// adjust y pos
|
// adjust y pos
|
||||||
switch ($this->font->getValign()) {
|
switch ($this->font->getValign()) {
|
||||||
case 'top':
|
case 'top':
|
||||||
$position->setY($position->getY() + $box->getHeight());
|
$position->setY($position->getY() + $box->height());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'middle':
|
case 'middle':
|
||||||
case 'center':
|
case 'center':
|
||||||
$position->setY($position->getY() + round($box->getHeight() / 2));
|
$position->setY(intval($position->getY() + round($box->height() / 2)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -58,7 +58,7 @@ class Point implements PointInterface
|
|||||||
/**
|
/**
|
||||||
* Move X coordinate
|
* Move X coordinate
|
||||||
*
|
*
|
||||||
* @param integer $x
|
* @param integer $value
|
||||||
*/
|
*/
|
||||||
public function moveX(int $value): self
|
public function moveX(int $value): self
|
||||||
{
|
{
|
||||||
@@ -70,7 +70,7 @@ class Point implements PointInterface
|
|||||||
/**
|
/**
|
||||||
* Move Y coordinate
|
* Move Y coordinate
|
||||||
*
|
*
|
||||||
* @param integer $y
|
* @param integer $value
|
||||||
*/
|
*/
|
||||||
public function moveY(int $value): self
|
public function moveY(int $value): self
|
||||||
{
|
{
|
||||||
@@ -79,6 +79,11 @@ class Point implements PointInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function move(int $x, int $y): self
|
||||||
|
{
|
||||||
|
return $this->moveX($x)->moveY($y);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets both X and Y coordinate
|
* Sets both X and Y coordinate
|
||||||
*
|
*
|
||||||
@@ -107,8 +112,8 @@ class Point implements PointInterface
|
|||||||
$cos = round(cos(deg2rad($angle)), 6);
|
$cos = round(cos(deg2rad($angle)), 6);
|
||||||
|
|
||||||
return $this->setPosition(
|
return $this->setPosition(
|
||||||
$cos * ($this->x - $pivot->x) - $sin * ($this->y - $pivot->y) + $pivot->x,
|
intval($cos * ($this->x - $pivot->x) - $sin * ($this->y - $pivot->y) + $pivot->x),
|
||||||
$sin * ($this->x - $pivot->x) + $cos * ($this->y - $pivot->y) + $pivot->y
|
intval($sin * ($this->x - $pivot->x) + $cos * ($this->y - $pivot->y) + $pivot->y)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
455
src/Geometry/Polygon.php
Normal file
455
src/Geometry/Polygon.php
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Geometry;
|
||||||
|
|
||||||
|
use ArrayAccess;
|
||||||
|
use Countable;
|
||||||
|
|
||||||
|
class Polygon implements Countable, ArrayAccess
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected array $points = [],
|
||||||
|
protected ?Point $pivot = null
|
||||||
|
) {
|
||||||
|
$this->pivot = $pivot ? $pivot : new Point();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return current pivot point
|
||||||
|
*
|
||||||
|
* @return Point
|
||||||
|
*/
|
||||||
|
public function getPivotPoint(): Point
|
||||||
|
{
|
||||||
|
return $this->pivot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change pivot point to given point
|
||||||
|
*
|
||||||
|
* @param Point $pivot
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function setPivotPoint(Point $pivot): self
|
||||||
|
{
|
||||||
|
$this->pivot = $pivot;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return first point of polygon
|
||||||
|
*
|
||||||
|
* @return ?Point
|
||||||
|
*/
|
||||||
|
public function first(): ?Point
|
||||||
|
{
|
||||||
|
if ($point = reset($this->points)) {
|
||||||
|
return $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return last point of polygon
|
||||||
|
*
|
||||||
|
* @return ?Point
|
||||||
|
*/
|
||||||
|
public function last(): ?Point
|
||||||
|
{
|
||||||
|
if ($point = end($this->points)) {
|
||||||
|
return $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return polygon's point count
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count(): int
|
||||||
|
{
|
||||||
|
return count($this->points);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if point exists at given offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset): bool
|
||||||
|
{
|
||||||
|
return array_key_exists($offset, $this->points);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return point at given offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
* @return Point
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
return $this->points[$offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set point at given offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
* @param Point $value
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function offsetSet($offset, $value): void
|
||||||
|
{
|
||||||
|
$this->points[$offset] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unset offset at given offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function offsetUnset($offset): void
|
||||||
|
{
|
||||||
|
unset($this->points[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add given point to polygon
|
||||||
|
*
|
||||||
|
* @param Point $point
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function addPoint(Point $point): self
|
||||||
|
{
|
||||||
|
$this->points[] = $point;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate total horizontal span of polygon
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function width(): int
|
||||||
|
{
|
||||||
|
return abs($this->getMostLeftPoint()->getX() - $this->getMostRightPoint()->getX());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate total vertical span of polygon
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function height(): int
|
||||||
|
{
|
||||||
|
return abs($this->getMostBottomPoint()->getY() - $this->getMostTopPoint()->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return most left point of all points in polygon
|
||||||
|
*
|
||||||
|
* @return Point
|
||||||
|
*/
|
||||||
|
public function getMostLeftPoint(): Point
|
||||||
|
{
|
||||||
|
$points = [];
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$points[] = $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($points, function ($a, $b) {
|
||||||
|
if ($a->getX() === $b->getX()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ($a->getX() < $b->getX()) ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $points[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return most right point in polygon
|
||||||
|
*
|
||||||
|
* @return Point
|
||||||
|
*/
|
||||||
|
public function getMostRightPoint(): Point
|
||||||
|
{
|
||||||
|
$points = [];
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$points[] = $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($points, function ($a, $b) {
|
||||||
|
if ($a->getX() === $b->getX()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ($a->getX() > $b->getX()) ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $points[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return most top point in polygon
|
||||||
|
*
|
||||||
|
* @return Point
|
||||||
|
*/
|
||||||
|
public function getMostTopPoint(): Point
|
||||||
|
{
|
||||||
|
$points = [];
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$points[] = $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($points, function ($a, $b) {
|
||||||
|
if ($a->getY() === $b->getY()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ($a->getY() > $b->getY()) ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $points[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return most bottom point in polygon
|
||||||
|
*
|
||||||
|
* @return Point
|
||||||
|
*/
|
||||||
|
public function getMostBottomPoint(): Point
|
||||||
|
{
|
||||||
|
$points = [];
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$points[] = $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($points, function ($a, $b) {
|
||||||
|
if ($a->getY() === $b->getY()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ($a->getY() < $b->getY()) ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $points[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and return point in absolute center of the polygon
|
||||||
|
*
|
||||||
|
* @return Point
|
||||||
|
*/
|
||||||
|
public function getCenterPoint(): Point
|
||||||
|
{
|
||||||
|
return new Point(
|
||||||
|
$this->getMostRightPoint()->getX() - (intval(round($this->width() / 2))),
|
||||||
|
$this->getMostTopPoint()->getY() - (intval(round($this->height() / 2)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Align pivot point to given horizontal position
|
||||||
|
*
|
||||||
|
* @param string $position
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function alignPivot(string $position): self
|
||||||
|
{
|
||||||
|
switch (strtolower($position)) {
|
||||||
|
case 'center':
|
||||||
|
$this->pivot->setX(
|
||||||
|
intval(($this->getMostRightPoint()->getX() + $this->getMostLeftPoint()->getX()) / 2)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'right':
|
||||||
|
$this->pivot->setX(
|
||||||
|
$this->getMostRightPoint()->getX()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'left':
|
||||||
|
$this->pivot->setX(
|
||||||
|
$this->getMostLeftPoint()->getX()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Align pivot point to given vertical position
|
||||||
|
*
|
||||||
|
* @param string $position
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function valignPivot(string $position): self
|
||||||
|
{
|
||||||
|
switch (strtolower($position)) {
|
||||||
|
case 'center':
|
||||||
|
case 'middle':
|
||||||
|
$this->pivot->setY(
|
||||||
|
intval(($this->getMostTopPoint()->getY() + $this->getMostBottomPoint()->getY()) / 2)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'top':
|
||||||
|
$this->pivot->setY(
|
||||||
|
$this->getMostTopPoint()->getY()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'bottom':
|
||||||
|
$this->pivot->setY(
|
||||||
|
$this->getMostBottomPoint()->getY()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Align all points of polygon horizontally to given position around pivot point
|
||||||
|
*
|
||||||
|
* @param string $position
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function align(string $position): self
|
||||||
|
{
|
||||||
|
switch (strtolower($position)) {
|
||||||
|
case 'center':
|
||||||
|
case 'middle':
|
||||||
|
$diff = ($this->getCenterPoint()->getX() - $this->pivot->getX());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'right':
|
||||||
|
$diff = ($this->getMostRightPoint()->getX() - $this->pivot->getX());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case 'left':
|
||||||
|
$diff = ($this->getMostLeftPoint()->getX() - $this->pivot->getX());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$point->setX($point->getX() - $diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Align all points of polygon vertically to given position around pivot point
|
||||||
|
*
|
||||||
|
* @param string $position
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function valign(string $position): self
|
||||||
|
{
|
||||||
|
switch (strtolower($position)) {
|
||||||
|
case 'center':
|
||||||
|
case 'middle':
|
||||||
|
$diff = ($this->getCenterPoint()->getY() - $this->pivot->getY());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'top':
|
||||||
|
$diff = ($this->getMostTopPoint()->getY() - $this->pivot->getY()) - $this->height();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case 'bottom':
|
||||||
|
$diff = ($this->getMostBottomPoint()->getY() - $this->pivot->getY()) + $this->height();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$point->setY($point->getY() - $diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate points of polygon around pivot point with given angle
|
||||||
|
*
|
||||||
|
* @param float $angle
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function rotate(float $angle): self
|
||||||
|
{
|
||||||
|
$sin = sin(deg2rad($angle));
|
||||||
|
$cos = cos(deg2rad($angle));
|
||||||
|
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
// translate point to pivot
|
||||||
|
$point->setX($point->getX() - $this->pivot->getX());
|
||||||
|
$point->setY($point->getY() - $this->pivot->getY());
|
||||||
|
|
||||||
|
// rotate point
|
||||||
|
$x = $point->getX() * $cos - $point->getY() * $sin;
|
||||||
|
$y = $point->getX() * $sin + $point->getY() * $cos;
|
||||||
|
|
||||||
|
// translate point back
|
||||||
|
$point->setX($x + $this->pivot->getX());
|
||||||
|
$point->setY($y + $this->pivot->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move all points by given amount on the x-axis
|
||||||
|
*
|
||||||
|
* @param int $amount
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function movePointsX(int $amount): self
|
||||||
|
{
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$point->moveX($amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move all points by given amount on the y-axis
|
||||||
|
*
|
||||||
|
* @param int $amount
|
||||||
|
* @return Polygon
|
||||||
|
*/
|
||||||
|
public function movePointsY(int $amount): self
|
||||||
|
{
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$point->moveY($amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return array of all x/y values of all points of polygon
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
$coordinates = [];
|
||||||
|
foreach ($this->points as $point) {
|
||||||
|
$coordinates[] = $point->getX();
|
||||||
|
$coordinates[] = $point->getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $coordinates;
|
||||||
|
}
|
||||||
|
}
|
@@ -209,6 +209,30 @@ class Size implements SizeInterface
|
|||||||
return new Point($x, $y);
|
return new Point($x, $y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function toPolygon(): Polygon
|
||||||
|
{
|
||||||
|
$polygon = new Polygon([
|
||||||
|
$this->pivot // top/left
|
||||||
|
], $this->pivot);
|
||||||
|
|
||||||
|
// top/right
|
||||||
|
$polygon->addPoint(
|
||||||
|
new Point($this->pivot->getX() + $this->getWidth(), $this->pivot->getY())
|
||||||
|
);
|
||||||
|
|
||||||
|
// bottom/right
|
||||||
|
$polygon->addPoint(
|
||||||
|
new Point($this->pivot->getX() + $this->getWidth(), $this->pivot->getY() - $this->getHeight())
|
||||||
|
);
|
||||||
|
|
||||||
|
// bottom/left
|
||||||
|
$polygon->addPoint(
|
||||||
|
new Point($this->pivot->getX(), $this->pivot->getY() - $this->getHeight())
|
||||||
|
);
|
||||||
|
|
||||||
|
return $polygon;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getResizer(?int $width = null, ?int $height = null): Resizer
|
protected function getResizer(?int $width = null, ?int $height = null): Resizer
|
||||||
{
|
{
|
||||||
return new Resizer($width, $height);
|
return new Resizer($width, $height);
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Interfaces;
|
namespace Intervention\Image\Interfaces;
|
||||||
|
|
||||||
use Intervention\Image\Geometry\Size;
|
use Intervention\Image\Geometry\Polygon;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
|
||||||
interface FontInterface
|
interface FontInterface
|
||||||
@@ -19,5 +19,5 @@ interface FontInterface
|
|||||||
public function hasFilename(): bool;
|
public function hasFilename(): bool;
|
||||||
public function align(string $align): self;
|
public function align(string $align): self;
|
||||||
public function getAlign(): string;
|
public function getAlign(): string;
|
||||||
public function getBoxSize(): Size;
|
public function getBoxSize(): Polygon;
|
||||||
}
|
}
|
||||||
|
397
tests/Geometry/PolygonTest.php
Normal file
397
tests/Geometry/PolygonTest.php
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intervention\Image\Tests\Geometry;
|
||||||
|
|
||||||
|
use Intervention\Image\Geometry\{Point, Polygon};
|
||||||
|
use Intervention\Image\Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Intervention\Image\Geometry\Polygon
|
||||||
|
*/
|
||||||
|
class PolygonTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testConstructor(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([]);
|
||||||
|
$this->assertInstanceOf(Polygon::class, $poly);
|
||||||
|
$this->assertEquals(0, $poly->count());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCount(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([new Point(), new Point()]);
|
||||||
|
$this->assertEquals(2, $poly->count());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArrayAccess(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([new Point(), new Point()]);
|
||||||
|
$this->assertInstanceOf(Point::class, $poly[0]);
|
||||||
|
$this->assertInstanceOf(Point::class, $poly[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddPoint(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([new Point(), new Point()]);
|
||||||
|
$this->assertEquals(2, $poly->count());
|
||||||
|
$result = $poly->addPoint(new Point());
|
||||||
|
$this->assertEquals(3, $poly->count());
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetCenterPoint(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(20, 0),
|
||||||
|
new Point(20, -20),
|
||||||
|
new Point(0, -20),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = $poly->getCenterPoint();
|
||||||
|
$this->assertEquals(10, $result->getX());
|
||||||
|
$this->assertEquals(-10, $result->getY());
|
||||||
|
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(0, -200),
|
||||||
|
], new Point(0, 0));
|
||||||
|
|
||||||
|
$result = $poly->getCenterPoint();
|
||||||
|
$this->assertEquals(150, $result->getX());
|
||||||
|
$this->assertEquals(-100, $result->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWidth(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(12, 45),
|
||||||
|
new Point(-23, -49),
|
||||||
|
new Point(3, 566),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals($poly->width(), 35);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHeight(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(12, 45),
|
||||||
|
new Point(-23, -49),
|
||||||
|
new Point(3, 566),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(615, $poly->height());
|
||||||
|
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(250, 207),
|
||||||
|
new Point(473, 207),
|
||||||
|
new Point(473, 250),
|
||||||
|
new Point(250, 250),
|
||||||
|
], new Point(250, 250));
|
||||||
|
|
||||||
|
$this->assertEquals(43, $poly->height());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFirst(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(12, 45),
|
||||||
|
new Point(-23, -49),
|
||||||
|
new Point(3, 566),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(12, $poly->first()->getX());
|
||||||
|
$this->assertEquals(45, $poly->first()->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLast(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(12, 45),
|
||||||
|
new Point(-23, -49),
|
||||||
|
new Point(3, 566),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(3, $poly->last()->getX());
|
||||||
|
$this->assertEquals(566, $poly->last()->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetPivotPoint(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon();
|
||||||
|
$this->assertInstanceOf(Point::class, $poly->getPivotPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAlignPivot(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(12, 45),
|
||||||
|
new Point(-24, -49),
|
||||||
|
new Point(3, 566),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $poly->getPivotPoint()->getX());
|
||||||
|
$this->assertEquals(0, $poly->getPivotPoint()->getY());
|
||||||
|
|
||||||
|
$result = $poly->alignPivot('center');
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
|
||||||
|
$this->assertEquals(-6, $result->getPivotPoint()->getX());
|
||||||
|
$this->assertEquals(0, $result->getPivotPoint()->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValignPivot(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(12, 45),
|
||||||
|
new Point(-24, -50),
|
||||||
|
new Point(3, 566),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $poly->getPivotPoint()->getX());
|
||||||
|
$this->assertEquals(0, $poly->getPivotPoint()->getY());
|
||||||
|
|
||||||
|
$result = $poly->valignPivot('middle');
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $result->getPivotPoint()->getX());
|
||||||
|
$this->assertEquals(258, $result->getPivotPoint()->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetMostLeftPoint(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(-32, -200),
|
||||||
|
], new Point(0, 0));
|
||||||
|
|
||||||
|
$result = $poly->getMostLeftPoint();
|
||||||
|
$this->assertEquals(-32, $result->getX());
|
||||||
|
$this->assertEquals(-200, $result->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetMostRightPoint(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(350, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(-32, -200),
|
||||||
|
], new Point(0, 0));
|
||||||
|
|
||||||
|
$result = $poly->getMostRightPoint();
|
||||||
|
$this->assertEquals(350, $result->getX());
|
||||||
|
$this->assertEquals(0, $result->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetMostTopPoint(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 100),
|
||||||
|
new Point(350, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(-32, 200),
|
||||||
|
], new Point(0, 0));
|
||||||
|
|
||||||
|
$result = $poly->getMostTopPoint();
|
||||||
|
$this->assertEquals(-32, $result->getX());
|
||||||
|
$this->assertEquals(200, $result->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetMostBottomPoint(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 100),
|
||||||
|
new Point(350, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(-32, 200),
|
||||||
|
], new Point(0, 0));
|
||||||
|
|
||||||
|
$result = $poly->getMostBottomPoint();
|
||||||
|
$this->assertEquals(300, $result->getX());
|
||||||
|
$this->assertEquals(-200, $result->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAlignCenter(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(0, -200),
|
||||||
|
], new Point(0, 0));
|
||||||
|
|
||||||
|
$result = $poly->align('center');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(-150, $result[0]->getX());
|
||||||
|
$this->assertEquals(0, $result[0]->getY());
|
||||||
|
$this->assertEquals(150, $result[1]->getX());
|
||||||
|
$this->assertEquals(0, $result[1]->getY());
|
||||||
|
$this->assertEquals(150, $result[2]->getX());
|
||||||
|
$this->assertEquals(-200, $result[2]->getY());
|
||||||
|
$this->assertEquals(-150, $result[3]->getX());
|
||||||
|
$this->assertEquals(-200, $result[3]->getY());
|
||||||
|
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(0, -200),
|
||||||
|
], new Point(-1000, -1000));
|
||||||
|
|
||||||
|
$result = $poly->align('center');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(-1150, $result[0]->getX());
|
||||||
|
$this->assertEquals(0, $result[0]->getY());
|
||||||
|
$this->assertEquals(-850, $result[1]->getX());
|
||||||
|
$this->assertEquals(0, $result[1]->getY());
|
||||||
|
$this->assertEquals(-850, $result[2]->getX());
|
||||||
|
$this->assertEquals(-200, $result[2]->getY());
|
||||||
|
$this->assertEquals(-1150, $result[3]->getX());
|
||||||
|
$this->assertEquals(-200, $result[3]->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAlignLeft(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(0, -200),
|
||||||
|
], new Point(100, 100));
|
||||||
|
|
||||||
|
$result = $poly->align('left');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(100, $result[0]->getX());
|
||||||
|
$this->assertEquals(0, $result[0]->getY());
|
||||||
|
$this->assertEquals(400, $result[1]->getX());
|
||||||
|
$this->assertEquals(0, $result[1]->getY());
|
||||||
|
$this->assertEquals(400, $result[2]->getX());
|
||||||
|
$this->assertEquals(-200, $result[2]->getY());
|
||||||
|
$this->assertEquals(100, $result[3]->getX());
|
||||||
|
$this->assertEquals(-200, $result[3]->getY());
|
||||||
|
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(0, -200),
|
||||||
|
], new Point(-1000, -1000));
|
||||||
|
|
||||||
|
$result = $poly->align('left');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(-1000, $result[0]->getX());
|
||||||
|
$this->assertEquals(0, $result[0]->getY());
|
||||||
|
$this->assertEquals(-700, $result[1]->getX());
|
||||||
|
$this->assertEquals(0, $result[1]->getY());
|
||||||
|
$this->assertEquals(-700, $result[2]->getX());
|
||||||
|
$this->assertEquals(-200, $result[2]->getY());
|
||||||
|
$this->assertEquals(-1000, $result[3]->getX());
|
||||||
|
$this->assertEquals(-200, $result[3]->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAlignRight(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(0, -200),
|
||||||
|
], new Point(100, 100));
|
||||||
|
|
||||||
|
$result = $poly->align('right');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(-200, $result[0]->getX());
|
||||||
|
$this->assertEquals(0, $result[0]->getY());
|
||||||
|
$this->assertEquals(100, $result[1]->getX());
|
||||||
|
$this->assertEquals(0, $result[1]->getY());
|
||||||
|
$this->assertEquals(100, $result[2]->getX());
|
||||||
|
$this->assertEquals(-200, $result[2]->getY());
|
||||||
|
$this->assertEquals(-200, $result[3]->getX());
|
||||||
|
$this->assertEquals(-200, $result[3]->getY());
|
||||||
|
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(300, 0),
|
||||||
|
new Point(300, -200),
|
||||||
|
new Point(0, -200),
|
||||||
|
], new Point(-1000, -1000));
|
||||||
|
|
||||||
|
$result = $poly->align('right');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(-1300, $result[0]->getX());
|
||||||
|
$this->assertEquals(0, $result[0]->getY());
|
||||||
|
$this->assertEquals(-1000, $result[1]->getX());
|
||||||
|
$this->assertEquals(0, $result[1]->getY());
|
||||||
|
$this->assertEquals(-1000, $result[2]->getX());
|
||||||
|
$this->assertEquals(-200, $result[2]->getY());
|
||||||
|
$this->assertEquals(-1300, $result[3]->getX());
|
||||||
|
$this->assertEquals(-200, $result[3]->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testValignMiddle(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(-21, -22),
|
||||||
|
new Point(91, -135),
|
||||||
|
new Point(113, -113),
|
||||||
|
new Point(0, 0),
|
||||||
|
], new Point(250, 250));
|
||||||
|
|
||||||
|
$result = $poly->valign('middle');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(-21, $result[0]->getX());
|
||||||
|
$this->assertEquals(296, $result[0]->getY());
|
||||||
|
$this->assertEquals(91, $result[1]->getX());
|
||||||
|
$this->assertEquals(183, $result[1]->getY());
|
||||||
|
$this->assertEquals(113, $result[2]->getX());
|
||||||
|
$this->assertEquals(205, $result[2]->getY());
|
||||||
|
$this->assertEquals(0, $result[3]->getX());
|
||||||
|
$this->assertEquals(318, $result[3]->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRotate(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(50, 0),
|
||||||
|
new Point(50, -50),
|
||||||
|
new Point(0, -50),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = $poly->rotate(45);
|
||||||
|
$this->assertInstanceOf(Polygon::class, $result);
|
||||||
|
$this->assertEquals(0, $result[0]->getX());
|
||||||
|
$this->assertEquals(0, $result[0]->getY());
|
||||||
|
$this->assertEquals(35, $result[1]->getX());
|
||||||
|
$this->assertEquals(35, $result[1]->getY());
|
||||||
|
$this->assertEquals(70, $result[2]->getX());
|
||||||
|
$this->assertEquals(0, $result[2]->getY());
|
||||||
|
$this->assertEquals(35, $result[3]->getX());
|
||||||
|
$this->assertEquals(-35, $result[3]->getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testToArray(): void
|
||||||
|
{
|
||||||
|
$poly = new Polygon([
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point(50, 0),
|
||||||
|
new Point(50, -50),
|
||||||
|
new Point(0, -50),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals([0, 0, 50, 0, 50, -50, 0, -50], $poly->toArray());
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Tests\Geometry;
|
namespace Intervention\Image\Tests\Geometry;
|
||||||
|
|
||||||
use Intervention\Image\Geometry\{Point, Size,};
|
use Intervention\Image\Geometry\{Point, Polygon, Size,};
|
||||||
use Intervention\Image\Tests\TestCase;
|
use Intervention\Image\Tests\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -254,6 +254,22 @@ class SizeTest extends TestCase
|
|||||||
$this->assertEquals(50, $pos->getY());
|
$this->assertEquals(50, $pos->getY());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testToPolygon(): void
|
||||||
|
{
|
||||||
|
$size = new Size(300, 200);
|
||||||
|
$poly = $size->toPolygon();
|
||||||
|
$this->assertInstanceOf(Polygon::class, $poly);
|
||||||
|
$this->assertCount(4, $poly);
|
||||||
|
$this->assertEquals(0, $poly[0]->getX());
|
||||||
|
$this->assertEquals(0, $poly[0]->getY());
|
||||||
|
$this->assertEquals(300, $poly[1]->getX());
|
||||||
|
$this->assertEquals(0, $poly[1]->getY());
|
||||||
|
$this->assertEquals(300, $poly[2]->getX());
|
||||||
|
$this->assertEquals(-200, $poly[2]->getY());
|
||||||
|
$this->assertEquals(0, $poly[3]->getX());
|
||||||
|
$this->assertEquals(-200, $poly[3]->getY());
|
||||||
|
}
|
||||||
|
|
||||||
public function testResize(): void
|
public function testResize(): void
|
||||||
{
|
{
|
||||||
$size = new Size(300, 200);
|
$size = new Size(300, 200);
|
||||||
|
Reference in New Issue
Block a user