You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 ?
The text was updated successfully, but these errors were encountered:
@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.
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:
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:
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:
IMAGE_CANVAS_SYSTEM_FONT_PATH
which points to "system" fonts.Image/Canvas/Fonts
which can hold fonts (a kind of local font path).Image_Canvas_Tool::fontMap
. This method will look intoImage/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 inIMAGE_CANVAS_SYSTEM_FONT_PATH
and inImage/Canvas/Fonts
(again). In theory, this method can look for other formats.Problems
The experience with PS summarize the problems:
ps_findfont
to load a file, etc. This is not always handled correctly.Here is a more detailed list of problems:
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.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.Image_Canvas_Tool::fontMap
can look for other formats but the call is buried inImage_Canvas::setFont
so not easy to overload.Solutions
Here is what I propose:
Image_Canvas
should not try to find the font file (i.e. don't callImage_Canvas_Tool::fontMap
). This is a responsibility of the drivers (hence, they can use the same logic to find the format they need).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.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 ?
The text was updated successfully, but these errors were encountered: