Back in the 1980s, Adobe saw that the existing methods of displaying text digitally – bitmapped fonts – were not up to the task at hand. Due to this, Outline font technologies (in the form of PostScript, notably Type 1) were born. While TrueType joined their class later in the decade, Type 1 fonts drove the technology forward in a way few standards ever can. Even today they still see regular use.
Naturally, with such a significant and established technology, support is widespread – except on the web. Browsers have no support for Type 1 fonts at all, which leaves you with an issue.
Thankfully, Type 1 hasn’t been completely forgotten, and an ‘upgrade path’ of sorts is available. Adobe later released the Compact Font Format, which can contain the same data as a Type 1 font in a different format. When OpenType came along, the decision was made to offer two methods of storing the glyphs – using TrueType’s ‘glyf’ table, or using an entire CFF font inside a ‘cff’ table. The result is that conversion from Type 1 to OpenType is very possible.
For the average user, I’d recommend using a tool like FontForge to convert your fonts.
For us, though, that’s not an option. Fonts in PDF files are often supplemented by other data, like replacement widths and mappings in ToUnicode arrays. We’ve written our own font converter that uses some of this data to improve the output.
Perhaps unsurprisingly, our Type 1 to OpenType/WOFF converter first converts Type 1 to CFF, then builds OpenType tables to go with it. One of the more complex things involved with this is converting Type 1 glyph outlines (known as ‘Type 1 Charstrings’) to CFF glyph outlines (known as ‘Type 2 Charstrings’).
Both of these formats encode the glyphs as a string of commands which draw the path. However, these commands can also call functions, set the glyph’s width, supply hinting information, and give unwanted information about the way the glyph is being drawn. We read the type 1 streams, creating an intermediary data structure representing the commands. Commands in this structure often absorbs previous commands due to Type 2 Charstrings more compacted form. We then run through this structure and use it to generate Type 2 Charstrings.
Some commands must be adapted heavily – for instance, ‘hsbw’ in Type 1 sets the width and left side bearing of the glyph and then moves to (leftSideBearing, 0). No similar command exists in Type 2, so we store the metrics, transform it into an ‘rmoveto’ command, and deal with the glyph width after the conversion.
Type 2 has two values elsewhere in the file called defaultWidthX and nominalWidthX. The purpose of the former is obvious. The latter stores a base value which each glyph adds a value to in order to get its real width. The value is stored at the start of each glyph, so we do an extra pass to calculate what defaultWidthX and nominalWidthX should be, then store the required values at the start of each Charstring.
The conversion process also allows us to make use of some nice features of Type 2 Charstrings. Many commands like ‘rrcurveto’ take a fixed number of arguments in Type 1 while being called over and over again. In Type 2, these can take multiples of their base number of arguments, and will repeat until it’s used all the arguments supplied.
Converting the Charstrings is just one step in this process, but it’s vital for getting the existing body of Type 1 fonts in PDF files onto the web.
In general, our advice is to move towards WOFF or OTF as the best fonts for content which you want to use on the web.
Do you have any hints or tricks you want to suggest?
This post is part of our “Fonts Articles Index” in these articles we explore Fonts.
Do you need to write or read JPEG in Java?
We have an easy guide on how to write JPEG in Java using ImageIO and JDeli.
You can learn how to read/write most of the image files in ImageIO. However, it gives little control over the process.
JDeli is easy to use and offers complete support, so why not give JDeli a try?