Hi Everybody,
I hope someone can help with this, it's taken so long to get this close but I just can't figure out the last small (but show stopping) detail.
I start with a string of text and a font-face entered/selected via a form. I am using imagettfbbox to determine the overall dimensions and the descent (height below the baseline) value of the string using the selected font.
Then I create an image using those dimensions and create the same text in that image using the same font (again, using imagettfbbox).
I position the imagettfbbox at x = 0 and y = overall height minus the descent value (I believe that that is how I calculate the baseline position of the string).
The goal is to create an image with all of the string visible but with no extra white space. It almost works.
I have found one character (so far) that has a problem with height using a normal font (§).
I have found several characters that cause a problem depending on whether I use a normal, italic or bold.
These characters seem to be cut off in the x axis if they are at the beginning or at the end of the string.
I'm guessing that I'm making a mistake somewhere when I calculate the dimension/descent.
You can see the output here: Click Here
Here is the code for the form page:
<?php
// Path to fonts (this will need to be changed to reflect the host environment)
$font_path = '/var/www/vhosts/sticky_lettering/fonts/';
// Input variables
if (isset($_POST['txt_string'])) {
$txt_string = $_POST['txt_string'];
} else {
$txt_string = 'Example text';
}
if (isset($_POST['font'])) {
$font = $_POST['font'];
} else {
$font = 'arial.ttf';
}
// Get the text dimensions
$base_coords = imagettfbbox(50, 0, $font_path . $font, $txt_string);
$base_width = abs($base_coords[4] - $base_coords[0]);
$base_height = abs($base_coords[5] - $base_coords[1]);
$base_descent = abs($base_coords[1]);
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>String Size Test</title>
</head>
<body>
<div id="outer_wrap" style="width: 75%; margin: 20px auto;">
<form method="post">
<p>Try these strings against each font:<br />§<br />g<br />lg<br />gl<br />You might have to look quite closely to see the problem, sometimes it's only one pixel that gets cut off, other times it is rather obvious.<br />I suspect I might be noticing a pattern (but I could be kidding myself!). If a problem exists on an italic font then it won't be a problem on a normal font and vice versa. The same relationship seems to exist between normal/bold.</p>
<input type="text" name="txt_string" value="<?php echo $txt_string; ?>" /><br />
<select name="font">
<option value="arial.ttf"<?php if ($font == 'arial.ttf') { echo ' selected';} ?>>Arial</option>
<option value="arialbd.ttf"<?php if ($font == 'arialbd.ttf') { echo ' selected';} ?>>Arial Bold</option>
<option value="arialbi.ttf"<?php if ($font == 'arialbi.ttf') { echo ' selected';} ?>>Arial Bold Italic</option>
<option value="ariali.ttf"<?php if ($font == 'ariali.ttf') { echo ' selected';} ?>>Arial Italic</option>
<option value="ARIALN.TTF"<?php if ($font == 'ARIALN.TTF') { echo ' selected';} ?>>Arial Narrow</option>
<option value="ARIALNB.TTF"<?php if ($font == 'ARIALNB.TTF') { echo ' selected';} ?>>Arial Narrow Bold</option>
<option value="ARIALNBI.TTF"<?php if ($font == 'ARIALNBI.TTF') { echo ' selected';} ?>>Arial Narrow Bold Italic</option>
<option value="ARIALNI.TTF"<?php if ($font == 'ARIALNI.TTF') { echo ' selected';} ?>>Arial Narrow Italic</option>
<option value="ariblk.ttf"<?php if ($font == 'ariblk.ttf') { echo ' selected';} ?>>Arial Black</option>
<option value="BRUSHSCI.TTF"<?php if ($font == 'BRUSHSCI.TTF') { echo ' selected';} ?>>Brush Script MT Italic</option>
<option value="comic.ttf"<?php if ($font == 'comic.ttf') { echo ' selected';} ?>>Comic Sans MS</option>
<option value="Cooper MD BT.TTF"<?php if ($font == 'Cooper MD BT.TTF') { echo ' selected';} ?>>Cooper Md BT Medium</option>
<option value="LCALLIG.TTF"<?php if ($font == 'LCALLIG.TTF') { echo ' selected';} ?>>Lucida Calligraphy Italic</option>
<option value="times.ttf"<?php if ($font == 'times.ttf') { echo ' selected';} ?>>Times New Roman</option>
<option value="timesbd.ttf"<?php if ($font == 'timesbd.ttf') { echo ' selected';} ?>>Times New Roman Bold</option>
</select><br />
<input type="submit" name="submit" value="submit" />
</form>
<table>
<tr>
<td>width: <?php echo $base_width; ?> | height: <?php echo $base_height; ?> | descent: <?php echo $base_descent; ?> | margin: 0</td>
</tr>
<tr>
<td><img src="image.php?txt_string=<?php echo $txt_string; ?>&font=<?php echo $font; ?>&width=<?php echo $base_width; ?>&height=<?php echo $base_height; ?>&descent=<?php echo $base_descent; ?>" /></td>
</tr>
<!-- This next image has margins and is for comparison purposes. -->
<tr>
<td>width + 10: <?php echo ($base_width + 10); ?> | height + 10: <?php echo ($base_height + 10); ?> | descent + 5: <?php echo ($base_descent + 5); ?> | margin: 5</td>
</tr>
<tr>
<td><img src="image.php?txt_string=<?php echo $txt_string; ?>&font=<?php echo $font; ?>&width=<?php echo ($base_width + 10); ?>&height=<?php echo ($base_height + 10); ?>&descent=<?php echo ($base_descent + 10); ?>&margin=1" /></td>
</tr>
</table>
</div>
</body>
</html>
Here is the code for the image file:
<?php
// Path to fonts (this will need to be changed to reflect the host environment)
$font_path = '/var/www/vhosts/sticky_lettering/site/fonts/';
// Input variables
$txt_string = $_GET['txt_string'];
$font = $_GET['font'];
$width = $_GET['width'];
$height = $_GET['height'];
$descent = $_GET['descent'];
if (isset($_GET['margin'])) {
$left_margin = 5;
} else {
$left_margin = 0;
}
$font = $font_path . $font;
// Create the image
$image = imagecreatetruecolor($width, $height);
imagesavealpha($image, true);
imagealphablending($image, false);
$white = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefill($image, 0, 0, $white);
$black = imagecolorallocate($image, 0, 0, 0);
imagettftext($image, 50, 0, $left_margin, ($height - $descent), $black, $font, $txt_string);
// Stream the image
header( "Content-type: image/png" );
imagepng($image );
// Tidy up (I know it's not really necessary here, I just can't help myself!)
imagecolordeallocate($image, $white);
imagecolordeallocate($image, $black);
imagedestroy($image)
?>
Thanks in advance for any help offered,
Simon.