The BlueValues Array & Setting Its Values

When hinting name- or CID-keyed fonts, appropriate hinting parameters are required. One of these parameters are alignment zones whose purpose is to snap shapes to pixel boundaries. Alignment zones are specified in the required /BlueValues array, and also in the optional /OtherBlues array.

The required /BlueValues array is specified in the /Private dictionary of name-keyed fonts, and in the /Private dictionary of each FDArray element of CID-keyed fonts. The purpose of this array is to specify alignment zones that are at the baseline or above, such as for the baseline, x-height, and cap-height. The optional /OtherBlues array is used to specify alignment zones that are below the baseline, such as for the descender. This article will demonstrate how the AFDKO stemHist tool can be used to determine appropriate alignment zone values.

CID-keyed fonts that include FDArray elements whose glyphs are Latin or Latin-like, meaning that that they rest on a baseline, and have x-height and cap-height properties, benefit from appropriate /BlueValues array settings, in the form of value-pairs. These value-pairs can be determined through careful and effective use of the stemHist tool. In my opinion, a minimum of three value-pairs should be included in a /BlueValues array for Latin glyphs, which correspond to the baseline, x-height, and cap-height.

The stemHist tool’s “-a” option specifies that alignment zone information is to be computed, and its “-g” option is used to specify glyphs within the font. For the purpose of this article, we will use the Adobe-Japan1-6 CID ranges that correspond to the ASCII digits (CIDs 17–26), the uppercase Alphabet (CIDs 34–59), and the lowercase Alphabet (CIDs 66–91). For name-keyed fonts, these CID ranges correspond to ‘zero’ through ‘nine’, ‘A’ through ‘Z’, and ‘a’ through ‘z’, respectively. When run with the “-a” option, the stemHist tool output two files: *.top.txt and *.bot.txt. The asterisked portion represents the filename of the font resource that was specified.

CJK Alignment Zones

For name-keyed fonts whose glyphs are primarily CJK, such as kana fonts, and for the FDArray elements of CID-keyed fonts that correspond to CJK glyphs, such as kana, ideographs, and Korean hangul syllables, along with most symbols, specifying alignment zones can be detrimental, mainly because these glyphs are usually centered in the em-box, optically or otherwise. For such fonts, the following (fixed) /BlueValues array is recommended, because it places alignment zones outside of the em-box so that they do not influence the glyphs:

/BlueValues [-250 -250 1100 1100] def

This /BlueValues array places a single-unit alignment zone at Y-axis coordinate -250, and another one at 1100.

Setting the Baseline & its Overshoot

The first value-pair in a /BlueValues array must be the baseline, which is in the form of the baseline overshoot, usually a negative value, followed by the baseline. Assuming that the CID-keyed font resource is a file named “,” the following command line can be used to determine the baseline value-pair:

% stemHist -a -g /17-/26,/34-/59,/66-/91

The baseline and its overshoot are bottom zones, so the resulting “” file is inspected for suitable values. For typical Latin glyphs whose baseline is at Y-axis coordinate 0 (zero), a large number of glyphs should have this value, or one very close to it. The baseline overshoot is typically a negative value that is 10 to 20 units below the baseline. Below is sample output for KozGoPr6N-Medium:

