imagick icon indicating copy to clipboard operation
imagick copied to clipboard

Default font behaviour

Open Danack opened this issue 5 years ago • 0 comments

@remicollet can you give me your thoughts on the following.

So it turns out that although drawing some text in an image works without setting a font explicitly most of the time, sometimes it doesn't.

-- START tests/279_ImagickDraw_setTextInterlineSpacing.diff
001+ Fatal error: Uncaught ImagickException: unable to read font `helvetica' @ error/annotate.c/RenderFreetype/1396 in /home/travis/build/Imagick/imagick/tests/279_ImagickDraw_setTextInterlineSpacing.php:32

The list of fonts available on that system is:

There are 34 fonts:
  Bitstream-Charter
  Bitstream-Charter-Bold
  Bitstream-Charter-Bold-Italic
  Bitstream-Charter-Italic
  Courier
  Courier-Bold
  Courier-Bold-Italic
  Courier-Italic
  DejaVu-Sans
  DejaVu-Sans-Bold
  DejaVu-Sans-Mono
  DejaVu-Sans-Mono-Bold
  DejaVu-Serif
  DejaVu-Serif-Bold
  Liberation-Mono
  Liberation-Mono-Bold
  Liberation-Mono-Bold-Italic
  Liberation-Mono-Italic
  Liberation-Sans
  Liberation-Sans-Bold
  Liberation-Sans-Bold-Italic
  Liberation-Sans-Italic
  Liberation-Sans-Narrow
  Liberation-Sans-Narrow-Bold
  Liberation-Sans-Narrow-Bold-Italic
  Liberation-Sans-Narrow-Italic
  Liberation-Serif
  Liberation-Serif-Bold
  Liberation-Serif-Bold-Italic
  Liberation-Serif-Italic
  Utopia
  Utopia-Bold
  Utopia-Bold-Italic
  Utopia-Italic

Other times the error looks more like:

-- START tests/208_ImagickDraw_setFontStretch_basic.out
php: unable to read font `(null)' @ error/annotate.c/RenderFreetype/1338.
php: unable to read font `(null)' @ error/annotate.c/RenderFreetype/1338.
Fatal error: Uncaught ImagickException: non-conforming drawing primitive definition `text' @ error/draw.c/DrawImage/3172 in /home/travis/build/Imagick/imagick/tests/208_ImagickDraw_setFontStretch_basic.php:28

On the one hand, I could just leave this as "users should choose a font". But it's kind of annoying.

Another option would be to always set the font explicitly when creating ImagickDraw object's from a list of reasonable fonts, with some code equivalent to this:

/**
 * On some systems, where the standard fonts aren't available, trying
 * to draw any text fails as the ImageMagick default font is null.
 *
 * This function just find a 'sensible' font to use, either from the
 * preferred list, or just the first one from queryFonts(). That 'probably'
 * is the right thing to do, as it makes the tests more stable.
 */
function findDefaultFont()
{
    $knownFonts = [
        'Courier',
        'Helvetica',
        'Times-Roman',
        'Liberation-Mono',
        'Utopia',
    ];

    $fontList = \Imagick::queryFonts();

    foreach ($knownFonts as $knownFont) {

        if (in_array($knownFont, $fontList, true) === true) {
            return $knownFont;
        }
    }

    if (count($fontList) !== 0) {
        return $fontList[0];
    }

    throw new \Exception("No fonts available on system, apparently.");
}

Which I'm having to do to get tests to pass.

That would be a small behaviour break for people who aren't explicitly setting a font, but would save people time and frustration in the future.

Thoughts?

Danack avatar Aug 19 '20 19:08 Danack