SVGGraph 2.28

Published

Over the years that I have been working on SVGGraph I have always been grumbling about text. Don't get me wrong - SVG is perfectly capable of displaying text, the problem is that I can never be sure what it is going to look like.

Version 2.28 is an attempt to improve things by using font metrics to calculate the sizes of strings of text more accurately. The two example graphs below demonstrate the difference between the new method and the older method.

Using metrics
no_font_metrics = true

Both graphs are using the "Times New Roman" font, where it is easy to see that "Amanda" is a longer string than "Illicit". The new method is used for the left-hand graph, where it displays the label boxes packed quite closely to the text. The old method is enabled with the new no_font_metrics option, shown in the right-hand graph. The label box is a bit tight around "Amanda", but much too wide for "Illicit". There is more space at the left side of the graph too, because the old method thinks the seven-character string "Illicit" should be longer than the six characters of "Amanda".

To use metrics for calculating measurements SVGGraph obviously needs a source of metrics. I thought about using existing font metrics files, but there are so many different font formats available that it didn't seem sensible to pick one. It didn't seem particularly sensible to make up my own format either, but that is what I have done. The metrics files are kept in a subdirectory called "fonts", and are stored in UTF-8 JSON format. The file contains the width of each character, the width of kerning pairs, and a few other fields for calculating height and vertical offset.

I've generated metrics files for these common fonts: Arial, Arial Black, Calibri, Cambria, Candara, Comic Sans MS, Consolas, Constantia, Corbel, Courier New, Georgia, Impact, Palatino Linotype, Times New Roman, Trebuchet MS and Verdana. There are several other, smaller JSON files used for font mappings, so "Times" will load the "Times New Roman" font metrics and "Helvetica" will load "Arial", etc. The format of those files is easy enough to create by hand, for example the "serif.json" file contains {"map":"times_new_roman"}

If you're not happy with the list of fonts available I've also included the browser-based script I used to create the metrics, which you will find in the file "measurer.html". The script allows you to choose a font, pick which characters to measure, test the measurements and download the metrics as a new JSON file. The script will also be useful if you want to use characters not in the main Latin set, like Cyrillic or Greek. You can also run the script on Arabic, Chinese or any other characters from the Unicode standard, but I don't know if the resulting metrics will be any better than going without.

Note: metrics are just measurements, not font files. The fonts you use in your SVG must be available where the SVG is rendered, which usually means in a browser somewhere. The browser will substitute missing fonts when rendering the SVG, but SVGGraph has no way of knowing that is going to happen and can only use one set of measurements - so try to avoid using fonts that your end users will not have available.

Another note: the text measurement functions use UTF-8 throughout. SVGGraph will attempt to convert other encodings using the iconv or mbstring extensions, but I strongly recommend using UTF-8 if at all possible.

Final note: the default fonts used by SVGGraph have changed from "monospace" to "Courier New" and from "sans-serif" to "Times New Roman". The reason for this is that the actual fonts used for "monospace" and "sans-serif" are dependent on browser settings, and can therefore vary widely.

The new version is available from the downloads page, GitHub and via Composer.

« Previous: JPEG Saver 5.1 Next: JPEG Saver 5.1.1 »