(none) imager-devel
/ help / lists / applications / search /

Re: Scaling fonts not working as expected

From: Peter Wood (
Date: Wed 20 Mar 2013 - 13:51:04 GMT

  • Next message: Tony Cook: "Re: Scaling fonts not working as expected"


    Thanks for your reply.

    I had previously tried doing this by changing the font size, but the
    results I got were odd. Here's an example:

    * Using font BodoniXT.TTF, initial size 70, image width 615px. Test string
    WWWWWWWWWWWWWWWWWWWW (20 'W's) display_width was initially 1298px. Got
    scaling ratio of 0.473805855161787, resulting in new font size of
    33.1664098613251. Applied this new size and got display_width of 619px.
    Exceeded the boundaries of the image by just 4px.
    * Same font, size, image width, but new, shorter test string. Test string
    was same as above less one 'W'. display_width was initially 1233px. Got
    scaling ratio of 0.498783454987835, resulting in new font size of
    34.9148418491484. Applied this new size and got display_width of 644px,
    exceeding the image width by 29px.
    * The first test string that actually fit inside the image width was 15
    'W's. This had an initial width of 973px, which resulted in a scaling
    ratio of 0.632065775950668 and a new font size of 44.2446043165468. With
    the new size, this rendered at a width of 613px, just 2px inside the

    Other fonts had different points where the final size would fit or not fit
    inside the boundaries.

    One of my colleagues suggested that this was due to font hinting, which
    could change at different font sizes and result in different string
    widths. We felt that trying to scale the font rather than change its size
    might give better results, in particular because this was supposed to
    disable font hinting.

    Any thoughts?



    On 3/19/13 5:45 PM, "Tony Cook" <20190@xyz.molar.is> wrote:

    >On Tue, Mar 19, 2013 at 01:21:41PM +0000, Peter Wood wrote:
    >> Hello,
    >> I'm working on a script that tries to determine whether a string
    > rendered in a given font will exceed the width of the image, and, if
    > so, scale the font down so that it fits inside the image. It's not
    > working as I would expect, however. The test script appears below so
    > that you can try to replicate the results yourself. What ends up
    > happening is that the string in the scaled-down font appears to take
    > up roughly the same width as the original font, and start at roughly
    > the same point. That means that as it gets smaller, the string moves
    > further off the left hand side of the image until it's completely
    > invisible.
    >> Any suggestions as to how to address this?
    >The problem is that bounding_box() doesn't take the transformation
    >matrix into account, and this isn't documented.
    >This confuses both you (since you expect it to work) and
    >align_string() which didn't take it into account.
    >For your case, it's much simpler to just change the size of the text,
    >rather than trying to transform it:
    > # I converted this to plain CGI for testing
    > # Find out whether the test string is wider than the image
    > if ( $initial_width > $image_width ) {
    > # Find the difference between the string width and the image width
    > my $difference = $initial_width - $image_width;
    > # Find the percentage the image width is of the initial width
    > my $percentage = $image_width / $initial_width;
    > $font_size *= $percentage;
    > # NOTE size parameter to bounding_box()
    > my $bbox2 = $font->bounding_box( string => $string, size =>
    >$font_size );
    > my $scaled_width = $bbox2->display_width();
    > print STDERR "Scaled width:$scaled_width\n";
    > }
    > # Place the string on the image
    > $image->align_string(
    > valign => 'center',
    > halign => 'center',
    > font => $font,
    > x => $image->getwidth / 2,
    > y => $image->getheight / 2,
    > text => $string,
    > size => $font_size, # NOTE THIS
    > );
    >This has two advantages:
    >- the code is simpler
    >- the font output remains hinted
    >The reason bounding_box() ignores the transformation matrix is that
    >most of the values won't make much sense if the matrix includes
    >rotation or shearing.
    > my $output;
    > $image->write( type => 'jpeg', data => \$output );
    >Unless you plan to render on top of photos, jpeg is about the worst
    >possible output format for this type of image.