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