Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Font handling #10

Open
duboism opened this issue Dec 31, 2024 · 2 comments
Open

Font handling #10

duboism opened this issue Dec 31, 2024 · 2 comments

Comments

@duboism
Copy link
Contributor

duboism commented Dec 31, 2024

I took a bit of time to understand how font handling works in this library and I want to discuss some improvements.

Context

To give you a bit of context I was trying to make tests for PS canvas work (see this branch). As a reminder, this code uses the PS extension itself based on pslib.

The blocking point is that PS canvas can't find the font. There are several reasons to that:

  • First of all by default this driver uses the Helvetica font which is proprietary and is not installed on my system (other drivers use Time New Roman which can be installed simply from MS Core Fonts).
  • Even if I try to change for another font, I need to convert it to AFM format.
  • Even with that, to use a font, one has to call ps_findfont which ultimately call PS_findfont which by default looks only in the current directory so one has to play with the SearchPath parameter.

I think this was working on Windows since Helvetica is bundled on such systems and the code was written to find it (see below).

I also took some time on that because I want to port the PDF canvas to FPDF which also uses a different font format (a PHP file to be created by some internal tools from the TTF file).

How fonts are handled?

Fonts can become rather complicated (formats, terminology, conventions, etc). AFAICS the user of the library has 2 options:

  • specify simple font properties (name, size, color, etc)
  • specify the font file

This is a rather good mix of simplicity/flexibility. The driver is in charge of finding and using the correct font according to this (if possible).

From an implementation point of view, the tricky point is to find font files. Here is what I found:

  • There is a constant called IMAGE_CANVAS_SYSTEM_FONT_PATH which points to "system" fonts.
  • There is also a local directory in Image/Canvas/Fonts which can hold fonts (a kind of local font path).
  • To find a font file, one has to call the method Image_Canvas_Tool::fontMap. This method will look into Image/Canvas/Fonts to translate a font name to a TTF file based on a text file (IIUC it can handle several files per font). If it can't find the file, it will look in IMAGE_CANVAS_SYSTEM_FONT_PATH and in Image/Canvas/Fonts (again). In theory, this method can look for other formats.

Problems

The experience with PS summarize the problems:

  • Default values are not consistent/realistic
  • Different drivers use different formats for the font and need some internal calls to manage the fonts: for instance, GD use a number to specify standard fonts but can also load a TTF file, pslib need to call ps_findfont to load a file, etc. This is not always handled correctly.

Here is a more detailed list of problems:

  • The code to set IMAGE_CANVAS_SYSTEM_FONT_PATH is windows specific (based on $_SERVER['SystemRoot']). This explain why I think that PS tests used to work on windows. As it is a constant, the user can't tune it.
  • The translation mechanism in Image_Canvas_Tool::fontMap is interesting there is no help to use it (i.e. installing fonts in it). As an aside, the current text files contains values but not the corresponding fonts.
  • In theory, Image_Canvas_Tool::fontMap can look for other formats but the call is buried in Image_Canvas::setFont so not easy to overload.

Solutions

Here is what I propose:

  • Use Time New Roman as the default font everywhere.
  • The base class Image_Canvas should not try to find the font file (i.e. don't call Image_Canvas_Tool::fontMap). This is a responsibility of the drivers (hence, they can use the same logic to find the format they need).
  • The code to define IMAGE_CANVAS_SYSTEM_FONT_PATH could be extended to test reasonable values for Linux and MacOS and give the user some way to add paths.
  • Provide ways to install fonts in Image/Canvas/Fonts and query installed fonts in the local font path with the translation mechanism. This way, the user can add fonts. Also if a driver needs a specific format, it can add the font here. As a bonus, add a method to simply install MS Core Fonts (to ease tests).

I think that those solutions are not too hard to implement.

Any idea ?

@ashnazg
Copy link
Member

ashnazg commented Jan 4, 2025

@duboism , sounds reasonable to me... given that I think #9 will require an API version bump, these changes could also go alongside as part of the larger version bump.

@duboism
Copy link
Contributor Author

duboism commented Jan 4, 2025

Thanks for your valuable comment. I will work on this ASAP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants