1 /* $XConsortium: sptobdf.c,v 1.5 94/04/17 20:17:51 dpw Exp $ */
2 /*
3 * Copyright 1990, 1991 Network Computing Devices;
4 * Portions Copyright 1987 by Digital Equipment Corporation
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the names of Network Computing Devices and
11 * Digital not be used in advertising or publicity pertaining to
12 * distribution of the software without specific, written prior permission.
13 * Network Computing Devices and Digital make no representations about the
14 * suitability of this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
16 *
17 * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
18 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19 * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
20 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 *
25 * Dave Lemke
26 */
27
28 /*
29
30 Copyright (c) 1987, 1994 X Consortium
31
32 Permission is hereby granted, free of charge, to any person obtaining
33 a copy of this software and associated documentation files (the
34 "Software"), to deal in the Software without restriction, including
35 without limitation the rights to use, copy, modify, merge, publish,
36 distribute, sublicense, and/or sell copies of the Software, and to
37 permit persons to whom the Software is furnished to do so, subject to
38 the following conditions:
39
40 The above copyright notice and this permission notice shall be included
41 in all copies or substantial portions of the Software.
42
43 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
44 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
45 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
46 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
47 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
48 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
49 OTHER DEALINGS IN THE SOFTWARE.
50
51 Except as contained in this notice, the name of the X Consortium shall
52 not be used in advertising or otherwise to promote the sale, use or
53 other dealings in this Software without prior written authorization
54 from the X Consortium.
55
56 */
57
58 /*
59 * Speedo outline to BFD format converter
60 */
61
62 #include <stdio.h>
63 #include "speedo.h"
64
65 #ifdef EXTRAFONTS
66 #include "ncdkeys.h"
67 #else
68 #include "keys.h"
69 #endif
70
71 #include "iso8859.h"
72
73 #define MAX_BITS 1024
74
75 #define BBOX_CLIP
76
77 static char line_of_bits[MAX_BITS + 1];
78
79 static FILE *fp;
80 static ufix16 char_index,
81 char_id;
82 static buff_t font;
83 static buff_t char_data;
84 static ufix8 *f_buffer,
85 *c_buffer;
86 static ufix16 mincharsize;
87 static fix15 cur_y;
88 static fix15 bit_width,
89 bit_height;
90
91 static ufix8 key[] =
92 {
93 KEY0,
94 KEY1,
95 KEY2,
96 KEY3,
97 KEY4,
98 KEY5,
99 KEY6,
100 KEY7,
101 KEY8
102 }; /* Font decryption key */
103
104
105 static char *progname;
106 static char *fontname = NULL;
107 static char *fontfile = NULL;
108
109 static int point_size = 120;
110 static int x_res = 72;
111 static int y_res = 72;
112 static int quality = 0;
113 static int iso_encoding = 1;
114
115 static int num_props = 7;
116 static int stretch = 120;
117
118 static specs_t specs;
119
120 static void dump_header();
121
122 static void
usage()123 usage()
124 {
125 fprintf(stderr, "Usage: %s [-xres x resolution] [-yres y resolution]\n\t[-ptsize pointsize] [-fn fontname] [-q quality (0-1)] fontfile\n", progname);
126 fprintf(stderr, "Where:\n");
127 fprintf(stderr, "-xres specifies the X resolution (72)\n");
128 fprintf(stderr, "-yres specifies the Y resolution (72)\n");
129 fprintf(stderr, "-pts specifies the pointsize in decipoints (120)\n");
130 fprintf(stderr, "-fn specifies the font name (full Bitstream name)\n");
131 fprintf(stderr, "-q specifies the font quality [0-1] (0)\n");
132 fprintf(stderr, "\n");
133 exit(0);
134 }
135
136 static fix15
read_2b(ptr)137 read_2b(ptr)
138 ufix8 *ptr;
139 {
140 fix15 tmp;
141
142 tmp = *ptr++;
143 tmp = (tmp << 8) + *ptr;
144 return tmp;
145 }
146
147 static fix31
read_4b(ptr)148 read_4b(ptr)
149 ufix8 *ptr;
150 {
151 fix31 tmp;
152
153 tmp = *ptr++;
154 tmp = (tmp << 8) + *ptr++;
155 tmp = (tmp << 8) + *ptr++;
156 tmp = (tmp << 8) + *ptr;
157 return tmp;
158 }
159
160 static void
process_args(ac,av)161 process_args(ac, av)
162 int ac;
163 char **av;
164 {
165 int i;
166
167 for (i = 1; i < ac; i++) {
168 if (!strncmp(av[i], "-xr", 3)) {
169 if (av[i + 1]) {
170 x_res = atoi(av[++i]);
171 } else
172 usage();
173 } else if (!strncmp(av[i], "-yr", 3)) {
174 if (av[i + 1]) {
175 y_res = atoi(av[++i]);
176 } else
177 usage();
178 } else if (!strncmp(av[i], "-pt", 3)) {
179 if (av[i + 1]) {
180 point_size = atoi(av[++i]);
181 } else
182 usage();
183 } else if (!strncmp(av[i], "-fn", 3)) {
184 if (av[i + 1]) {
185 fontname = av[++i];
186 } else
187 usage();
188 } else if (!strncmp(av[i], "-q", 2)) {
189 if (av[i + 1]) {
190 quality = atoi(av[++i]);
191 } else
192 usage();
193 } else if (!strncmp(av[i], "-st", 3)) {
194 if (av[i + 1]) {
195 stretch = atoi(av[++i]);
196 } else
197 usage();
198 } else if (!strncmp(av[i], "-noni", 5)) {
199 iso_encoding = 0;
200 } else if (*av[i] == '-') {
201 usage();
202 } else
203 fontfile = av[i];
204 }
205 if (!fontfile)
206 usage();
207 }
208
209 void
main(argc,argv)210 main(argc, argv)
211 int argc;
212 char **argv;
213 {
214 ufix32 i;
215 ufix8 tmp[16];
216 ufix32 minbufsize;
217 ufix16 cust_no;
218 int first_char_index,
219 num_chars;
220
221 progname = argv[0];
222 process_args(argc, argv);
223 fp = fopen(fontfile, "r");
224 if (!fp) {
225 fprintf(stderr, "No such font file, \"%s\"\n", fontfile);
226 exit(-1);
227 }
228 if (fread(tmp, sizeof(ufix8), 16, fp) != 16) {
229 fprintf(stderr, "error reading \"%s\"\n", fontfile);
230 exit(-1);
231 }
232 minbufsize = (ufix32) read_4b(tmp + FH_FBFSZ);
233 f_buffer = (ufix8 *) malloc(minbufsize);
234 if (!f_buffer) {
235 fprintf(stderr, "can't get %x bytes of memory\n", minbufsize);
236 exit(-1);
237 }
238 fseek(fp, (ufix32) 0, 0);
239
240 if (fread(f_buffer, sizeof(ufix8), (ufix16) minbufsize, fp) != minbufsize) {
241 fprintf(stderr, "error reading file \"%s\"\n", fontfile);
242 exit(-1);
243 }
244 mincharsize = read_2b(f_buffer + FH_CBFSZ);
245
246 c_buffer = (ufix8 *) malloc(mincharsize);
247 if (!c_buffer) {
248 fprintf(stderr, "can't get %x bytes for char buffer\n", mincharsize);
249 exit(-1);
250 }
251 /* init */
252 sp_reset();
253
254 font.org = f_buffer;
255 font.no_bytes = minbufsize;
256
257 if ((cust_no = sp_get_cust_no(font)) != CUS0) {
258 fprintf(stderr, "Non-standard encryption for \"%s\"\n", fontfile);
259 exit(-1);
260 }
261 sp_set_key(key);
262
263 first_char_index = read_2b(f_buffer + FH_FCHRF);
264 num_chars = read_2b(f_buffer + FH_NCHRL);
265
266 /* set up specs */
267 /* Note that point size is in decipoints */
268 specs.pfont = &font;
269 /* XXX beware of overflow */
270 specs.xxmult = point_size * x_res / 720 * (1 << 16);
271 specs.xymult = 0L << 16;
272 specs.xoffset = 0L << 16;
273 specs.yxmult = 0L << 16;
274 specs.yymult = point_size * y_res / 720 * (1 << 16);
275 specs.yoffset = 0L << 16;
276 switch (quality) {
277 case 0:
278 specs.flags = 0;
279 break;
280 case 1:
281 specs.flags = MODE_SCREEN;
282 break;
283 case 2:
284 specs.flags = MODE_2D;
285 break;
286 default:
287 fprintf(stderr, "bogus quality value %d\n", quality);
288 break;
289 }
290 specs.out_info = NULL;
291
292 if (!fontname) {
293 fontname = (char *) (f_buffer + FH_FNTNM);
294 }
295 if (iso_encoding)
296 num_chars = num_iso_chars;
297 dump_header(num_chars);
298
299 if (!sp_set_specs(&specs)) {
300 fprintf(stderr, "can't set specs\n");
301 } else {
302 if (iso_encoding) {
303 for (i = 0; i < num_iso_chars * 2; i += 2) {
304 char_index = iso_map[i + 1];
305 char_id = iso_map[i];
306 if (!sp_make_char(char_index)) {
307 fprintf(stderr, "can't make char %x\n", char_index);
308 }
309 }
310 } else {
311 for (i = 0; i < num_chars; i++) {
312 char_index = i + first_char_index;
313 char_id = sp_get_char_id(char_index);
314 if (char_id) {
315 if (!sp_make_char(char_index)) {
316 fprintf(stderr, "can't make char %x\n", char_index);
317 }
318 }
319 }
320 }
321 }
322
323 (void) fclose(fp);
324
325 printf("ENDFONT\n");
326 exit(0);
327 }
328
329 static void
dump_header(num_chars)330 dump_header(num_chars)
331 ufix32 num_chars;
332 {
333 fix15 xmin,
334 ymin,
335 xmax,
336 ymax;
337 fix15 ascent,
338 descent;
339 fix15 pixel_size;
340
341 xmin = read_2b(f_buffer + FH_FXMIN);
342 ymin = read_2b(f_buffer + FH_FYMIN);
343 xmax = read_2b(f_buffer + FH_FXMAX);
344 ymax = read_2b(f_buffer + FH_FYMAX);
345 pixel_size = point_size * x_res / 720;
346
347 printf("STARTFONT 2.1\n");
348 printf("COMMENT\n");
349 printf("COMMENT Generated from Bitstream Speedo outlines via sptobdf\n");
350 printf("COMMENT\n");
351 printf("FONT %s\n", fontname);
352 printf("SIZE %d %d %d\n", pixel_size, x_res, y_res);
353 printf("FONTBOUNDINGBOX %d %d %d %d\n", xmin, ymin, xmax, ymax);
354 printf("STARTPROPERTIES %d\n", num_props);
355
356 printf("RESOLUTION_X %d\n", x_res);
357 printf("RESOLUTION_Y %d\n", y_res);
358 printf("POINT_SIZE %d\n", point_size);
359 printf("PIXEL_SIZE %d\n", pixel_size);
360 printf("COPYRIGHT \"%s\"\n", f_buffer + FH_CPYRT);
361
362 /* do some stretching here so that its isn't too tight */
363 pixel_size = pixel_size * stretch / 100;
364 ascent = pixel_size * 764 / 1000; /* 764 == EM_TOP */
365 descent = pixel_size - ascent;
366 printf("FONT_ASCENT %d\n", ascent);
367 printf("FONT_DESCENT %d\n", descent);
368
369 printf("ENDPROPERTIES\n");
370 printf("CHARS %d\n", num_chars);
371 }
372
373 buff_t *
sp_load_char_data(file_offset,num,cb_offset)374 sp_load_char_data(file_offset, num, cb_offset)
375 fix31 file_offset;
376 fix15 num;
377 fix15 cb_offset;
378 {
379 if (fseek(fp, (long) file_offset, (int) 0)) {
380 fprintf(stderr, "can't seek to char\n");
381 (void) fclose(fp);
382 exit(-1);
383 }
384 if ((num + cb_offset) > mincharsize) {
385 fprintf(stderr, "char buf overflow\n");
386 (void) fclose(fp);
387 exit(-2);
388 }
389 if (fread((c_buffer + cb_offset), sizeof(ufix8), num, fp) != num) {
390 fprintf(stderr, "can't get char data\n");
391 exit(-1);
392 }
393 char_data.org = (ufix8 *) c_buffer + cb_offset;
394 char_data.no_bytes = num;
395
396 return &char_data;
397 }
398
399 /*
400 * Called by Speedo character generator to report an error.
401 *
402 * Since character data not available is one of those errors
403 * that happens many times, don't report it to user
404 */
405 void
sp_report_error(n)406 sp_report_error(n)
407 fix15 n;
408 {
409 switch (n) {
410 case 1:
411 fprintf(stderr, "Insufficient font data loaded\n");
412 break;
413 case 3:
414 fprintf(stderr, "Transformation matrix out of range\n");
415 break;
416 case 4:
417 fprintf(stderr, "Font format error\n");
418 break;
419 case 5:
420 fprintf(stderr, "Requested specs not compatible with output module\n");
421 break;
422 case 7:
423 fprintf(stderr, "Intelligent transformation requested but not supported\n");
424 break;
425 case 8:
426 fprintf(stderr, "Unsupported output mode requested\n");
427 break;
428 case 9:
429 fprintf(stderr, "Extended font loaded but only compact fonts supported\n");
430 break;
431 case 10:
432 fprintf(stderr, "Font specs not set prior to use of font\n");
433 break;
434 case 12:
435 break;
436 case 13:
437 fprintf(stderr, "Track kerning data not available()\n");
438 break;
439 case 14:
440 fprintf(stderr, "Pair kerning data not available()\n");
441 break;
442 default:
443 fprintf(stderr, "report_error(%d)\n", n);
444 break;
445 }
446 }
447
448 void
sp_open_bitmap(x_set_width,y_set_width,xorg,yorg,xsize,ysize)449 sp_open_bitmap(x_set_width, y_set_width, xorg, yorg, xsize, ysize)
450 fix31 x_set_width;
451 fix31 y_set_width;
452 fix31 xorg;
453 fix31 yorg;
454 fix15 xsize;
455 fix15 ysize;
456 {
457 fix15 i;
458 fix15 off_horz;
459 fix15 off_vert;
460 fix31 width,
461 pix_width;
462 bbox_t bb;
463
464 bit_width = xsize;
465
466 bit_height = ysize;
467 off_horz = (fix15) ((xorg + 32768L) >> 16);
468 off_vert = (fix15) ((yorg + 32768L) >> 16);
469
470 if (bit_width > MAX_BITS) {
471
472 #ifdef DEBUG
473 fprintf(stderr, "char wider than max bits -- truncated\n");
474 #endif
475
476 bit_width = MAX_BITS;
477 }
478 width = sp_get_char_width(char_index);
479 pix_width = width * (specs.xxmult / 65536L) +
480 ((ufix32) width * ((ufix32) specs.xxmult & 0xffff)) / 65536L;
481 pix_width /= 65536L;
482
483 width = (pix_width * 7200L) / (point_size * y_res);
484
485 (void) sp_get_char_bbox(char_index, &bb);
486 bb.xmin >>= 16;
487 bb.ymin >>= 16;
488 bb.xmax >>= 16;
489 bb.ymax >>= 16;
490
491 #ifdef DEBUG
492 if ((bb.xmax - bb.xmin) != bit_width)
493 fprintf(stderr, "bbox & width mismatch 0x%x (%d) (%d vs %d)\n",
494 char_index, char_id, (bb.xmax - bb.xmin), bit_width);
495 if ((bb.ymax - bb.ymin) != bit_height)
496 fprintf(stderr, "bbox & height mismatch 0x%x (%d) (%d vs %d)\n",
497 char_index, char_id, (bb.ymax - bb.ymin), bit_height);
498 if (bb.xmin != off_horz)
499 fprintf(stderr, "x min mismatch 0x%x (%d) (%d vs %d)\n",
500 char_index, char_id, bb.xmin, off_horz);
501 if (bb.ymin != off_vert)
502 fprintf(stderr, "y min mismatch 0x%x (%d) (%d vs %d)\n",
503 char_index, char_id, bb.ymin, off_vert);
504 #endif
505
506 #ifdef BBOX_CLIP
507 bit_width = bb.xmax - bb.xmin;
508 bit_height = bb.ymax - bb.ymin;
509 off_horz = bb.xmin;
510 off_vert = bb.ymin;
511 #endif
512
513 /* XXX kludge to handle space */
514 if (bb.xmin == 0 && bb.ymin == 0 && bb.xmax == 0 && bb.ymax == 0 &&
515 width) {
516 bit_width = 1;
517 bit_height = 1;
518 }
519 printf("STARTCHAR %d\n", char_id);
520 printf("ENCODING %d\n", char_id);
521 printf("SWIDTH %d 0\n", width);
522 printf("DWIDTH %d 0\n", pix_width);
523 printf("BBX %d %d %d %d\n", bit_width, bit_height, off_horz, off_vert);
524 printf("BITMAP\n");
525
526 for (i = 0; i < bit_width; i++) {
527 line_of_bits[i] = '.';
528 }
529 line_of_bits[bit_width] = '\0';
530 cur_y = 0;
531 }
532
533 static void
dump_line(line)534 dump_line(line)
535 ufix8 *line;
536 {
537 int bit;
538 unsigned byte;
539
540 byte = 0;
541 for (bit = 0; bit < bit_width; bit++) {
542 if (line[bit] == 'X')
543 byte |= (1 << (7 - (bit & 7)));
544 if ((bit & 7) == 7) {
545 printf("%02X", byte);
546 byte = 0;
547 }
548 }
549 if ((bit & 7) != 0)
550 printf("%02X", byte);
551 printf("\n");
552 }
553
554 #ifdef BBOX_CLIP
555 static fix15 last_y;
556 static int trunc = 0;
557
558 #endif
559
560 void
sp_set_bitmap_bits(y,xbit1,xbit2)561 sp_set_bitmap_bits(y, xbit1, xbit2)
562 fix15 y;
563 fix15 xbit1;
564 fix15 xbit2;
565 {
566 fix15 i;
567
568 if (xbit1 > MAX_BITS) {
569
570 #ifdef DEBUG
571 fprintf(stderr, "run wider than max bits -- truncated\n");
572 #endif
573
574 xbit1 = MAX_BITS;
575 }
576 if (xbit2 > MAX_BITS) {
577
578 #ifdef DEBUG
579 fprintf(stderr, "run wider than max bits -- truncated\n");
580 #endif
581
582 xbit2 = MAX_BITS;
583 }
584 while (cur_y != y) {
585 dump_line(line_of_bits);
586 for (i = 0; i < bit_width; i++) {
587 line_of_bits[i] = '.';
588 }
589 cur_y++;
590 }
591
592 #ifdef BBOX_CLIP
593 last_y = y;
594 if (y >= bit_height) {
595
596 #ifdef DEBUG
597 fprintf(stderr,
598 "y value is larger than height 0x%x (%d) -- truncated\n",
599 char_index, char_id);
600 #endif
601
602 trunc = 1;
603 return;
604 }
605 #endif /* BBOX_CLIP */
606
607 for (i = xbit1; i < xbit2; i++) {
608 line_of_bits[i] = 'X';
609 }
610 }
611
612 void
sp_close_bitmap()613 sp_close_bitmap()
614 {
615
616 #ifdef BBOX_CLIP
617 int i;
618
619 if (!trunc)
620 dump_line(line_of_bits);
621 trunc = 0;
622
623
624 last_y++;
625 while (last_y < bit_height) {
626
627 #ifdef DEBUG
628 fprintf(stderr, "padding out height for 0x%x (%d)\n",
629 char_index, char_id);
630 #endif
631
632 for (i = 0; i < bit_width; i++) {
633 line_of_bits[i] = '.';
634 }
635 dump_line(line_of_bits);
636 last_y++;
637 }
638
639 #else
640 dump_line(line_of_bits);
641 #endif
642
643 printf("ENDCHAR\n");
644 }
645
646 /* outline stubs */
647 void
sp_open_outline()648 sp_open_outline()
649 {
650 }
651
652 void
sp_start_new_char()653 sp_start_new_char()
654 {
655 }
656
657 void
sp_start_contour()658 sp_start_contour()
659 {
660 }
661
662 void
sp_curve_to()663 sp_curve_to()
664 {
665 }
666
667 void
sp_line_to()668 sp_line_to()
669 {
670 }
671
672 void
sp_close_contour()673 sp_close_contour()
674 {
675 }
676
677 void
sp_close_outline()678 sp_close_outline()
679 {
680 }
681