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.

diafol commented: Good question +14

Hi, Diafol,

Thanks for that link. It helped in so much as it gave me a slightly different formula to get the same result and most helpfully, for my confidence in what I'm doing, it confirmed to me that I was on the right track in respect of the procedure that I'm using.

Unfortunately, using the code on the page produced the same problem.

Thanks anyway, I appreciate the effort you have taken,

Simon.

Member Avatar for diafol

No problem. Interesting question - of course we notice this type of thing from time to time in desktop applications too, more usually with uncommon fonts. A quick fix for horizontal issues is to throw in a space at the end, but I note that you don't want this. Anybody else?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.