Bottom Zone List for on Mon Apr 2 14:20:54 2012
Count Bottom Zone Glyph List
1 -249 ['cid00090']
1 -237 ['cid00075']
2 -235 ['cid00072', 'cid00072']
44 -11 ['cid00017', 'cid00017', 'cid00020', 'cid00020', 'cid00022', 'cid00022', 'cid00023', 'cid00023', 'cid00025', 'cid00025', 'cid00036', 'cid00036', 'cid00043', 'cid00043', 'cid00048', 'cid00048', 'cid00050', 'cid00050', 'cid00052', 'cid00052', 'cid00054', 'cid00054', 'cid00066', 'cid00066', 'cid00067', 'cid00067', 'cid00068', 'cid00068', 'cid00069', 'cid00069', 'cid00070', 'cid00070', 'cid00080', 'cid00080', 'cid00081', 'cid00081', 'cid00082', 'cid00082', 'cid00084', 'cid00084', 'cid00085', 'cid00085', 'cid00086', 'cid00086']
2 -10 ['cid00026', 'cid00026']
2 -8 ['cid00040', 'cid00040']
4 -7 ['cid00035', 'cid00035', 'cid00037', 'cid00037']
42 0 ['cid00018', 'cid00019', 'cid00019', 'cid00021', 'cid00024', 'cid00034', 'cid00038', 'cid00038', 'cid00039', 'cid00041', 'cid00042', 'cid00044', 'cid00045', 'cid00045', 'cid00046', 'cid00047', 'cid00049', 'cid00051', 'cid00053', 'cid00055', 'cid00055', 'cid00056', 'cid00056', 'cid00057', 'cid00058', 'cid00059', 'cid00059', 'cid00071', 'cid00073', 'cid00074', 'cid00076', 'cid00077', 'cid00078', 'cid00079', 'cid00083', 'cid00087', 'cid00087', 'cid00088', 'cid00088', 'cid00089', 'cid00091', 'cid00091']
1 3 ['cid00072']
1 199 ['cid00021']
1 225 ['cid00034']
1 249 ['cid00070']
1 271 ['cid00026']
1 277 ['cid00066']
1 295 ['cid00049']
1 319 ['cid00040']
1 324 ['cid00051']
1 336 ['cid00039']
1 348 ['cid00041']
1 351 ['cid00038']
1 360 ['cid00035']
1 361 ['cid00020']
1 395 ['cid00022']
1 410 ['cid00023']
1 420 ['cid00088']
1 452 ['cid00083']
1 457 ['cid00091']
2 464 ['cid00071', 'cid00085']
2 467 ['cid00073', 'cid00079']
1 468 ['cid00078']
3 470 ['cid00067', 'cid00081', 'cid00082']
3 471 ['cid00068', 'cid00069', 'cid00072']
1 476 ['cid00080']
2 478 ['cid00066', 'cid00084']
1 480 ['cid00070']
1 617 ['cid00056']
2 636 ['cid00074', 'cid00075']
1 639 ['cid00046']
1 644 ['cid00021']
2 657 ['cid00022', 'cid00024']
1 665 ['cid00034']
1 666 ['cid00053']
3 668 ['cid00038', 'cid00039', 'cid00059']
1 671 ['cid00019']
2 672 ['cid00020', 'cid00023']
1 673 ['cid00017']
1 675 ['cid00040']
2 679 ['cid00036', 'cid00037']
3 680 ['cid00026', 'cid00049', 'cid00052']
1 681 ['cid00051']
2 682 ['cid00048', 'cid00050']
1 683 ['cid00035']
1 684 ['cid00025']
1 720 ['cid00071']

In this particular example, there are 42 instances of Y-axis coordinate 0 (zero), and 44 instances of -11. Thus, 0 and -11 are suitable values for the baseline and its overshoot. Our example /BlueValues array begins as follows:

/BlueValues [-11 0] def

Setting the x-Height & its Overshoot

The x-height value-pair is best determined by specifying only the glyphs for the lowercase Alphabet, as shown in the command line below:

% stemHist -a -g /66-/91

The x-height is a top zone, so the “” file is checked:

