Building a CID-keyed font with 64K glyphs & 256 FDArray elements

As mentioned at the end of the May 15, 2012 CJK Type Blog article, I will demonstrate in this article how to build a CID-keyed font with 64K glyphs (CIDs 0 through 65534) and 256 FDArray elements. These represent two limits that are inherent in CIDFont resources.

Again, the incredibly powerful AFDKO mergeFonts tool will perform most of the work.

The same name-keyed Type 1 font will be used, along with the same cidfontinfo file, provided below for convenience:

FontName        (UnicodeP01)
FullName        (Unicode P01)
FamilyName      (Unicode P01)
Weight          (Regular)
version         (1.000)
Registry        (Adobe)
Ordering        (Identity)
Supplement      0
XUID            [1 11 9273868]
AdobeCopyright  (Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.)
Trademark       ()
FSType          8
isFixedPitch    true
Serif           false
IsBoldStyle     false
IsItalicStyle   false

Because there will be 256 FDArray elements, 256 mergeFonts mapping files will be required. But, before we worry about building the 256 mergeFonts mapping files, we need to build a name-keyed font that includes 257 glyphs. We do this by using mergeFonts to build a name-keyed fonts with 257 glyphs, the first of which is the required .notdef glyph, along with 256 instances of the same glyph, named P_zero_one. Of course, a mergeFonts mapping file is required, which I named font.map. The following command line produces a name-keyed font, named font-new.pfa, that contains the 257 glyphs:

% mergeFonts font-new.pfa font.map font.pfa

With this 257-glyph name-keyed font, font-new.pfa, whose glyphs are named .notdef and cid1 through cid256, we are now ready to build the CID-keyed font.

To aid in the creation of the mergeFonts mapping files, I wrote a short Perl script, named mk64k256fdarray.pl, that performs the following operations:

  1. Generates 256 mergeFonts mapping files, one for each FDArray element.
  2. Names each of the FDArray elements according to the FontName as specified in the cidfontinfo file, followed by an integer value from 0 to 255. This is done by specifying this string as the argument of “mergeFonts” that is the first line of each mergeFonts mapping file.
  3. Generates, as STDOUT, a shell script that executes three mergeFonts command lines.

It would be appropriate to ask why three mergeFonts command lines are necessary. The reason is simply because the current version of mergeFonts cannot handle 256 FDArray elements at once, so two mergeFonts command lines are used to build two interim CIDFont resources, each with 128 FDArray elements. The third mergeFonts command line combines the two interim CIDFont resources into a single one with 256 FDArray elements. The only duplicate CID in the two interim CIDFont resources is CID+0, which is mandatory.

Below are the two command lines, the second of which executes the shell script that was generated by the first one:

% mk64k256fdarray.pl UnicodeP01 > cidbuild.sh
% sh ./cidbuild.sh

Note that the command-line argument, UnicodeP01, is a string that is used as part of the names for the FDArray elements. The result will be a CIDFont resource named cidfont.ps that includes 64K glyphs arranged in 256 FDArray elements. The interim CIDFont resources with 128 FDArray elements, named cidfont.1 and cidfont.2, can be removed.

If you carefully examine the Perl script, mk64k256fdarray.pl, you will note that it special-cases the following three FDArray elements:

  • 0: The mandatory .notdef glyph is added to the corresponding mergeFonts mapping file, which serves as CID+0 in the first interim CIDFont resource, cidfont.1.
  • 127: A new mergeFonts command line begins, for FDArray elements 128 through 255. And, the mandatory .notdef glyph is once again added to the corresponding mergeFonts mapping file, which serves as CID+0 in the second interim CIDFont resource, cidfont.2.
  • 255: Because the maximum CID is 65534, the last FDArray element, which includes the number 255 in its name, must include only 254 glyphs, not 256. The end range of the foreach loop is adjusted accordingly.

This article should have demonstrated that the assignment of CIDs to FDArray elements can be easily controlled by carefully constructing mergeFonts mapping files, and that the entire process can be scripted, in whatever scripting language you prefer, whether it is awk, Perl, Python, or Ruby.

