Skip to content

Commit

Permalink
Image: better processing and checking dimensions in strings [Closes #217
Browse files Browse the repository at this point in the history
]
  • Loading branch information
dg committed Nov 5, 2020
1 parent d6c4bb6 commit 29b8034
Showing 1 changed file with 36 additions and 20 deletions.
56 changes: 36 additions & 20 deletions src/Utils/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,22 +320,22 @@ public function resize($width, $height, $flags = self::FIT)
*/
public static function calculateSize($srcWidth, $srcHeight, $newWidth, $newHeight, $flags = self::FIT)
{
if (is_string($newWidth) && substr($newWidth, -1) === '%') {
$newWidth = (int) round($srcWidth / 100 * abs(substr($newWidth, 0, -1)));
if ($newWidth !== null && self::isPercent($newWidth)) {
$newWidth = (int) round($srcWidth / 100 * abs($newWidth));
$percents = true;
} else {
$newWidth = (int) abs($newWidth);
$newWidth = abs($newWidth);
}

if (is_string($newHeight) && substr($newHeight, -1) === '%') {
$newHeight = (int) round($srcHeight / 100 * abs(substr($newHeight, 0, -1)));
if ($newHeight !== null && self::isPercent($newHeight)) {
$newHeight = (int) round($srcHeight / 100 * abs($newHeight));
$flags |= empty($percents) ? 0 : self::STRETCH;
} else {
$newHeight = (int) abs($newHeight);
$newHeight = abs($newHeight);
}

if ($flags & self::STRETCH) { // non-proportional
if (empty($newWidth) || empty($newHeight)) {
if (!$newWidth || !$newHeight) {
throw new Nette\InvalidArgumentException('For stretching must be both width and height specified.');
}

Expand All @@ -345,7 +345,7 @@ public static function calculateSize($srcWidth, $srcHeight, $newWidth, $newHeigh
}

} else { // proportional
if (empty($newWidth) && empty($newHeight)) {
if (!$newWidth && !$newHeight) {
throw new Nette\InvalidArgumentException('At least width or height must be specified.');
}

Expand Down Expand Up @@ -410,17 +410,17 @@ public function crop($left, $top, $width, $height)
*/
public static function calculateCutout($srcWidth, $srcHeight, $left, $top, $newWidth, $newHeight)
{
if (is_string($newWidth) && substr($newWidth, -1) === '%') {
$newWidth = (int) round($srcWidth / 100 * substr($newWidth, 0, -1));
if (self::isPercent($newWidth)) {
$newWidth = (int) round($srcWidth / 100 * $newWidth);
}
if (is_string($newHeight) && substr($newHeight, -1) === '%') {
$newHeight = (int) round($srcHeight / 100 * substr($newHeight, 0, -1));
if (self::isPercent($newHeight)) {
$newHeight = (int) round($srcHeight / 100 * $newHeight);
}
if (is_string($left) && substr($left, -1) === '%') {
$left = (int) round(($srcWidth - $newWidth) / 100 * substr($left, 0, -1));
if (self::isPercent($left)) {
$left = (int) round(($srcWidth - $newWidth) / 100 * $left);
}
if (is_string($top) && substr($top, -1) === '%') {
$top = (int) round(($srcHeight - $newHeight) / 100 * substr($top, 0, -1));
if (self::isPercent($top)) {
$top = (int) round(($srcHeight - $newHeight) / 100 * $top);
}
if ($left < 0) {
$newWidth += $left;
Expand Down Expand Up @@ -469,12 +469,12 @@ public function place(self $image, $left = 0, $top = 0, $opacity = 100)
$width = $image->getWidth();
$height = $image->getHeight();

if (is_string($left) && substr($left, -1) === '%') {
$left = (int) round(($this->getWidth() - $width) / 100 * substr($left, 0, -1));
if (self::isPercent($left)) {
$left = (int) round(($this->getWidth() - $width) / 100 * $left);
}

if (is_string($top) && substr($top, -1) === '%') {
$top = (int) round(($this->getHeight() - $height) / 100 * substr($top, 0, -1));
if (self::isPercent($top)) {
$top = (int) round(($this->getHeight() - $height) / 100 * $top);
}

$output = $input = $image->image;
Expand Down Expand Up @@ -644,6 +644,22 @@ public function __clone()
}


/**
* @param int|string $num in pixels or percent
*/
private static function isPercent(&$num)
{
if (is_string($num) && substr($num, -1) === '%') {
$num = (float) substr($num, 0, -1);
return true;
} elseif (is_int($num) || $num === (string) (int) $num) {
$num = (int) $num;
return false;
}
throw new Nette\InvalidArgumentException("Expected dimension in int|string, '$num' given.");
}


/**
* Prevents serialization.
*/
Expand Down

0 comments on commit 29b8034

Please sign in to comment.