]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/font/Speedo/sptobdf.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / lib / font / Speedo / sptobdf.c
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
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
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
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
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
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
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     *
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
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
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
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
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
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
648 sp_open_outline()
649 {
650 }
651
652 void
653 sp_start_new_char()
654 {
655 }
656
657 void
658 sp_start_contour()
659 {
660 }
661
662 void
663 sp_curve_to()
664 {
665 }
666
667 void
668 sp_line_to()
669 {
670 }
671
672 void
673 sp_close_contour()
674 {
675 }
676
677 void
678 sp_close_outline()
679 {
680 }