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