1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * University Copyright- Copyright (c) 1982, 1986, 1988 35 * The Regents of the University of California 36 * All Rights Reserved 37 * 38 * University Acknowledgment- Portions of this document are derived from 39 * software developed by the University of California, Berkeley, and its 40 * contributors. 41 */ 42 43 /* Note added 9/25/83 44 Setting the parameter biggestfont in the DESC file 45 to be at least as big as the number of characters 46 in the largest font for a particular device 47 eliminates the "font X too big for position Y" 48 message from troff. 49 Thanks to Dave Stephens, WECo. 50 */ 51 /* 52 makedev: 53 read text info about a particular device 54 (e.g., cat, 202, aps5) from file, convert 55 it into internal (binary) form suitable for 56 fast reading by troff initialization (ptinit()). 57 58 Usage: 59 60 makedev DESC [ F ... ] 61 uses DESC to create a description file 62 using the information therein. 63 It creates the file DESC.out. 64 65 makedev F ... 66 makes the font tables for fonts F only, 67 creates files F.out. 68 69 DESC.out contains: 70 dev structure with fundamental sizes 71 list of sizes (nsizes+1) terminated by 0, as short's 72 indices of char names (nchtab * sizeof(short)) 73 char names as hy\0em\0... (lchname) 74 nfonts occurrences of 75 widths (nwidth) 76 kerning (nwidth) [ascender+descender only so far] 77 codes (nwidth) to drive actual typesetter 78 fitab (nchtab+128-32) 79 each of these is an array of char. 80 81 dev.filesize contains the number of bytes 82 in the file, excluding the dev part itself. 83 84 F.out contains the font header, width, kern, codes, and fitab. 85 Width, kern and codes are parallel arrays. 86 (Which suggests that they ought to be together?) 87 Later, we might allow for codes which are actually 88 sequences of formatting info so characters can be drawn. 89 */ 90 91 #include "stdio.h" 92 #include "dev.h" 93 94 #define BYTEMASK 0377 95 #define skipline(f) while(getc(f) != '\n') 96 97 struct dev dev; 98 struct Font font; 99 100 #define NSIZE 100 /* maximum number of sizes */ 101 short size[NSIZE]; 102 #define NCH 256 /* max number of characters with funny names */ 103 char chname[5*NCH]; /* character names, including \0 for each */ 104 short chtab[NCH]; /* index of character in chname */ 105 106 #define NFITAB (NCH + 128-32) /* includes ascii chars, but not non-graphics */ 107 char fitab[NFITAB]; /* font index table: position of char i on this font. */ 108 /* zero if not there */ 109 110 #define FSIZE 256 /* size of a physical font (e.g., 102 for cat) */ 111 char width[FSIZE]; /* width table for a physical font */ 112 char kern[FSIZE]; /* ascender+descender info */ 113 char code[FSIZE]; /* actual device codes for a physical font */ 114 115 #define NFONT 60 /* max number of default fonts */ 116 char fname[NFONT][10]; /* temp space to hold default font names */ 117 118 int fflag = 0; /* on if font table to be written */ 119 int fdout; /* output file descriptor */ 120 char *fout = "DESC.out"; 121 122 int main(int argc, char *argv[]) 123 { 124 FILE *fin; 125 char cmd[100], *p; 126 int i, totfont, v; 127 128 if (argc < 2) { 129 fprintf(stderr, "Usage: makedev [DESC] [fonts]\n"); 130 exit(1); 131 } 132 133 if ((fin = fopen("DESC", "r")) == NULL) { 134 fprintf(stderr, "makedev: can't open %s\n", argv[1]); 135 exit(1); 136 } 137 while (fscanf(fin, "%s", cmd) != EOF) { 138 if (cmd[0] == '#') /* comment */ 139 skipline(fin); 140 else if (strcmp(cmd, "res") == 0) { 141 fscanf(fin, "%hd", &dev.res); 142 } else if (strcmp(cmd, "hor") == 0) { 143 fscanf(fin, "%hd", &dev.hor); 144 } else if (strcmp(cmd, "vert") == 0) { 145 fscanf(fin, "%hd", &dev.vert); 146 } else if (strcmp(cmd, "unitwidth") == 0) { 147 fscanf(fin, "%hd", &dev.unitwidth); 148 } else if (strcmp(cmd, "sizescale") == 0) { 149 fscanf(fin, "%hd", &dev.sizescale); 150 } else if (strcmp(cmd, "paperwidth") == 0) { 151 fscanf(fin, "%hd", &dev.paperwidth); 152 } else if (strcmp(cmd, "paperlength") == 0) { 153 fscanf(fin, "%hd", &dev.paperlength); 154 } else if (strcmp(cmd, "biggestfont") == 0) { 155 fscanf(fin, "%hd", &dev.biggestfont); 156 } else if (strcmp(cmd, "spare2") == 0) { 157 fscanf(fin, "%hd", &dev.spare2); 158 } else if (strcmp(cmd, "sizes") == 0) { 159 dev.nsizes = 0; 160 while (fscanf(fin, "%d", &v) != EOF && v != 0) 161 size[dev.nsizes++] = v; 162 size[dev.nsizes] = 0; /* need an extra 0 at the end */ 163 } else if (strcmp(cmd, "fonts") == 0) { 164 fscanf(fin, "%hd", &dev.nfonts); 165 for (i = 0; i < dev.nfonts; i++) 166 fscanf(fin, "%s", fname[i]); 167 } else if (strcmp(cmd, "charset") == 0) { 168 p = chname; 169 dev.nchtab = 0; 170 while (fscanf(fin, "%s", p) != EOF) { 171 chtab[dev.nchtab++] = p - chname; 172 while (*p++) /* skip to end of name */ 173 ; 174 } 175 dev.lchname = p - chname; 176 chtab[dev.nchtab++] = 0; /* terminate properly */ 177 } else 178 fprintf(stderr, "makedev: unknown command %s\n", cmd); 179 } 180 if (argc > 0 && strcmp(argv[1], "DESC") == 0) { 181 fdout = creat(fout, 0666); 182 if (fdout < 0) { 183 fprintf(stderr, "makedev: can't open %s\n", fout); 184 exit(1); 185 } 186 write(fdout, &dev, sizeof(struct dev)); 187 write(fdout, size, (dev.nsizes+1) * sizeof(size[0])); /* we need a 0 on the end */ 188 write(fdout, chtab, dev.nchtab * sizeof(chtab[0])); 189 write(fdout, chname, dev.lchname); 190 totfont = 0; 191 for (i = 0; i < dev.nfonts; i++) { 192 totfont += dofont(fname[i]); 193 write(fdout, &font, sizeof(struct Font)); 194 write(fdout, width, font.nwfont & BYTEMASK); 195 write(fdout, kern, font.nwfont & BYTEMASK); 196 write(fdout, code, font.nwfont & BYTEMASK); 197 write(fdout, fitab, dev.nchtab+128-32); 198 } 199 lseek(fdout, 0L, 0); /* back to beginning to install proper size */ 200 dev.filesize = /* excluding dev struct itself */ 201 (dev.nsizes+1) * sizeof(size[0]) 202 + dev.nchtab * sizeof(chtab[0]) 203 + dev.lchname * sizeof(char) 204 + totfont * sizeof(char); 205 write(fdout, &dev, sizeof(struct dev)); 206 close(fdout); 207 argc--; 208 argv++; 209 } 210 for (i = 1; i < argc; i++) 211 dofont(argv[i]); 212 exit(0); 213 } 214 215 dofont(name) /* create fitab and width tab for font */ 216 char *name; 217 { 218 FILE *fin; 219 int fdout; 220 int i, nw, spacewidth, n, v; 221 char buf[100], ch[10], s1[10], s2[10], s3[10], cmd[30]; 222 223 if ((fin = fopen(name, "r")) == NULL) { 224 fprintf(stderr, "makedev: can't open font %s\n", name); 225 exit(2); 226 } 227 sprintf(cmd, "%s.out", name); 228 fdout = creat(cmd, 0666); 229 for (i = 0; i < NFITAB; i++) 230 fitab[i] = 0; 231 for (i = 0; i < FSIZE; i++) 232 width[i] = kern[i] = code[i] = 0; 233 font.specfont = font.ligfont = spacewidth = 0; 234 while (fscanf(fin, "%s", cmd) != EOF) { 235 if (cmd[0] == '#') 236 skipline(fin); 237 else if (strcmp(cmd, "name") == 0) 238 fscanf(fin, "%s", font.namefont); 239 else if (strcmp(cmd, "internalname") == 0) 240 fscanf(fin, "%s", font.intname); 241 else if (strcmp(cmd, "special") == 0) 242 font.specfont = 1; 243 else if (strcmp(cmd, "spare1") == 0) 244 fscanf(fin, "%1s", &font.spare1); 245 else if (strcmp(cmd, "ligatures") == 0) { 246 font.ligfont = getlig(fin); 247 } else if (strcmp(cmd, "spacewidth") == 0) { 248 fscanf(fin, "%d", &spacewidth); 249 width[0] = spacewidth; /* width of space on this font */ 250 } else if (strcmp(cmd, "charset") == 0) { 251 skipline(fin); 252 nw = 0; 253 /* widths are origin 1 so fitab==0 can mean "not there" */ 254 while (fgets(buf, 100, fin) != NULL) { 255 sscanf(buf, "%s %s %s %s", ch, s1, s2, s3); 256 if (s1[0] != '"') { /* it's a genuine new character */ 257 nw++; 258 width[nw] = atoi(s1); 259 kern[nw] = atoi(s2); 260 /* temporarily, pick up one byte as code */ 261 if (s3[0] == '0') 262 sscanf(s3, "%o", &i); 263 else 264 sscanf(s3, "%d", &i); 265 code[nw] = i; 266 } 267 /* otherwise it's a synonym for previous character, 268 /* so leave previous values intact 269 */ 270 if (strlen(ch) == 1) /* it's ascii */ 271 fitab[ch[0] - 32] = nw; /* fitab origin omits non-graphics */ 272 else { /* it has a funny name */ 273 for (i = 0; i < dev.nchtab; i++) 274 if (strcmp(&chname[chtab[i]], ch) == 0) { 275 fitab[i + 128-32] = nw; /* starts after the ascii */ 276 break; 277 } 278 if (i >= dev.nchtab) 279 fprintf(stderr, "makedev: font %s: %s not in charset\n", name, ch); 280 } 281 } 282 nw++; 283 if (dev.biggestfont >= nw) 284 n = dev.biggestfont; 285 else { 286 if (dev.biggestfont > 0) 287 fprintf(stderr, "font %s too big\n", name); 288 n = nw; 289 } 290 font.nwfont = n; 291 } 292 } 293 if (spacewidth == 0) 294 width[0] = dev.res * dev.unitwidth / 72 / 3; 295 fclose(fin); 296 297 write(fdout, &font, sizeof(struct Font)); 298 write(fdout, width, font.nwfont & BYTEMASK); 299 write(fdout, kern, font.nwfont & BYTEMASK); 300 write(fdout, code, font.nwfont & BYTEMASK); 301 write(fdout, fitab, dev.nchtab+128-32); 302 close(fdout); 303 v = sizeof(struct Font) + 3 * n + dev.nchtab + 128-32; 304 fprintf(stderr, "%3s: %3d chars, width %3d, size %3d\n", 305 font.namefont, nw, width[0], v); 306 return v; 307 } 308 309 getlig(fin) /* pick up ligature list */ 310 FILE *fin; 311 { 312 int lig; 313 char temp[100]; 314 315 lig = 0; 316 while (fscanf(fin, "%s", temp) != EOF && strcmp(temp, "0") != 0) { 317 if (strcmp(temp, "fi") == 0) 318 lig |= LFI; 319 else if (strcmp(temp, "fl") == 0) 320 lig |= LFL; 321 else if (strcmp(temp, "ff") == 0) 322 lig |= LFF; 323 else if (strcmp(temp, "ffi") == 0) 324 lig |= LFFI; 325 else if (strcmp(temp, "ffl") == 0) 326 lig |= LFFL; 327 else 328 fprintf(stderr, "illegal ligature %s\n", temp); 329 } 330 skipline(fin); 331 return lig; 332 } 333