Stay tuned until next week, when I will demonstrate how to use this CID-keyed font to build a fully-functional OpenType/CFF font.

One Response to Building a CID-keyed font with 64K glyphs & 256 FDArray elements

  1. Below shows the FDArray structure of the CID-keyed font, named cidfont.ps, that we built in today’s article, by using the fdarray-check.pl tool that was introduced in the February 29, 2012 CJK Type Blog article:

    % fdarray-check.pl cidfont.ps
    Detected ROS: Adobe-Identity-0
    UnicodeP01-0 (0): 0-256 (257)
    UnicodeP01-1 (1): 257-512 (256)
    UnicodeP01-2 (2): 513-768 (256)
    UnicodeP01-3 (3): 769-1024 (256)
    UnicodeP01-4 (4): 1025-1280 (256)
    UnicodeP01-5 (5): 1281-1536 (256)
    UnicodeP01-6 (6): 1537-1792 (256)
    UnicodeP01-7 (7): 1793-2048 (256)
    UnicodeP01-8 (8): 2049-2304 (256)
    UnicodeP01-9 (9): 2305-2560 (256)
    UnicodeP01-10 (10): 2561-2816 (256)
    UnicodeP01-11 (11): 2817-3072 (256)
    UnicodeP01-12 (12): 3073-3328 (256)
    UnicodeP01-13 (13): 3329-3584 (256)
    UnicodeP01-14 (14): 3585-3840 (256)
    UnicodeP01-15 (15): 3841-4096 (256)
    UnicodeP01-16 (16): 4097-4352 (256)
    UnicodeP01-17 (17): 4353-4608 (256)
    UnicodeP01-18 (18): 4609-4864 (256)
    UnicodeP01-19 (19): 4865-5120 (256)
    UnicodeP01-20 (20): 5121-5376 (256)
    UnicodeP01-21 (21): 5377-5632 (256)
    UnicodeP01-22 (22): 5633-5888 (256)
    UnicodeP01-23 (23): 5889-6144 (256)
    UnicodeP01-24 (24): 6145-6400 (256)
    UnicodeP01-25 (25): 6401-6656 (256)
    UnicodeP01-26 (26): 6657-6912 (256)
    UnicodeP01-27 (27): 6913-7168 (256)
    UnicodeP01-28 (28): 7169-7424 (256)
    UnicodeP01-29 (29): 7425-7680 (256)
    UnicodeP01-30 (30): 7681-7936 (256)
    UnicodeP01-31 (31): 7937-8192 (256)
    UnicodeP01-32 (32): 8193-8448 (256)
    UnicodeP01-33 (33): 8449-8704 (256)
    UnicodeP01-34 (34): 8705-8960 (256)
    UnicodeP01-35 (35): 8961-9216 (256)
    UnicodeP01-36 (36): 9217-9472 (256)
    UnicodeP01-37 (37): 9473-9728 (256)
    UnicodeP01-38 (38): 9729-9984 (256)
    UnicodeP01-39 (39): 9985-10240 (256)
    UnicodeP01-40 (40): 10241-10496 (256)
    UnicodeP01-41 (41): 10497-10752 (256)
    UnicodeP01-42 (42): 10753-11008 (256)
    UnicodeP01-43 (43): 11009-11264 (256)
    UnicodeP01-44 (44): 11265-11520 (256)
    UnicodeP01-45 (45): 11521-11776 (256)
    UnicodeP01-46 (46): 11777-12032 (256)
    UnicodeP01-47 (47): 12033-12288 (256)
    UnicodeP01-48 (48): 12289-12544 (256)
    UnicodeP01-49 (49): 12545-12800 (256)
    UnicodeP01-50 (50): 12801-13056 (256)
    UnicodeP01-51 (51): 13057-13312 (256)
    UnicodeP01-52 (52): 13313-13568 (256)
    UnicodeP01-53 (53): 13569-13824 (256)
    UnicodeP01-54 (54): 13825-14080 (256)
    UnicodeP01-55 (55): 14081-14336 (256)
    UnicodeP01-56 (56): 14337-14592 (256)
    UnicodeP01-57 (57): 14593-14848 (256)
    UnicodeP01-58 (58): 14849-15104 (256)
    UnicodeP01-59 (59): 15105-15360 (256)
    UnicodeP01-60 (60): 15361-15616 (256)
    UnicodeP01-61 (61): 15617-15872 (256)
    UnicodeP01-62 (62): 15873-16128 (256)
    UnicodeP01-63 (63): 16129-16384 (256)
    UnicodeP01-64 (64): 16385-16640 (256)
    UnicodeP01-65 (65): 16641-16896 (256)
    UnicodeP01-66 (66): 16897-17152 (256)
    UnicodeP01-67 (67): 17153-17408 (256)
    UnicodeP01-68 (68): 17409-17664 (256)
    UnicodeP01-69 (69): 17665-17920 (256)
    UnicodeP01-70 (70): 17921-18176 (256)
    UnicodeP01-71 (71): 18177-18432 (256)
    UnicodeP01-72 (72): 18433-18688 (256)
    UnicodeP01-73 (73): 18689-18944 (256)
    UnicodeP01-74 (74): 18945-19200 (256)
    UnicodeP01-75 (75): 19201-19456 (256)
    UnicodeP01-76 (76): 19457-19712 (256)
    UnicodeP01-77 (77): 19713-19968 (256)
    UnicodeP01-78 (78): 19969-20224 (256)
    UnicodeP01-79 (79): 20225-20480 (256)
    UnicodeP01-80 (80): 20481-20736 (256)
    UnicodeP01-81 (81): 20737-20992 (256)
    UnicodeP01-82 (82): 20993-21248 (256)
    UnicodeP01-83 (83): 21249-21504 (256)
    UnicodeP01-84 (84): 21505-21760 (256)
    UnicodeP01-85 (85): 21761-22016 (256)
    UnicodeP01-86 (86): 22017-22272 (256)
    UnicodeP01-87 (87): 22273-22528 (256)
    UnicodeP01-88 (88): 22529-22784 (256)
    UnicodeP01-89 (89): 22785-23040 (256)
    UnicodeP01-90 (90): 23041-23296 (256)
    UnicodeP01-91 (91): 23297-23552 (256)
    UnicodeP01-92 (92): 23553-23808 (256)
    UnicodeP01-93 (93): 23809-24064 (256)
    UnicodeP01-94 (94): 24065-24320 (256)
    UnicodeP01-95 (95): 24321-24576 (256)
    UnicodeP01-96 (96): 24577-24832 (256)
    UnicodeP01-97 (97): 24833-25088 (256)
    UnicodeP01-98 (98): 25089-25344 (256)
    UnicodeP01-99 (99): 25345-25600 (256)
    UnicodeP01-100 (100): 25601-25856 (256)
    UnicodeP01-101 (101): 25857-26112 (256)
    UnicodeP01-102 (102): 26113-26368 (256)
    UnicodeP01-103 (103): 26369-26624 (256)
    UnicodeP01-104 (104): 26625-26880 (256)
    UnicodeP01-105 (105): 26881-27136 (256)
    UnicodeP01-106 (106): 27137-27392 (256)
    UnicodeP01-107 (107): 27393-27648 (256)
    UnicodeP01-108 (108): 27649-27904 (256)
    UnicodeP01-109 (109): 27905-28160 (256)
    UnicodeP01-110 (110): 28161-28416 (256)
    UnicodeP01-111 (111): 28417-28672 (256)
    UnicodeP01-112 (112): 28673-28928 (256)
    UnicodeP01-113 (113): 28929-29184 (256)
    UnicodeP01-114 (114): 29185-29440 (256)
    UnicodeP01-115 (115): 29441-29696 (256)
    UnicodeP01-116 (116): 29697-29952 (256)
    UnicodeP01-117 (117): 29953-30208 (256)
    UnicodeP01-118 (118): 30209-30464 (256)
    UnicodeP01-119 (119): 30465-30720 (256)
    UnicodeP01-120 (120): 30721-30976 (256)
    UnicodeP01-121 (121): 30977-31232 (256)
    UnicodeP01-122 (122): 31233-31488 (256)
    UnicodeP01-123 (123): 31489-31744 (256)
    UnicodeP01-124 (124): 31745-32000 (256)
    UnicodeP01-125 (125): 32001-32256 (256)
    UnicodeP01-126 (126): 32257-32512 (256)
    UnicodeP01-127 (127): 32513-32768 (256)
    UnicodeP01-128 (128): 32769-33024 (256)
    UnicodeP01-129 (129): 33025-33280 (256)
    UnicodeP01-130 (130): 33281-33536 (256)
    UnicodeP01-131 (131): 33537-33792 (256)
    UnicodeP01-132 (132): 33793-34048 (256)
    UnicodeP01-133 (133): 34049-34304 (256)
    UnicodeP01-134 (134): 34305-34560 (256)
    UnicodeP01-135 (135): 34561-34816 (256)
    UnicodeP01-136 (136): 34817-35072 (256)
    UnicodeP01-137 (137): 35073-35328 (256)
    UnicodeP01-138 (138): 35329-35584 (256)
    UnicodeP01-139 (139): 35585-35840 (256)
    UnicodeP01-140 (140): 35841-36096 (256)
    UnicodeP01-141 (141): 36097-36352 (256)
    UnicodeP01-142 (142): 36353-36608 (256)
    UnicodeP01-143 (143): 36609-36864 (256)
    UnicodeP01-144 (144): 36865-37120 (256)
    UnicodeP01-145 (145): 37121-37376 (256)
    UnicodeP01-146 (146): 37377-37632 (256)
    UnicodeP01-147 (147): 37633-37888 (256)
    UnicodeP01-148 (148): 37889-38144 (256)
    UnicodeP01-149 (149): 38145-38400 (256)
    UnicodeP01-150 (150): 38401-38656 (256)
    UnicodeP01-151 (151): 38657-38912 (256)
    UnicodeP01-152 (152): 38913-39168 (256)
    UnicodeP01-153 (153): 39169-39424 (256)
    UnicodeP01-154 (154): 39425-39680 (256)
    UnicodeP01-155 (155): 39681-39936 (256)
    UnicodeP01-156 (156): 39937-40192 (256)
    UnicodeP01-157 (157): 40193-40448 (256)
    UnicodeP01-158 (158): 40449-40704 (256)
    UnicodeP01-159 (159): 40705-40960 (256)
    UnicodeP01-160 (160): 40961-41216 (256)
    UnicodeP01-161 (161): 41217-41472 (256)
    UnicodeP01-162 (162): 41473-41728 (256)
    UnicodeP01-163 (163): 41729-41984 (256)
    UnicodeP01-164 (164): 41985-42240 (256)
    UnicodeP01-165 (165): 42241-42496 (256)
    UnicodeP01-166 (166): 42497-42752 (256)
    UnicodeP01-167 (167): 42753-43008 (256)
    UnicodeP01-168 (168): 43009-43264 (256)
    UnicodeP01-169 (169): 43265-43520 (256)
    UnicodeP01-170 (170): 43521-43776 (256)
    UnicodeP01-171 (171): 43777-44032 (256)
    UnicodeP01-172 (172): 44033-44288 (256)
    UnicodeP01-173 (173): 44289-44544 (256)
    UnicodeP01-174 (174): 44545-44800 (256)
    UnicodeP01-175 (175): 44801-45056 (256)
    UnicodeP01-176 (176): 45057-45312 (256)
    UnicodeP01-177 (177): 45313-45568 (256)
    UnicodeP01-178 (178): 45569-45824 (256)
    UnicodeP01-179 (179): 45825-46080 (256)
    UnicodeP01-180 (180): 46081-46336 (256)
    UnicodeP01-181 (181): 46337-46592 (256)
    UnicodeP01-182 (182): 46593-46848 (256)
    UnicodeP01-183 (183): 46849-47104 (256)
    UnicodeP01-184 (184): 47105-47360 (256)
    UnicodeP01-185 (185): 47361-47616 (256)
    UnicodeP01-186 (186): 47617-47872 (256)
    UnicodeP01-187 (187): 47873-48128 (256)
    UnicodeP01-188 (188): 48129-48384 (256)
    UnicodeP01-189 (189): 48385-48640 (256)
    UnicodeP01-190 (190): 48641-48896 (256)
    UnicodeP01-191 (191): 48897-49152 (256)
    UnicodeP01-192 (192): 49153-49408 (256)
    UnicodeP01-193 (193): 49409-49664 (256)
    UnicodeP01-194 (194): 49665-49920 (256)
    UnicodeP01-195 (195): 49921-50176 (256)
    UnicodeP01-196 (196): 50177-50432 (256)
    UnicodeP01-197 (197): 50433-50688 (256)
    UnicodeP01-198 (198): 50689-50944 (256)
    UnicodeP01-199 (199): 50945-51200 (256)
    UnicodeP01-200 (200): 51201-51456 (256)
    UnicodeP01-201 (201): 51457-51712 (256)
    UnicodeP01-202 (202): 51713-51968 (256)
    UnicodeP01-203 (203): 51969-52224 (256)
    UnicodeP01-204 (204): 52225-52480 (256)
    UnicodeP01-205 (205): 52481-52736 (256)
    UnicodeP01-206 (206): 52737-52992 (256)
    UnicodeP01-207 (207): 52993-53248 (256)
    UnicodeP01-208 (208): 53249-53504 (256)
    UnicodeP01-209 (209): 53505-53760 (256)
    UnicodeP01-210 (210): 53761-54016 (256)
    UnicodeP01-211 (211): 54017-54272 (256)
    UnicodeP01-212 (212): 54273-54528 (256)
    UnicodeP01-213 (213): 54529-54784 (256)
    UnicodeP01-214 (214): 54785-55040 (256)
    UnicodeP01-215 (215): 55041-55296 (256)
    UnicodeP01-216 (216): 55297-55552 (256)
    UnicodeP01-217 (217): 55553-55808 (256)
    UnicodeP01-218 (218): 55809-56064 (256)
    UnicodeP01-219 (219): 56065-56320 (256)
    UnicodeP01-220 (220): 56321-56576 (256)
    UnicodeP01-221 (221): 56577-56832 (256)
    UnicodeP01-222 (222): 56833-57088 (256)
    UnicodeP01-223 (223): 57089-57344 (256)
    UnicodeP01-224 (224): 57345-57600 (256)
    UnicodeP01-225 (225): 57601-57856 (256)
    UnicodeP01-226 (226): 57857-58112 (256)
    UnicodeP01-227 (227): 58113-58368 (256)
    UnicodeP01-228 (228): 58369-58624 (256)
    UnicodeP01-229 (229): 58625-58880 (256)
    UnicodeP01-230 (230): 58881-59136 (256)
    UnicodeP01-231 (231): 59137-59392 (256)
    UnicodeP01-232 (232): 59393-59648 (256)
    UnicodeP01-233 (233): 59649-59904 (256)
    UnicodeP01-234 (234): 59905-60160 (256)
    UnicodeP01-235 (235): 60161-60416 (256)
    UnicodeP01-236 (236): 60417-60672 (256)
    UnicodeP01-237 (237): 60673-60928 (256)
    UnicodeP01-238 (238): 60929-61184 (256)
    UnicodeP01-239 (239): 61185-61440 (256)
    UnicodeP01-240 (240): 61441-61696 (256)
    UnicodeP01-241 (241): 61697-61952 (256)
    UnicodeP01-242 (242): 61953-62208 (256)
    UnicodeP01-243 (243): 62209-62464 (256)
    UnicodeP01-244 (244): 62465-62720 (256)
    UnicodeP01-245 (245): 62721-62976 (256)
    UnicodeP01-246 (246): 62977-63232 (256)
    UnicodeP01-247 (247): 63233-63488 (256)
    UnicodeP01-248 (248): 63489-63744 (256)
    UnicodeP01-249 (249): 63745-64000 (256)
    UnicodeP01-250 (250): 64001-64256 (256)
    UnicodeP01-251 (251): 64257-64512 (256)
    UnicodeP01-252 (252): 64513-64768 (256)
    UnicodeP01-253 (253): 64769-65024 (256)
    UnicodeP01-254 (254): 65025-65280 (256)
    UnicodeP01-255 (255): 65281-65534 (254)