Back to Home

True TrueType Font Names and PDF Export

truetype · pdf · fonts · windows

True TrueType Font Names and PDF Export

In Ursula Le Guin's book “The Wizard of the Seaside,” magic demanded knowledge of the “true name” of what the magician works with. I think any programmer will agree that the idea is sound. URLs, UUIDs and other unique identifiers of objects are what we deal with all the time. And, just like in the wizarding world, these true names are not so easy to find out. At least for font names it is.

I needed to implement export of text blocks to PDF in our software product. The proprietary Adobe PDF Library (http://datalogics.com/products/pdfl/) and the add-on DLI (Datalogics Library Interface) add-on are used for export. I will not delve into these libraries, I think they are of little interest to anyone. But I believe that the problem I encountered is common to any implementation of PDF export.

Each font (take, for example, Arial) has 4 different styles - regular, bold, oblique, and bold oblique. Those. Arial, Arial Bold, Arial Italic and Arial Bold Italic. Each style is stored in a separate TTF file or in a separate section of the TTC file. And if we want to print an oblique or bold font in a PDF file, we must explicitly indicate “Arial Italic” or “Arial Bold” in the call to the corresponding function. But in the text block that we export, it is indicated that its font is “Arial” and the Bold and Italic attributes are set separately. And EnumFontsFamiliesEx returns us only the name “Arial” and that's it! Q How do we get the “Arial Italic” string we need?

The obvious solution — simply assigning the “Italic” line to the font name — does not always work. For example, it does not work with the font “Lucida Sans Typewriter”. The PDF library throws an error if we pass “Lucida Sans Typewriter Italic”.

The key to the decision (pun intended) is HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Fonts. Just look into the contents of this key and it becomes clear that it was necessary to transmit “Lucida Sans Typewriter Oblique”. Then everything works.
The format of the entries in this key is not documented anywhere, but it seems to be obvious:

“Arial (TrueType)” = “arial.ttf”
“Arial Italic (TrueType)” = “ariali.ttf”
“Arial Bold (TrueType)” = “ arialbd.ttf "
" Arial Bold Italic (TrueType) "=" arialbi.ttf "
“Batang & BatangChe & Gungsuh & GungsuhChe (TrueType)” = “batang.ttc”
...
“Mangal (TrueType)” = “mangal.ttf”
“Mangal Bold (TrueType)” = “mangalb.ttf”
“Meiryo & Meiryo Italic & Meiryo UI & Meiryo UI Italic (TrueType) "=" meiryo.ttc "
" Meiryo Bold & Meiryo Bold Italic & Meiryo UI Bold & Meiryo UI Bold Italic (TrueType) "=" meiryob.ttc "
" MS Gothic & MS PGothic & MS UI Gothic (TrueType) "=" msgothic.ttc "
...
" Lucida Sans
Typewriter Bold (TrueType) "=" LTYPEB.TTF "
" Lucida Sans Typewriter Bold Oblique ( TrueType) ”=“ LTYPEBO.TTF ”
“ Lucida Sans Typewriter Oblique (TrueType) ”=“ LTYPEO.TTF ”

It can be seen that for TTC collections, the fonts contained in them are indicated by “&“.

The algorithm for establishing a correspondence between the common font name and the font names is as follows: for each font name we cut one word from the end until the remainder matches any name received from EnumFontsFamiliesEx. In addition, the cut-off words are checked for coincidence with the words “Bold”, “Ilalic”, “Semibold”, “Oblique” and we remember the corresponding attribute for this style. For example, for the Lucida Sans Typewriter family:

Lucida Sans Typewriter Regular -> Lucida Sans Typewriter
Lucida Sans Typewriter Bold -> Lucida Sans Typewriter
Lucida Sans Typewriter Oblique -> Lucida Sans Typewriter
Lucida Sans Typewriter Bold Oblique ->Lucida Sans Typewriter Bold -> Lucida Sans Typewriter

Now if you want to print the font “Lucida Sans Typewriter” bold and slanted, we know that the name “Lucida Sans Typewriter Bold Oblique” corresponds to this font and we pass this name to the PDF library.

Here, however, another trouble awaits. For example, the font “Mangal” has only a bold face (“Mangal Bold”), but it does not have a slant. Although we can set the attribute “oblique” to this font and Windows GDI in this case will independently distort the existing style when displayed on the screen. When exporting to PDF, you will have to do it yourself. A PDF library may allow you to specify a transformation matrix for text output. For example, in my case, it looked like this:

ASFixedMatrix fontSkew;
if (bSimulateItalic)
{
double angle = 15;
fontSkew.a = fixedOne; // x scale
fontSkew.b = fixedZero; // rotate & skew
fontSkew.c = FloatToASFixed (tan (_PI * angle / 180)); // rotate & skew
fontSkew.d = fixedOne; // y scale
fontSkew.h = 0; // x translation
fontSkew.v = 0; // y translation
dlpdfcontentfontskew (..., & fontSkew);
}

I did not find a beautiful solution to imitate bold type. I just print a line that needs to be bold, several times with a slight shift. Visually, everything looks fine, but it is frustrating that the text in the PDF file is duplicated.

But this is not the end. The product we are developing has a Japanese version. Therefore, special attention is paid to the correct work with Asian fonts. And here two more problems come out:
  • A font with the name “MS P ゴ シ ッ ク” is not present in HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Fonts and it turns out that we cannot find out the font names for this font.
  • The PDF library does not understand font names in Unicode at all.

Let's start with the first problem (although historically it all started with the second, but for the coherence of the story it’s easier). Google tells us that the font “MS P ゴ シ ッ ク” is actually MS Gothic. It turns out that he gets a Japanese name if a Japanese locale is set in the system. Moreover, in the registry, of course, he remains under the name MS Gothic. This turns out to be the regular behavior of EnumFontsFamiliesEx. Here is a quote from the documentation for it: “The fonts for many East Asian languages ​​have two typeface names an English name and a localized name. "EnumFonts, EnumFontFamilies, and EnumFontFamiliesEx return the English typeface name if the system locale does not match the language of the font."

By the way, if we find out that “MS P ゴ シ ッ ク” is “MS Gothic”, then this also solves the second problem, at least for the case when the English name is stored in the registry. We just transfer the name “MS Gothic” to the PDF library and it works. It remains to establish this correspondence.
For most styles from HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Fonts, we have mapped the font names from EnumFontsFamiliesEx. But for some styles, no pair was found. Still - in the registry we have “MS Gothic”, and EnumFontsFamiliesEx returned “MS P ゴ シ ッ ク”.
In this case, it remains only to independently parse the TTF / TTC file and find the corresponding Japanese name there.

Parsing a TTC / TTF file is a simple task. For a working sample, you can take the source code of the “ttf2eot” projectcode.google.com/p/ttf2eot . The TTF / TTC format itself is well documented on the Microsoft website: www.microsoft.com/typography/otspec . Please note that all data in TTF is stored in big endian format, so all numbers and Unicode strings must be converted before use.

Unfortunately, I have no right to lay out my code, so I’ll just write here what to look for.

We are interested in the “name” table www.microsoft.com/typography/otspec/name.htm . Select records with:

  • nPlatformId = 3: Windows. I assume that if the font is installed under Windows, then these entries should be there. Maybe I'm wrong, but let such a font first meet, then we'll figure it out.
  • nNameId = 1: Font Family name. Up to four fonts can share the Font Family name, forming a font style linking group (regular, italic, bold, bold italic - as defined by OS / 2.fsSelection bit settings). Those. this is exactly the name that EnumFontFamiliesEx returns.
  • nEncodingId = 0 - single-byte ASCII string or 1 - double-byte USC2 string. The rest of the encodings can be ignored: the specification explicitly requires that at least one of these two encodings is present: “When building a Unicode font for Windows, the platform ID should be 3 and the encoding ID should be 1. When building a symbol font for Windows, the platform ID should be 3 and the encoding ID should be 0. ”


One of the names found will match some name from EnumFontFamiliesEx.

For example, for the “Meiryo Bold Italic” style, analyzing meiryob.ttc, we learn that the name “メ イ リ オ” from EnumFontFamiliesEx corresponds to this style.

It remains to be seen whether this style is bold and oblique. The idea begs to take this information from the font too, but, as it turned out experimentally, these attributes in the font file may be incorrect. Therefore, we take them from the name of the outline (“Meiryo Bold Italic”), as already done above. We will only cut off the words until the remainder matches any name extracted from the TTF file, and not from the output of EnumFontFamiliesEx.

Thus, if you want to export a text block in oblique and bold with the name “メ イ リ オ”, we transfer the name “Meiryo Bold Italic” to the PDF library. Profit!

Read Next