jrobinsonc
2/13/2015 - 3:55 PM

Write text to the image using TrueType fonts and split text into several lines based on a width size.

Write text to the image using TrueType fonts and split text into several lines based on a width size.

<?php

/**
 * imagettftext_in_lines
 * 
 * @author JoseRobinson.com
 * @link https://gist.github.com/jrobinsonc/699ea6fadd7369146574
 * @version 201502131102
 * @param $image An image resource, returned by one of the image creation functions, such as imagecreatetruecolor().
 * @param $font_size The font size. Depending on your version of GD, this should be specified as the pixel size (GD1) or point size (GD2).
 * @param $angle The angle in degrees, with 0 degrees being left-to-right reading text. Higher values represent a counter-clockwise rotation. For example, a value of 90 would result in bottom-to-top reading text.
 * @param $x The coordinates given by x and y will define the basepoint of the first character (roughly the lower-left corner of the character). This is different from the imagestring(), where x and y define the upper-left corner of the first character. For example, "top left" is 0, 0.
 * @param $y The y-ordinate. This sets the position of the fonts baseline, not the very bottom of the character.
 * @param $font_color The color index. Using the negative of a color index has the effect of turning off antialiasing. See imagecolorallocate().
 * @param $font_file The path to the TrueType font you wish to use.
 * @param $text The text string in UTF-8 encoding.
 * @param $max_width The max width for every line of text.
 * @param $line_height The height of every line of the text.
 * @param $align_vertical Align text to: top, buttom.
 * @return array The lines of text.
 */
function imagettftext_in_lines($image, $font_size, $angle, $x, $y, $font_color, $font_file, $text, $max_width, $line_height = 1, $align_vertical = 'top')
{
	$bbox = imagettfbbox($font_size, $angle, $font_file, $text);
	$line_text_height = abs($bbox[7]) * $line_height;
	$text_lines = array();

	if ($bbox[4] <= $max_width)
	{
		$text_lines[] = $text;
	}
	else
	{
		$words = explode(' ', $text);
	    $words_qty = count($words);
	    $line_num = 1;
	    
	    for ($i = 0; $i < $words_qty; $i++)
	    {
	        split_text_in_lines_check_again:

	        if ($line_num > $words_qty)
	            break;


	        if (! isset($text_lines[$line_num]))
	            $text_lines[$line_num] = '';


	        $current_line_text = trim("{$text_lines[$line_num]} {$words[$i]}");
	        $font_bbox = imagettfbbox($font_size, $angle, $font_file, $current_line_text);

	        if ($font_bbox[4] > $max_width)
	        {
	            if (count(explode(' ', $current_line_text)) === 1)
	            {
	                $text_lines[$line_num] = $current_line_text;
	                continue;
	            }

	            $line_num++;
	            goto split_text_in_lines_check_again;
	        }
	        else
	        {
	            $text_lines[$line_num] = $current_line_text;
	        }
	    }
	}

	
	switch ($align_vertical) 
	{
		case 'top':
			$y_ = $y;
			break;

		case 'bottom':
			$y_ = $y - ((count($text_lines) * $line_text_height) - $line_text_height);
			break;
	}


	foreach ($text_lines as $line)
	{
		imagettftext($image, $font_size, $angle, $x, $y_, $font_color, $font_file, $line);

		$y_ += $line_text_height;
	}

	return $text_lines;
}