@@ -318,7 +318,7 @@ public function curl(string $url, array $curlOptions = [], bool $failOnError = f
318318
319319 $ image = \curl_exec ($ curl );
320320
321- if ($ failOnError && \curl_errno ($ curl )){
321+ if ($ failOnError && \curl_errno ($ curl )) {
322322 throw new \Exception (\curl_error ($ curl ));
323323 }
324324
@@ -635,22 +635,22 @@ private static function formatColor(string $stringColor): string
635635 * Allocate a new color to the image.
636636 *
637637 * @param string $color Hexadecimal string color
638- * @return int Color id
638+ * @return int|false Color id
639639 */
640- private function colorAllocate (string $ color ): int
640+ private function colorAllocate (string $ color )
641641 {
642642 $ color = static ::formatColor ($ color );
643643 $ red = \hexdec (\substr ($ color , 0 , 2 ));
644644 $ green = \hexdec (\substr ($ color , 2 , 2 ));
645645 $ blue = \hexdec (\substr ($ color , 4 , 2 ));
646646 $ alpha = \floor (\hexdec (\substr ($ color , 6 , 2 )) / 2 );
647647
648- $ newColor = \imagecolorexactalpha ($ this ->image , $ red , $ green , $ blue , $ alpha );
649- if ($ newColor === -1 ) {
650- $ newColor = \imagecolorallocatealpha ($ this ->image , $ red , $ green , $ blue , $ alpha );
648+ $ colorId = \imagecolorexactalpha ($ this ->image , $ red , $ green , $ blue , $ alpha );
649+ if ($ colorId === -1 ) {
650+ $ colorId = \imagecolorallocatealpha ($ this ->image , $ red , $ green , $ blue , $ alpha );
651651 }
652652
653- return $ newColor ;
653+ return $ colorId ;
654654 }
655655
656656
@@ -801,18 +801,19 @@ public function grayscale(): Image
801801 *
802802 * @param string $string Text to be added on the image
803803 * @param string $fontPath Path to the TTF file
804- * @param int $fontSize Font size
804+ * @param float $fontSize Font size
805805 * @param string $color Hexadecimal string color
806- * @param int|string $posX Left position in pixel. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
807- * @param int|string $posY Top position in pixel. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
808- * @param int|string $anchorX Horizontal anchor of the text. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
809- * @param int|string $anchorY Vertical anchor of the text. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
810- * @param int $rotation Counterclockwise text rotation in degrees
806+ * @param float|string $posX Left position in pixel. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
807+ * @param float|string $posY Top position in pixel. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
808+ * @param float|string $anchorX Horizontal anchor of the text. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
809+ * @param float|string $anchorY Vertical anchor of the text. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
810+ * @param float $rotation Counterclockwise text rotation in degrees
811+ * @param float $letterSpacing add space between letters
811812 * @return $this Fluent interface
812813 */
813- public function writeText (string $ string , string $ fontPath , int $ fontSize , string $ color = '# ffffff ' , $ posX = 0 , $ posY = 0 , string $ anchorX = Image::ALIGN_CENTER , string $ anchorY = Image::ALIGN_MIDDLE , int $ rotation = 0 , int $ letter_spacing = 0 ): Image
814+ public function writeText (string $ string , string $ fontPath , float $ fontSize , string $ color = 'ffffff ' , $ posX = 0 , $ posY = 0 , $ anchorX = Image::ALIGN_CENTER , $ anchorY = Image::ALIGN_MIDDLE , float $ rotation = 0 , float $ letterSpacing = 0 ): Image
814815 {
815- $ this ->writeTextAndGetBoundingBox ($ string , $ fontPath , $ fontSize , $ color , $ posX , $ posY , $ anchorX , $ anchorY , $ rotation , $ letter_spacing );
816+ $ this ->writeTextAndGetBoundingBox ($ string , $ fontPath , $ fontSize , $ color , $ posX , $ posY , $ anchorX , $ anchorY , $ rotation , $ letterSpacing );
816817 return $ this ;
817818 }
818819
@@ -821,16 +822,17 @@ public function writeText(string $string, string $fontPath, int $fontSize, strin
821822 *
822823 * @param string $string Text to be added on the image
823824 * @param string $fontPath Path to the TTF file
824- * @param int $fontSize Font size
825+ * @param float $fontSize Font size
825826 * @param string $color Hexadecimal string color
826- * @param int|string $posX Left position in pixel. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
827- * @param int|string $posY Top position in pixel. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
828- * @param int|string $anchorX Horizontal anchor of the text. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
829- * @param int|string $anchorY Vertical anchor of the text. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
830- * @param int $rotation Counterclockwise text rotation in degrees
831- * @return array Pixels positions of the
832- */
833- public function writeTextAndGetBoundingBox (string $ string , string $ fontPath , int $ fontSize , string $ color = '#ffffff ' , $ posX = 0 , $ posY = 0 , string $ anchorX = Image::ALIGN_CENTER , string $ anchorY = Image::ALIGN_MIDDLE , int $ rotation = 0 , int $ letter_spacing = 0 ): array
827+ * @param float|string $posX Left position in pixel. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
828+ * @param float|string $posY Top position in pixel. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
829+ * @param float|string $anchorX Horizontal anchor of the text. You can use `Image::ALIGN_LEFT`, `Image::ALIGN_CENTER`, `Image::ALIGN_RIGHT`
830+ * @param float|string $anchorY Vertical anchor of the text. You can use `Image::ALIGN_TOP`, `Image::ALIGN_MIDDLE`, `Image::ALIGN_BOTTOM`
831+ * @param float $rotation Counterclockwise text rotation in degrees
832+ * @param float $letterSpacing add space between letters
833+ * @return array Bounding box positions of the text
834+ */
835+ public function writeTextAndGetBoundingBox (string $ string , string $ fontPath , float $ fontSize , string $ color = 'ffffff ' , $ posX = 0 , $ posY = 0 , $ anchorX = Image::ALIGN_CENTER , $ anchorY = Image::ALIGN_MIDDLE , float $ rotation = 0 , float $ letterSpacing = 0 ): array
834836 {
835837 if (!$ this ->isImageDefined ()) {
836838 return [];
@@ -858,7 +860,7 @@ public function writeTextAndGetBoundingBox(string $string, string $fontPath, int
858860 ) {
859861 if (
860862 ($ newImg = \imagecreatetruecolor (1 , 1 )) === false ||
861- ($ posText = $ this ->imagettftextWithSpacing ($ newImg , $ fontSize , $ rotation , 0 , 0 , $ color , $ fontPath , $ string , $ letter_spacing )) === false
863+ ($ posText = $ this ->imagettftextWithSpacing ($ newImg , $ fontSize , $ rotation , 0 , 0 , $ color , $ fontPath , $ string , $ letterSpacing )) === false
862864 ) {
863865 return [];
864866 }
@@ -884,6 +886,7 @@ public function writeTextAndGetBoundingBox(string $string, string $fontPath, int
884886 }
885887
886888 $ sizeWidth = $ xMax - $ xMin ;
889+ $ sizeHeight = $ yMax - $ yMin ;
887890
888891 switch ($ anchorX ) {
889892 case static ::ALIGN_LEFT :
@@ -898,17 +901,18 @@ public function writeTextAndGetBoundingBox(string $string, string $fontPath, int
898901 }
899902 switch ($ anchorY ) {
900903 case static ::ALIGN_TOP :
901- $ posY = $ posY + $ fontSize ;
904+ $ posY = $ posY - $ yMin ;
902905 break ;
903906 case static ::ALIGN_MIDDLE :
904- $ posY = $ posY + $ fontSize / 2 ;
907+ $ posY = $ posY - $ sizeHeight / 2 - $ yMin ;
905908 break ;
906909 case static ::ALIGN_BOTTOM :
910+ $ posY = $ posY - $ sizeHeight - $ yMin ;
907911 break ;
908912 }
909913 }
910914
911- $ posText = $ this ->imagettftextWithSpacing ($ this ->image , $ fontSize , $ rotation , $ posX , $ posY , $ color , $ fontPath , $ string , $ letter_spacing );
915+ $ posText = $ this ->imagettftextWithSpacing ($ this ->image , $ fontSize , $ rotation , $ posX , $ posY , $ color , $ fontPath , $ string , $ letterSpacing );
912916
913917 if ($ posText === false ) {
914918 return [];
@@ -943,35 +947,52 @@ public function writeTextAndGetBoundingBox(string $string, string $fontPath, int
943947
944948 /**
945949 * @param $image
946- * @param $size
947- * @param $angle
948- * @param $x
949- * @param $y
950- * @param $color
951- * @param $font
952- * @param $text
953- * @param int $spacing
954- * @return array
955- */
956- private function imagettftextWithSpacing ($ image , float $ size , float $ angle , float $ x , float $ y , int $ color , string $ font , string $ text , int $ spacing = 0 )
950+ * @param float $size
951+ * @param float $angle
952+ * @param float $x
953+ * @param float $y
954+ * @param int $color
955+ * @param string $font
956+ * @param string $text
957+ * @param float $spacing
958+ * @return array|false
959+ */
960+ private function imagettftextWithSpacing ($ image , float $ size , float $ angle , float $ x , float $ y , int $ color , string $ font , string $ text , float $ spacing = 0 )
957961 {
958- if ($ spacing == 0 )
959- {
962+ if ($ spacing == 0 ) {
960963 return \imagettftext ($ image , $ size , $ angle , $ x , $ y , $ color , $ font , $ text );
961- }
962- else
963- {
964- $ temp_x = $ x ;
965- $ temp_y = $ y ;
966- $ posText = [];
967- for ($ i = 0 ; $ i < \mb_strlen ($ text ); ++$ i )
968- {
969- $ posText = \imagettftext ($ image , $ size , $ angle , $ temp_x , $ temp_y , $ color , $ font , $ text [$ i ]);
964+ } else {
965+ $ length = \mb_strlen ($ text );
966+
967+ if ($ length == 0 ) {
968+ return false ;
969+ }
970+
971+ $ letterPos = ['x ' => $ x , 'y ' => $ y ];
972+ $ textWidth = $ spacing * ($ length - 1 );
973+ $ top = 0 ;
974+ $ bottom = 0 ;
975+
976+ for ($ i = 0 ; $ i < $ length ; ++$ i ) {
977+ \imagettftext ($ image , $ size , $ angle , $ letterPos ['x ' ], $ letterPos ['y ' ], $ color , $ font , $ text [$ i ]);
970978 $ bbox = \imagettfbbox ($ size , 0 , $ font , $ text [$ i ]);
971- $ temp_x += \cos (\deg2rad ($ angle )) * ($ spacing + ($ bbox [2 ] - $ bbox [0 ]));
972- $ temp_y -= \sin (\deg2rad ($ angle )) * ($ spacing + ($ bbox [2 ] - $ bbox [0 ]));
979+ $ letterPos = Geometry2D::getDstXY ($ letterPos ['x ' ], $ letterPos ['y ' ], $ angle , $ spacing + $ bbox [2 ]);
980+
981+ $ textWidth += $ bbox [2 ];
982+ if ($ top > $ bbox [5 ]) {
983+ $ top = $ bbox [5 ];
984+ }
985+ if ($ bottom < $ bbox [1 ]) {
986+ $ bottom = $ bbox [1 ];
987+ }
973988 }
974- return $ posText ;
989+
990+ $ bottomLeft = Geometry2D::getDstXY ($ x , $ y , $ angle - 90 , $ bottom );
991+ $ bottomRight = Geometry2D::getDstXY ($ bottomLeft ['x ' ], $ bottomLeft ['y ' ], $ angle , $ textWidth );
992+ $ topLeft = Geometry2D::getDstXY ($ x , $ y , $ angle + 90 , \abs ($ top ));
993+ $ topRight = Geometry2D::getDstXY ($ topLeft ['x ' ], $ topLeft ['y ' ], $ angle , $ textWidth );
994+
995+ return [$ bottomLeft ['x ' ], $ bottomLeft ['y ' ], $ bottomRight ['x ' ], $ bottomRight ['y ' ], $ topRight ['x ' ], $ topRight ['y ' ], $ topLeft ['x ' ], $ topLeft ['y ' ]];
975996 }
976997 }
977998
@@ -1010,7 +1031,7 @@ public function drawRectangle(int $left, int $top, int $right, int $bottom, stri
10101031 * @param string $color Hexadecimal string color
10111032 * @return $this Fluent interface
10121033 */
1013- public function drawPolygon (array $ points , string $ color = '# 000000 ' , $ antialias = false ): Image
1034+ public function drawPolygon (array $ points , string $ color = '000000 ' , $ antialias = false ): Image
10141035 {
10151036 if (!$ this ->isImageDefined ()) {
10161037 return $ this ;
@@ -1022,14 +1043,14 @@ public function drawPolygon(array $points, string $color = '#000000', $antialias
10221043 return $ this ;
10231044 }
10241045
1025- if ($ antialias ) {
1046+ if ($ antialias ) {
10261047 \imageantialias ($ this ->image , true );
10271048 \imagepolygon ($ this ->image , $ points , \count ($ points ) / 2 , $ color );
10281049 }
10291050
10301051 \imagefilledpolygon ($ this ->image , $ points , \count ($ points ) / 2 , $ color );
10311052
1032- if ($ antialias ) {
1053+ if ($ antialias ) {
10331054 \imageantialias ($ this ->image , false );
10341055 }
10351056
@@ -1280,10 +1301,10 @@ private function getData(callable $imgFunction): string
12801301
12811302 \ob_start ();
12821303 $ imgFunction ();
1283- $ image_data = \ob_get_contents ();
1304+ $ imageData = \ob_get_contents ();
12841305 \ob_end_clean ();
12851306
1286- return $ image_data ;
1307+ return $ imageData ;
12871308 }
12881309
12891310 /**
@@ -1293,7 +1314,9 @@ private function getData(callable $imgFunction): string
12931314 */
12941315 public function getDataPNG (): string
12951316 {
1296- return $ this ->getData (function () {$ this ->displayPNG ();});
1317+ return $ this ->getData (function () {
1318+ $ this ->displayPNG ();
1319+ });
12971320 }
12981321
12991322 /**
@@ -1304,7 +1327,9 @@ public function getDataPNG(): string
13041327 */
13051328 public function getDataJPG (int $ quality = -1 ): string
13061329 {
1307- return $ this ->getData (function () use ($ quality ) {$ this ->displayJPG ($ quality );});
1330+ return $ this ->getData (function () use ($ quality ) {
1331+ $ this ->displayJPG ($ quality );
1332+ });
13081333 }
13091334
13101335 /**
@@ -1314,7 +1339,9 @@ public function getDataJPG(int $quality = -1): string
13141339 */
13151340 public function getDataGIF (): string
13161341 {
1317- return $ this ->getData (function () {$ this ->displayGIF ();});
1342+ return $ this ->getData (function () {
1343+ $ this ->displayGIF ();
1344+ });
13181345 }
13191346
13201347 /**
0 commit comments