diff --git a/composer.json b/composer.json index 34e893d..6d7bf2c 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "A class drawing multiline and aligned text on pictures. Uses GD extension.", "license": "MIT", "require": { - "php": ">=5.3", + "php": ">=8.0", "ext-gd": "*" }, "require-dev": { diff --git a/src/Box.php b/src/Box.php index 3721a50..f1d180c 100644 --- a/src/Box.php +++ b/src/Box.php @@ -6,82 +6,26 @@ class Box { - /** - * @var resource - */ - protected $im; - - /** - * @var int - */ - protected $strokeSize = 0; - - /** - * @var Color - */ - protected $strokeColor; - - /** - * @var int - */ - protected $fontSize = 12; - - /** - * @var Color - */ - protected $fontColor; - - /** - * @var string - */ - protected $alignX = 'left'; - - /** - * @var string - */ - protected $alignY = 'top'; - - /** - * @var int - */ - protected $textWrapping = TextWrapping::WrapWithOverflow; - - /** - * @var float - */ - protected $lineHeight = 1.25; - - /** - * @var float - */ - protected $baseline = 0.2; - - /** - * @var string - */ - protected $fontFace = null; - - /** - * @var bool - */ - protected $debug = false; - - /** - * @var bool|array - */ - protected $textShadow = false; - - /** - * @var bool|Color - */ - protected $backgroundColor = false; - - /** - * @var Rectangle - */ - protected $box; - - public function __construct(&$image) + protected \GdImage $im; + + protected int $strokeSize = 0; + protected Color $strokeColor; + protected int $fontSize = 12; + protected Color $fontColor; + protected string $alignX = 'left'; + protected string $alignY = 'top'; + protected int $textWrapping = TextWrapping::WrapWithOverflow; + protected float $lineHeight = 1.25; + protected float $baseline = 0.2; + protected ?string $fontFaceFilePath = null; + protected bool $debug = false; + + protected ?Struct\Shadow $textShadow = null; + + protected ?Color $backgroundColor = null; + protected Struct\Rectangle $box; + + public function __construct(\GDImage $image) { $this->im = $image; $this->fontColor = new Color(0, 0, 0); @@ -89,44 +33,38 @@ public function __construct(&$image) $this->box = new Rectangle(0, 0, 100, 100); } - /** - * @param Color $color Font color - */ - public function setFontColor(Color $color) + public function setFontColor(Color $fontColor) : void { - $this->fontColor = $color; + $this->fontColor = $fontColor; } /** - * @param string $path Path to the font file + * @param string $filePath Path to the font file */ - public function setFontFace($path) + public function setFontFace(string $filePath) : void { - $this->fontFace = $path; + $this->fontFaceFilePath = $filePath; } /** - * @param int $v Font size in *pixels* + * @param int $fontsizePixels Font size in *pixels* */ - public function setFontSize($v) + public function setFontSize(int $fontsizePixels) : void { - $this->fontSize = $v; + $this->fontSize = $fontsizePixels; } - - /** - * @param Color $color Stroke color - */ - public function setStrokeColor(Color $color) + + public function setStrokeColor(Color $strokeColor) : void { - $this->strokeColor = $color; + $this->strokeColor = $strokeColor; } - + /** - * @param int $v Stroke size in *pixels* + * @param int $strokeSizePixels Stroke size in *pixels* */ - public function setStrokeSize($v) + public function setStrokeSize(int $strokeSizePixels) : void { - $this->strokeSize = $v; + $this->strokeSize = $strokeSizePixels; } /** @@ -134,37 +72,34 @@ public function setStrokeSize($v) * @param int $xShift Relative shadow position in pixels. Positive values move shadow to right, negative to left. * @param int $yShift Relative shadow position in pixels. Positive values move shadow to bottom, negative to up. */ - public function setTextShadow(Color $color, $xShift, $yShift) + public function setTextShadow(Color $color, int $xShift, int $yShift) : void { - $this->textShadow = array( - 'color' => $color, - 'offset' => new Point($xShift, $yShift) + $this->textShadow = new Struct\Shadow( + $color, + new Struct\Point($xShift, $yShift), ); } - /** - * @param Color $color Font color - */ - public function setBackgroundColor(Color $color) + public function setBackgroundColor(Color $color) : void { $this->backgroundColor = $color; } /** * Allows to customize spacing between lines. - * @param float $v Height of the single text line, in percents, proportionally to font size + * @param float $value Height of the single text line, in percents, proportionally to font size */ - public function setLineHeight($v) + public function setLineHeight(float $value) : void { - $this->lineHeight = $v; + $this->lineHeight = $value; } /** - * @param float $v Position of baseline, in percents, proportionally to line height measuring from the bottom. + * @param float $value Position of baseline, in percents, proportionally to line height measuring from the bottom. */ - public function setBaseline($v) + public function setBaseline(float $value) : void { - $this->baseline = $v; + $this->baseline = $value; } /** @@ -172,7 +107,7 @@ public function setBaseline($v) * @param string $x Horizontal alignment. Allowed values are: left, center, right. * @param string $y Vertical alignment. Allowed values are: top, center, bottom. */ - public function setTextAlign($x = 'left', $y = 'top') + public function setTextAlign(string $x = 'left', string $y = 'top') : void { $xAllowed = array('left', 'right', 'center'); $yAllowed = array('top', 'bottom', 'center'); @@ -196,7 +131,7 @@ public function setTextAlign($x = 'left', $y = 'top') * @param int $width Width of texbox in pixels. * @param int $height Height of textbox in pixels. */ - public function setBox($x, $y, $width, $height) + public function setBox(int $x, int $y, int $width, int $height) : void { $this->box = new Rectangle($x, $y, $width, $height); } @@ -204,41 +139,107 @@ public function setBox($x, $y, $width, $height) /** * Enables debug mode. Whole textbox and individual lines will be filled with random colors. */ - public function enableDebug() + public function enableDebug() : void { $this->debug = true; } + public function setTextWrapping(int $textWrapping) : void + { + $this->textWrapping = $textWrapping; + } + + /** - * @param int $textWrapping + * Draws the text on the picture. + * + * @param string $text Text to draw. May contain newline characters. + * + * @return Rectangle Area that cover the drawn text */ - public function setTextWrapping($textWrapping) + public function draw(string $text) : Struct\Rectangle { - $this->textWrapping = $textWrapping; + return $this->drawText($text, true); + } + + /** + * Draws the text on the picture, fitting it to the current box + * + * @param string $text Text to draw. May contain newline characters. + * @param int $precision Increment or decrement of font size. The lower this value, the slower this method. + * + * @return Rectangle Area that cover the drawn text + */ + public function drawFitFontSize(string $text, int $precision = -1, int $maxFontSize = -1, int $minFontSize = -1, &$usedFontSize = null) : Struct\Rectangle + { + $initialFontSize = $this->fontSize; + + $usedFontSize = $this->fontSize; + $rectangle = $this->calculate($text); + + if ($rectangle->getHeight() > $this->box->getHeight() || $rectangle->getWidth() > $this->box->getWidth()) { + // Decrement font size + do { + $this->setFontSize($usedFontSize); + $rectangle = $this->calculate($text); + + $usedFontSize -= $precision; + } while ( + ($minFontSize == -1 || $usedFontSize > $minFontSize) && + ($rectangle->getHeight() > $this->box->getHeight() || $rectangle->getWidth() > $this->box->getWidth()) + ); + + $usedFontSize += $precision; + } else { + // Increment font size + do { + $this->setFontSize($usedFontSize); + $rectangle = $this->calculate($text); + + $usedFontSize += $precision; + } while (($maxFontSize > 0 && $usedFontSize < $maxFontSize) + && $rectangle->getHeight() < $this->box->getHeight() + && $rectangle->getWidth() < $this->box->getWidth()); + + $usedFontSize -= $precision * 2; + } + $this->setFontSize($usedFontSize); + + $rectangle = $this->drawText($text, true); + + // Restore initial font size + $this->setFontSize($initialFontSize); + + return $rectangle; + } + + /** + * Get the area that will cover the given text + */ + public function calculate(string $text) : Struct\Rectangle + { + return $this->drawText($text, false); } /** * Draws the text on the picture. * @param string $text Text to draw. May contain newline characters. + * @param bool $draw + * @return Rectangle */ - public function draw($text) + protected function drawText(string $text, bool $draw) : Struct\Rectangle { - if (!isset($this->fontFace)) { + if (!isset($this->fontFaceFilePath)) { throw new \InvalidArgumentException('No path to font file has been specified.'); } - switch ($this->textWrapping) { - case TextWrapping::NoWrap: - $lines = array($text); - break; - case TextWrapping::WrapWithOverflow: - default: - $lines = $this->wrapTextWithOverflow($text); - break; - } + $lines = match ( $this->textWrapping ) { + TextWrapping::NoWrap => array( $text ), + default => $this->wrapTextWithOverflow($text), + }; if ($this->debug) { - // Marks whole texbox area with color + // Marks whole textbox area with color $this->drawFilledRectangle( $this->box, new Color(rand(180, 255), rand(180, 255), rand(180, 255), 80) @@ -248,40 +249,34 @@ public function draw($text) $lineHeightPx = $this->lineHeight * $this->fontSize; $textHeight = count($lines) * $lineHeightPx; - switch ($this->alignY) { - case VerticalAlignment::Center: - $yAlign = ($this->box->getHeight() / 2) - ($textHeight / 2); - break; - case VerticalAlignment::Bottom: - $yAlign = $this->box->getHeight() - $textHeight; - break; - case VerticalAlignment::Top: - default: - $yAlign = 0; - } + $yAlign = match ( $this->alignY ) { + VerticalAlignment::Center => ( $this->box->getHeight() / 2 ) - ( $textHeight / 2 ), + VerticalAlignment::Bottom => $this->box->getHeight() - $textHeight, + default => 0, + }; $n = 0; + + $drawnX = $drawnY = PHP_INT_MAX; + $drawnH = $drawnW = 0; + foreach ($lines as $line) { $box = $this->calculateBox($line); - switch ($this->alignX) { - case HorizontalAlignment::Center: - $xAlign = ($this->box->getWidth() - $box->getWidth()) / 2; - break; - case HorizontalAlignment::Right: - $xAlign = ($this->box->getWidth() - $box->getWidth()); - break; - case HorizontalAlignment::Left: - default: - $xAlign = 0; - } + + $xAlign = match ( $this->alignX ) { + HorizontalAlignment::Center => ( $this->box->getWidth() - $box->getWidth() ) / 2, + HorizontalAlignment::Right => ( $this->box->getWidth() - $box->getWidth() ), + default => 0, + }; + $yShift = $lineHeightPx * (1 - $this->baseline); // current line X and Y position $xMOD = $this->box->getX() + $xAlign; $yMOD = $this->box->getY() + $yAlign + $yShift + ($n * $lineHeightPx); - if ($line && $this->backgroundColor) { - // Marks whole texbox area with given background-color + if ($draw && $line && $this->backgroundColor !== null) { + // Marks whole textbox area with given background-color $backgroundHeight = $this->fontSize; $this->drawFilledRectangle( @@ -308,29 +303,38 @@ public function draw($text) ); } - if ($this->textShadow !== false) { + if ($draw) { + if ($this->textShadow !== null) { + $this->drawInternal( + new Point( + $xMOD + $this->textShadow->offset->getX(), + $yMOD + $this->textShadow->offset->getY() + ), + $this->textShadow->color, + $line, + ); + } + + $this->strokeText((int)$xMOD, (int)$yMOD, $line); $this->drawInternal( new Point( - $xMOD + $this->textShadow['offset']->getX(), - $yMOD + $this->textShadow['offset']->getY() + (int)$xMOD, + (int)$yMOD ), - $this->textShadow['color'], - $line + $this->fontColor, + $line, ); } - $this->strokeText($xMOD, $yMOD, $line); - $this->drawInternal( - new Point( - $xMOD, - $yMOD - ), - $this->fontColor, - $line - ); + $drawnX = min($xMOD, $drawnX); + $drawnY = min($this->box->getY() + $yAlign + ($n * $lineHeightPx), $drawnY); + $drawnW = max($drawnW, $box->getWidth()); + $drawnH += $lineHeightPx; $n++; } + + return new Rectangle($drawnX, $drawnY, $drawnW, $drawnH); } /** @@ -338,7 +342,7 @@ public function draw($text) * @param string $text * @return string[] */ - protected function wrapTextWithOverflow($text) + protected function wrapTextWithOverflow(string $text) : array { $lines = array(); // Split text explicitly into lines by \n, \r\n and \r @@ -361,15 +365,12 @@ protected function wrapTextWithOverflow($text) return $lines; } - /** - * @return float - */ - protected function getFontSizeInPoints() + protected function getFontSizeInPoints() : float { return 0.75 * $this->fontSize; } - protected function drawFilledRectangle(Rectangle $rect, Color $color) + protected function drawFilledRectangle(Rectangle $rect, Color $color) : void { imagefilledrectangle( $this->im, @@ -383,12 +384,10 @@ protected function drawFilledRectangle(Rectangle $rect, Color $color) /** * Returns the bounding box of a text. - * @param string $text - * @return Rectangle */ - protected function calculateBox($text) + protected function calculateBox(string $text) : Struct\Rectangle { - $bounds = imagettfbbox($this->getFontSizeInPoints(), 0, $this->fontFace, $text); + $bounds = imagettfbbox($this->getFontSizeInPoints(), 0, $this->fontFaceFilePath, $text); $xLeft = $bounds[0]; // (lower|upper) left corner, X position $xRight = $bounds[2]; // (lower|upper) right corner, X position @@ -403,7 +402,7 @@ protected function calculateBox($text) ); } - protected function strokeText($x, $y, $text) + protected function strokeText(int $x, int $y, string $text) : void { $size = $this->strokeSize; if ($size <= 0) return; @@ -414,7 +413,7 @@ protected function strokeText($x, $y, $text) } } - protected function drawInternal(Point $position, Color $color, $text) + protected function drawInternal(Point $position, Color $color, $text) : void { imagettftext( $this->im, @@ -423,8 +422,8 @@ protected function drawInternal(Point $position, Color $color, $text) $position->getX(), $position->getY(), $color->getIndex($this->im), - $this->fontFace, + $this->fontFaceFilePath, $text ); } -} +} \ No newline at end of file diff --git a/src/Color.php b/src/Color.php index 5efee50..7d1813a 100644 --- a/src/Color.php +++ b/src/Color.php @@ -7,33 +7,19 @@ */ class Color { - /** - * @var int - */ - protected $red; - /** - * @var int - */ - protected $green; - - /** - * @var int - */ - protected $blue; - - /** - * @var int|null - */ - protected $alpha; + protected int $red; + protected int $green; + protected int $blue; + protected ?int $alpha; /** * @param int $red Value of red component 0-255 * @param int $green Value of green component 0-255 * @param int $blue Value of blue component 0-255 - * @param int $alpha A value between 0 and 127. 0 indicates completely opaque while 127 indicates completely transparent. + * @param int|null $alpha A value between 0 and 127. 0 indicates completely opaque while 127 indicates completely transparent. */ - public function __construct($red = 0, $green = 0, $blue = 0, $alpha = null) + public function __construct(int $red = 0, int $green = 0, int $blue = 0, int $alpha = null) { $this->red = $red; $this->green = $green; @@ -43,56 +29,53 @@ public function __construct($red = 0, $green = 0, $blue = 0, $alpha = null) /** * Parses string to Color object representation. - * @param string $str String with color information, ex. #000000 + * @param string $string String with color information, ex. #000000 * @return Color * @todo Add parsing of CSS-like strings: rgb(), rgba(), hsl() */ - public static function parseString($str) + public static function parseString(string $string) : Color { - $str = str_replace('#', '', $str); - if (strlen($str) == 6) { - $r = hexdec(substr($str, 0, 2)); - $g = hexdec(substr($str, 2, 2)); - $b = hexdec(substr($str, 4, 2)); - } else if (strlen($str) == 3) { - $r = hexdec(str_repeat(substr($str, 0, 1), 2)); - $g = hexdec(str_repeat(substr($str, 1, 1), 2)); - $b = hexdec(str_repeat(substr($str, 2, 1), 2)); - } else { + $string = str_replace('#', '', $string); + + if (strlen($string) == 6) { + $r = hexdec(substr($string, 0, 2)); + $g = hexdec(substr($string, 2, 2)); + $b = hexdec(substr($string, 4, 2)); + } + else if (strlen($string) == 3) { + $r = hexdec(str_repeat(substr($string, 0, 1), 2)); + $g = hexdec(str_repeat(substr($string, 1, 1), 2)); + $b = hexdec(str_repeat(substr($string, 2, 1), 2)); + } + else { throw new \InvalidArgumentException('Unrecognized color.'); } return new Color($r, $g, $b); } - /** - * @param float $h Hue - * @param float $s Saturation - * @param float $l Light - * @return Color - */ - public static function fromHsl($h, $s, $l) + public static function fromHsl(float $hue, float $saturation, float $light) : Color { $fromFloat = function (array $rgb) { foreach ($rgb as &$v) { $v = (int)round($v * 255); - }; + } return new Color($rgb[0], $rgb[1], $rgb[2]); }; // If saturation is 0, the given color is grey and only // lightness is relevant. - if ($s == 0) { - return $fromFloat(array($l, $l, $l)); + if ($saturation == 0) { + return $fromFloat(array($light, $light, $light)); } // Else calculate r, g, b according to hue. // Check http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL for details - $chroma = (1 - abs(2 * $l - 1)) * $s; - $h_ = $h * 6; + $chroma = (1 - abs(2 * $light - 1)) * $saturation; + $h_ = $hue * 6; $x = $chroma * (1 - abs((fmod($h_,2)) - 1)); // Note: fmod because % (modulo) returns int value!! - $m = $l - round($chroma/2, 10); // Bugfix for strange float behaviour (e.g. $l=0.17 and $s=1) + $m = $light - round($chroma/2, 10); // Bugfix for strange float behaviour (e.g. $l=0.17 and $s=1) if ($h_ >= 0 && $h_ < 1) $rgb = array(($chroma + $m), ($x + $m), $m); elseif ($h_ >= 1 && $h_ < 2) $rgb = array(($x + $m), ($chroma + $m), $m); @@ -100,18 +83,20 @@ public static function fromHsl($h, $s, $l) elseif ($h_ >= 3 && $h_ < 4) $rgb = array($m, ($x + $m), ($chroma + $m)); elseif ($h_ >= 4 && $h_ < 5) $rgb = array(($x + $m), $m, ($chroma + $m)); elseif ($h_ >= 5 && $h_ < 6) $rgb = array(($chroma + $m), $m, ($x + $m)); - else throw new \InvalidArgumentException('Invalid hue, it should be a value between 0 and 1.'); + else + throw new \InvalidArgumentException('Invalid hue, it should be a value between 0 and 1.'); return $fromFloat($rgb); } /** - * @param resource $image GD image resource + * @param \GdImage $image GD image resource * @return int Returns the index of the specified color+alpha in the palette of the image, * or index of allocated color if the color does not exist in the image's palette. */ - public function getIndex($image) + public function getIndex(\GdImage $image) : int { + $index = $this->hasAlphaChannel() ? imagecolorexactalpha( $image, $this->red, $this->green, $this->blue, $this->alpha) @@ -132,7 +117,7 @@ public function getIndex($image) /** * @return bool TRUE when alpha channel is specified, FALSE otherwise */ - public function hasAlphaChannel() + public function hasAlphaChannel() : bool { return $this->alpha !== null; } @@ -140,7 +125,7 @@ public function hasAlphaChannel() /** * @return int[] */ - public function toArray() + public function toArray() : array { return array($this->red, $this->green, $this->blue); } diff --git a/src/Struct/Point.php b/src/Struct/Point.php index 7060b30..ef97af4 100644 --- a/src/Struct/Point.php +++ b/src/Struct/Point.php @@ -4,39 +4,21 @@ class Point { - /** - * @var int - */ - private $x; + private int $x; + private int $y; - /** - * @var int - */ - private $y; - - /** - * Point constructor. - * @param int $x - * @param int $y - */ - public function __construct($x, $y) + public function __construct(int $x, int $y) { $this->x = $x; $this->y = $y; } - /** - * @return int - */ - public function getX() + public function getX() : int { return $this->x; } - /** - * @return int - */ - public function getY() + public function getY() : int { return $this->y; } diff --git a/src/Struct/Rectangle.php b/src/Struct/Rectangle.php index c24e708..7d48afc 100644 --- a/src/Struct/Rectangle.php +++ b/src/Struct/Rectangle.php @@ -4,74 +4,43 @@ class Rectangle extends Point { - /** - * @var int - */ - private $width; + private int $width; + private int $height; - /** - * @var int - */ - private $height; - - /** - * Rectangle constructor. - * @param int $x - * @param int $y - * @param int $width - * @param int $height - */ - public function __construct($x, $y, $width, $height) + public function __construct(float $x, float $y, float $width, float $height) { - parent::__construct($x, $y); - $this->width = $width; - $this->height = $height; + parent::__construct((int)$x, (int)$y); + + $this->width = (int)$width; + $this->height = (int)$height; } - /** - * @return int - */ - public function getWidth() + public function getWidth() : int { return $this->width; } - /** - * @return int - */ - public function getHeight() + public function getHeight() : int { return $this->height; } - /** - * @return int - */ - public function getLeft() + public function getLeft() : int { return $this->getX(); } - /** - * @return int - */ - public function getTop() + public function getTop() : int { return $this->getY(); } - /** - * @return int - */ - public function getRight() + public function getRight() : int { return $this->getX() + $this->width; } - /** - * @return int - */ - public function getBottom() + public function getBottom() : int { return $this->getY() + $this->height; } diff --git a/src/Struct/Shadow.php b/src/Struct/Shadow.php new file mode 100644 index 0000000..4d2b108 --- /dev/null +++ b/src/Struct/Shadow.php @@ -0,0 +1,17 @@ +color = $color; + $this->offset = $point; + } +} \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php index f687d70..fa12415 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,7 +5,7 @@ class TestCase extends \PHPUnit\Framework\TestCase { /** * @param $name - * @return resource + * @return resource|\GdImage */ protected function openImageResource($name) { @@ -18,7 +18,7 @@ protected function openImageResource($name) */ protected function sha1ImageResource($name) { - return sha1_file(__DIR__.'/images/'.$name); + return sha1_file(__DIR__ . '/images/' .$name); } /** diff --git a/tests/TextAlignmentTest.php b/tests/TextAlignmentTest.php index 283fe80..b25b528 100644 --- a/tests/TextAlignmentTest.php +++ b/tests/TextAlignmentTest.php @@ -15,7 +15,7 @@ protected function mockBox($im) imagesavealpha($im, true); $box = new Box($im); - $box->setFontFace(__DIR__.'/LinLibertine_R.ttf'); // http://www.dafont.com/franchise.font + $box->setFontFace(__DIR__ . '/LinLibertine_R.ttf'); // http://www.dafont.com/franchise.font $box->setFontColor(new Color(255, 75, 140)); $box->setFontSize(16); $box->setBackgroundColor(new Color(0, 0, 0)); diff --git a/tests/TextWrappingTest.php b/tests/TextWrappingTest.php index b9d2578..c76327a 100644 --- a/tests/TextWrappingTest.php +++ b/tests/TextWrappingTest.php @@ -13,7 +13,7 @@ protected function mockBox($im) imagesavealpha($im, true); $box = new Box($im); - $box->setFontFace(__DIR__.'/LinLibertine_R.ttf'); // http://www.dafont.com/franchise.font + $box->setFontFace(__DIR__ . '/LinLibertine_R.ttf'); // http://www.dafont.com/franchise.font $box->setFontColor(new Color(255, 75, 140)); $box->setFontSize(16); $box->setBox(0, 135, imagesx($im), 70); diff --git a/tests/images/test_align_bottom_center.png b/tests/images/test_align_bottom_center.png index 408ae63..7823d6d 100644 Binary files a/tests/images/test_align_bottom_center.png and b/tests/images/test_align_bottom_center.png differ diff --git a/tests/images/test_align_bottom_left.png b/tests/images/test_align_bottom_left.png index 357d943..d775598 100644 Binary files a/tests/images/test_align_bottom_left.png and b/tests/images/test_align_bottom_left.png differ diff --git a/tests/images/test_align_bottom_right.png b/tests/images/test_align_bottom_right.png index 923c097..12e5ad9 100644 Binary files a/tests/images/test_align_bottom_right.png and b/tests/images/test_align_bottom_right.png differ diff --git a/tests/images/test_align_center_center.png b/tests/images/test_align_center_center.png index d8dea09..a98caf0 100644 Binary files a/tests/images/test_align_center_center.png and b/tests/images/test_align_center_center.png differ diff --git a/tests/images/test_align_center_left.png b/tests/images/test_align_center_left.png index 7ec2843..50b3056 100644 Binary files a/tests/images/test_align_center_left.png and b/tests/images/test_align_center_left.png differ diff --git a/tests/images/test_align_center_right.png b/tests/images/test_align_center_right.png index 11fd023..4931893 100644 Binary files a/tests/images/test_align_center_right.png and b/tests/images/test_align_center_right.png differ diff --git a/tests/images/test_align_top_center.png b/tests/images/test_align_top_center.png index 71c4d97..9983e5a 100644 Binary files a/tests/images/test_align_top_center.png and b/tests/images/test_align_top_center.png differ diff --git a/tests/images/test_align_top_left.png b/tests/images/test_align_top_left.png index 358abe6..41d6874 100644 Binary files a/tests/images/test_align_top_left.png and b/tests/images/test_align_top_left.png differ diff --git a/tests/images/test_align_top_right.png b/tests/images/test_align_top_right.png index 57d464f..2450650 100644 Binary files a/tests/images/test_align_top_right.png and b/tests/images/test_align_top_right.png differ diff --git a/tests/images/test_wrap_NoWrap.png b/tests/images/test_wrap_NoWrap.png index ab18596..5588cfe 100644 Binary files a/tests/images/test_wrap_NoWrap.png and b/tests/images/test_wrap_NoWrap.png differ diff --git a/tests/images/test_wrap_WrapWithOverflow.png b/tests/images/test_wrap_WrapWithOverflow.png index 9be9ee2..97130a3 100644 Binary files a/tests/images/test_wrap_WrapWithOverflow.png and b/tests/images/test_wrap_WrapWithOverflow.png differ