3

I'm looking to see if there is a way, in PHP, to determine if a glyph exists for a given character in a font.

My use case is this - I'm generating small images using Imagick - essentially small "badges" given user-provided info, and I'd really like to support full Unicode, including emoji and whatnot. As of now, I have a handful of fonts that each support a "class" of characters well (e.g., my "main" font is Futura, and I have Symbola for emoji and other symbols, and I may need to add another font for Eastern glyphs), but they don't have enough overlap to only use one font.

I've seen a post that suggests the commercial PDFlib add-on can do this, but I'd like to avoid commercial add-ons if I can. I also saw that the PECL PS add-on has ps_symbol_name(), but this requires an AFM file, and as far as I can tell, I can't use that with multibyte fonts.

I've got the font switching part taken care of in Imagick - I just need to know how I can tell it, programmatically, what font to use for a given character. Thanks!

Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
csyria
  • 190
  • 8

2 Answers2

4

Here is another solution for checking if a UTF-8 character is supported by a given font (OTF / TTF) using PHP.

  1. Extract the list of all supported code points from your font
  2. Convert your character / string to list of corresponding code points
  3. Compare the code points of your string with the list of supported code points by your font to determine if they are supported

I would suggest using an existing library like pdf-font-lib to extract the list of supported code points from your font.

To convert your UTF-8 string into code points you can use this code snippet.

Here is a complete example for checking if all letters of a given string a supported by a OTF font. (needs php-font-lib, font not included)

This approach can also be used as basis for a simple approach to detect the best font for rending a given UTF-8 string:

  1. Go through all existing fonts
  2. Compare coverage of string by supported characters for each font in percentage
  3. Pick the font with the highest coverage or default font as fallback
Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
2

Depending on the complexity of what you need to do, have a look at https://github.com/pomax/php-font-parser, which I wrote for the same purpose (although using gd rather than imagemagick).

Note that only CMAP 4 and 12 are supported, which covers UCS-2 and UCS-4. Higher code points probably won't be found even if they exist in the font (mostly because when I wrote this, Unicode hadn't been polluted with emoji yet).

Alternatively, you can use something like the AdobeFDK's tx program, running it against your font through shell-exec or the like, to see if it finds a glyph definition, or you can run the entire font through ttx, save the CMAP table's XML as its own file, and then just run your checks against that (which is a very reliable solution if your font is unlikely to change a lot)

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • Thank you so much! I did end up going the ttx route, since it seemed like the simplest/least processor intensive option, given that my fonts will change at most once a year. Now... to solve the kerning issues when I switch from one typeface to another. :/ Hats off to you for your work on php-font-parser - this is definitely more complicated than I expected. – csyria Apr 30 '15 at 02:18