Top Zone List for on Mon Apr 2 14:26:00 2012
Count Top Zone Glyph List
2 813 ['cid00071', 'cid00071']
5 802 ['cid00067', 'cid00069', 'cid00073', 'cid00076', 'cid00077']
4 771 ['cid00074', 'cid00074', 'cid00075', 'cid00075']
1 687 ['cid00085']
25 563 ['cid00066', 'cid00066', 'cid00067', 'cid00068', 'cid00068', 'cid00069', 'cid00070', 'cid00070', 'cid00072', 'cid00072', 'cid00073', 'cid00078', 'cid00078', 'cid00079', 'cid00079', 'cid00080', 'cid00080', 'cid00081', 'cid00081', 'cid00082', 'cid00082', 'cid00083', 'cid00083', 'cid00084', 'cid00084']
1 552 ['cid00086']
9 551 ['cid00071', 'cid00085', 'cid00087', 'cid00088', 'cid00088', 'cid00089', 'cid00090', 'cid00091', 'cid00091']
1 355 ['cid00066']
1 332 ['cid00070']
1 118 ['cid00087']
1 111 ['cid00088']
1 94 ['cid00091']
1 92 ['cid00072']
1 85 ['cid00086']
1 84 ['cid00085']
1 83 ['cid00069']
3 82 ['cid00067', 'cid00068', 'cid00082']
1 81 ['cid00081']
1 78 ['cid00070']
1 76 ['cid00080']
1 75 ['cid00084']
1 74 ['cid00066']
1 -144 ['cid00072']

The appropriate x-height value would be 551 (nine instances), and its overshoot would be 563 (25 instances). If you look carefully, you will also notice an ascender-height value of 802 (five instances), and its overshoot value of 813 (2 instances). This gives us two more value-pairs for our growing /BlueValues array:

/BlueValues [-11 0 551 563 802 813] def

Setting the Cap-Height & its Overshoot

Determining an appropriate cap-height value-pair is done much in the same way as above, except that the CIDs for the uppercase Alphabet should be specified as the argument of the stemHist tool’s “-g” option, as follows:

% stemHist -a -g /34-/59

The resulting “” is as follows:

Top Zone List for on Mon Apr 2 14:33:42 2012
Count Top Zone Glyph List
6 777 ['cid00048', 'cid00048', 'cid00050', 'cid00050', 'cid00052', 'cid00052']
2 776 ['cid00036', 'cid00036']
2 773 ['cid00040', 'cid00040']
8 771 ['cid00035', 'cid00035', 'cid00037', 'cid00037', 'cid00049', 'cid00049', 'cid00051', 'cid00051']
5 766 ['cid00041', 'cid00043', 'cid00046', 'cid00046', 'cid00055']
19 765 ['cid00034', 'cid00034', 'cid00038', 'cid00038', 'cid00039', 'cid00039', 'cid00042', 'cid00044', 'cid00045', 'cid00047', 'cid00053', 'cid00053', 'cid00054', 'cid00056', 'cid00056', 'cid00057', 'cid00058', 'cid00059', 'cid00059']
1 450 ['cid00041']
1 447 ['cid00038']
1 446 ['cid00035']
1 432 ['cid00039']
1 412 ['cid00040']
1 411 ['cid00051']
1 387 ['cid00049']
1 314 ['cid00034']
1 135 ['cid00056']
1 123 ['cid00055']
2 98 ['cid00045', 'cid00059']
1 97 ['cid00038']
1 88 ['cid00043']
3 87 ['cid00036', 'cid00040', 'cid00052']
1 86 ['cid00037']
3 84 ['cid00048', 'cid00050', 'cid00054']
1 82 ['cid00035']

765 (19 instances) is an appropriate cap-height value, and 777 (six instances) serves as its overshoot value. We end up with the following fully-specified /BlueValues array when this fourth value-pair is added (in ascending order):

/BlueValues [-11 0 551 563 765 777 802 813] def

If the font includes Latin or Latin-like glyphs with a significant number of descenders, these can be specified in much the same way, but in the optional /OtherBlues array. These are bottom zones, so the *.bot.txt is inspected to determine an appropriate value-pair.

NOTE: The stemHist command lines provided above, when used with a name-keyed font whose glyphs are named according to standard conventions, should substitute the CID ranges with glyph-name ranges, as follows:

% stemHist -a -g zero-nine,A-Z,a-z font.pfa
% stemHist -a -g a-z font.pfa
% stemHist -a -g A-Z font.pfa

Comments are closed.