1 /* $XConsortium: nsample.c,v 1.3 93/10/28 15:27:12 gildea Exp $ */
5 Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
6 You are hereby granted permission under all Bitstream propriety rights to
7 use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
8 software and the Bitstream Charter outline font for any purpose and without
9 restrictions; provided, that this notice is left intact on all copies of such
10 software or font and that Bitstream's trademark is acknowledged as shown below
11 on all unmodified copies of such font.
13 BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
16 BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
17 WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
19 DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
20 INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
21 WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
26 /*************************** N S A M P L E . C *******************************
28 * SPEEDO CHARACTER GENERATOR TEST MODULE *
30 * This is an illustration of what external resources are required to *
31 * load a Speedo outline and use the Speedo character generator to generate *
32 * bitmaps or scaled outlines according to the desired specification. * *
34 * This program loads a Speedo outline, defines a set of character *
35 * generation specifications, generates bitmap (or outline) data for each *
36 * character in the font and prints them on the standard output. *
38 * If the font buffer is too small to hold the entire font, the first *
39 * part of the font is loaded. Character data is then loaded dynamically *
42 ****************************************************************************/
49 void main(int argc,char *argv[]);
54 #include "speedo.h" /* General definition for make_bmap */
55 #include "keys.h" /* Font decryption keys */
60 #define SHOW(X) printf("X = %d\n", X)
65 #define MAX_BITS 256 /* Max line length of generated bitmap */
67 /***** GLOBAL FUNCTIONS *****/
69 /***** EXTERNAL FUNCTIONS *****/
71 /***** STATIC FUNCTIONS *****/
74 fix31 read_4b(ufix8 FONTFAR *ptr);
75 fix15 read_2b(ufix8 FONTFAR *ptr);
80 /***** STATIC VARIABLES *****/
81 static char pathname[100]; /* Name of font file to be output */
82 static ufix8 FONTFAR *font_buffer; /* Pointer to allocated Font buffer */
83 static ufix8 FONTFAR *char_buffer; /* Pointer to allocate Character buffer */
84 static buff_t font; /* Buffer descriptor for font data */
86 static buff_t char_data; /* Buffer descriptor for character data */
88 static FILE *fdescr; /* Speedo outline file descriptor */
89 static ufix16 char_index; /* Index of character to be generated */
90 static ufix16 char_id; /* Character ID */
91 static ufix16 minchrsz; /* minimum character buffer size */
104 }; /* Font decryption key */
106 static fix15 raswid; /* raster width */
107 static fix15 rashgt; /* raster height */
108 static fix15 offhor; /* horizontal offset from left edge of emsquare */
109 static fix15 offver; /* vertical offset from baseline */
110 static fix15 set_width; /* character set width */
111 static fix15 y_cur; /* Current y value being generated and printed */
112 static char line_of_bits[2 * MAX_BITS + 1]; /* Buffer for row of generated bits */
115 #if INCL_BLACK || INCL_SCREEN || INCL_2D
116 bitmap_t bfuncs = { sp_open_bitmap, sp_set_bitmap_bits, sp_close_bitmap };
119 outline_t ofuncs = { sp_open_outline, sp_start_new_char, sp_start_contour, sp_curve_to,
120 sp_line_to, sp_close_contour, sp_close_outline };
125 ufix8 temp[16]; /* temp buffer for first 16 bytes of font */
128 FUNCTION void main(argc,argv)
132 ufix16 bytes_read; /* Number of bytes read from font file */
133 specs_t specs; /* Bundle of character generation specs */
134 int first_char_index; /* Index of first character in font */
135 int no_layout_chars; /* number of characters in layout */
137 ufix32 minbufsz; /* minimum font buffer size to allocate */
139 ufix8 FONTFAR *byte_ptr;
142 SPEEDO_GLOBALS* sp_global_ptr;
148 fprintf(stderr,"Usage: nsample {fontfile}\n\n");
152 sprintf(pathname, argv[1]);
154 /* Load Speedo outline file */
155 fdescr = fopen (pathname, "rb");
158 printf("****** Cannot open file %s\n", pathname);
162 /* get minimum font buffer size - read first 16 bytes to get the minimum
163 size field from the header, then allocate buffer dynamically */
165 bytes_read = fread(temp, sizeof(ufix8), 16, fdescr);
167 if (bytes_read != 16)
169 printf("****** Error on reading %s: %x\n", pathname, bytes_read);
174 minbufsz = (ufix32)read_4b(temp+FH_FBFSZ);
176 minbufsz = (ufix32)read_4b(temp+FH_FNTSZ);
177 if (minbufsz >= 0x10000)
179 printf("****** Cannot process fonts greater than 64K - use dynamic character loading configuration option\n");
185 #if (defined(M_I86SM) || defined(M_I86MM))
186 font_buffer = (ufix8 FONTFAR *)_fmalloc((ufix16)minbufsz);
188 font_buffer = (ufix8 *)malloc((ufix16)minbufsz);
191 if (font_buffer == NULL)
193 printf("****** Unable to allocate memory for font buffer\n");
199 printf("Loading font file %s\n", pathname);
202 fseek(fdescr, (ufix32)0, 0);
203 #if (defined(M_I86SM) || (defined(M_I86MM)))
204 byte_ptr = font_buffer;
205 for (i=0; i< minbufsz; i++){
209 {printf ("Premature EOF in reading font buffer, %ld bytes read\n",i);
216 bytes_read = fread((ufix8 *)font_buffer, sizeof(ufix8), (ufix16)minbufsz, fdescr);
219 printf("****** Error on reading %s: %x\n", pathname, bytes_read);
226 /* now allocate minimum character buffer */
228 minchrsz = read_2b(font_buffer+FH_CBFSZ);
229 #if (defined(M_I86SM) || (defined(M_I86MM)))
230 char_buffer = (ufix8 FONTFAR *)_fmalloc(minchrsz);
232 char_buffer = (ufix8*)malloc(minchrsz);
235 if (char_buffer == NULL)
237 printf("****** Unable to allocate memory for character buffer\n");
243 #if DYNAMIC_ALLOC || REENTRANT_ALLOC
244 sp_global_ptr = (SPEEDO_GLOBALS *)malloc(sizeof(SPEEDO_GLOBALS));
245 memset(sp_global_ptr,(ufix8)0,sizeof(SPEEDO_GLOBALS));
251 sp_reset(sp_global_ptr); /* Reset Speedo character generator */
253 sp_reset(); /* Reset Speedo character generator */
256 font.org = font_buffer;
257 font.no_bytes = bytes_read;
260 if ((cust_no=sp_get_cust_no(sp_global_ptr,font)) != CUS0 && /* NOT STANDARD ENCRYPTION */
262 if ((cust_no=sp_get_cust_no(font)) != CUS0 && /* NOT STANDARD ENCRYPTION */
267 printf("Unable to use fonts for customer number %d\n",
268 sp_get_cust_no(sp_global_ptr(font)));
270 printf("Unable to use fonts for customer number %d\n",
271 sp_get_cust_no(font));
279 sp_set_key(sp_global_ptr,key); /* Set decryption key */
281 sp_set_key(key); /* Set decryption key */
286 #if INCL_BLACK || INCL_SCREEN || INCL_2D
288 sp_set_bitmap_device(sp_global_ptr,&bfuncs,sizeof(bfuncs)); /* Set decryption key */
290 sp_set_bitmap_device(&bfuncs,sizeof(bfuncs)); /* Set decryption key */
295 sp_set_outline_device(sp_global_ptr,&ofuncs,sizeof(ofuncs)); /* Set decryption key */
297 sp_set_outline_device(&ofuncs,sizeof(ofuncs)); /* Set decryption key */
302 first_char_index = read_2b(font_buffer + FH_FCHRF);
303 no_layout_chars = read_2b(font_buffer + FH_NCHRL);
305 /* Set specifications for character to be generated */
306 specs.pfont = &font; /* Pointer to Speedo outline structure */
307 specs.xxmult = 25L << 16; /* Coeff of X to calculate X pixels */
308 specs.xymult = 0L << 16; /* Coeff of Y to calculate X pixels */
309 specs.xoffset = 0L << 16; /* Position of X origin */
310 specs.yxmult = 0L << 16; /* Coeff of X to calculate Y pixels */
311 specs.yymult = 25L << 16; /* Coeff of Y to calculate Y pixels */
312 specs.yoffset = 0L << 16; /* Position of Y origin */
313 specs.flags = 0; /* Mode flags */
314 specs.out_info = NULL;
318 if (!sp_set_specs(sp_global_ptr,&specs)) /* Set character generation specifications */
320 if (!sp_set_specs(&specs)) /* Set character generation specifications */
323 printf("****** Cannot set requested specs\n");
327 for (i = 0; i < no_layout_chars; i++) /* For each character in font */
329 char_index = i + first_char_index;
331 char_id = sp_get_char_id(sp_global_ptr,char_index);
333 char_id = sp_get_char_id(char_index);
338 if (!sp_make_char(sp_global_ptr,char_index))
340 if (!sp_make_char(char_index))
343 printf("****** Cannot generate character %d\n", char_index);
354 FUNCTION buff_t *sp_load_char_data(sp_global_ptr, file_offset, no_bytes, cb_offset)
355 SPEEDO_GLOBALS *sp_global_ptr;
357 FUNCTION buff_t *sp_load_char_data(file_offset, no_bytes, cb_offset)
359 fix31 file_offset; /* Offset in bytes from the start of the font file */
360 fix15 no_bytes; /* Number of bytes to be loaded */
361 fix15 cb_offset; /* Offset in bytes from start of char buffer */
363 * Called by Speedo character generator to request that character
364 * data be loaded from the font file into a character data buffer.
365 * The character buffer offset is zero for all characters except elements
366 * of compound characters. If a single buffer is allocated for character
367 * data, cb_offset ensures that sub-character data is loaded after the
368 * top-level compound character.
369 * Returns a pointer to a buffer descriptor.
375 printf("\nCharacter data(%d, %d, %d) requested\n", file_offset, no_bytes, cb_offset);
377 if (fseek(fdescr, (long)file_offset, (int)0) != 0)
379 printf("****** Error in seeking character\n");
384 if ((no_bytes + cb_offset) > minchrsz)
386 printf("****** Character buffer overflow\n");
391 bytes_read = fread((char_buffer + cb_offset), sizeof(ufix8), no_bytes, fdescr);
392 if (bytes_read != no_bytes)
394 printf("****** Error on reading character data\n");
400 printf("Character data loaded\n");
403 char_data.org = (ufix8 FONTFAR *)char_buffer + cb_offset;
404 char_data.no_bytes = no_bytes;
411 FUNCTION void sp_report_error(sp_global_ptr,n)
412 SPEEDO_GLOBALS *sp_global_ptr;
414 FUNCTION void sp_report_error(n)
416 fix15 n; /* Error identification number */
418 * Called by Speedo character generator to report an error.
420 * Since character data not available is one of those errors
421 * that happens many times, don't report it to user
428 printf("Insufficient font data loaded\n");
432 printf("Transformation matrix out of range\n");
436 printf("Font format error\n");
440 printf("Requested specs not compatible with output module\n");
444 printf("Intelligent transformation requested but not supported\n");
448 printf("Unsupported output mode requested\n");
452 printf("Extended font loaded but only compact fonts supported\n");
456 printf("Font specs not set prior to use of font\n");
463 printf("Track kerning data not available()\n");
467 printf("Pair kerning data not available()\n");
471 printf("report_error(%d)\n", n);
477 FUNCTION void sp_open_bitmap(sp_global_ptr, x_set_width, y_set_width, xorg, yorg, xsize, ysize)
478 SPEEDO_GLOBALS *sp_global_ptr;
480 FUNCTION void sp_open_bitmap(x_set_width, y_set_width, xorg, yorg, xsize, ysize)
483 fix31 y_set_width; /* Set width vector */
484 fix31 xorg; /* Pixel boundary at left extent of bitmap character */
485 fix31 yorg; /* Pixel boundary at right extent of bitmap character */
486 fix15 xsize; /* Pixel boundary of bottom extent of bitmap character */
487 fix15 ysize; /* Pixel boundary of top extent of bitmap character */
489 * Called by Speedo character generator to initialize a buffer prior
490 * to receiving bitmap data.
496 printf("open_bitmap(%3.1f, %3.1f, %3.1f, %3.1f, %d, %d)\n",
497 (real)x_set_width / 65536.0, (real)y_set_width / 65536.0,
498 (real)xorg / 65536.0, (real)yorg / 65536.0, (int)xsize, (int)ysize);
502 offhor = (fix15)(xorg >> 16);
503 offver = (fix15)(yorg >> 16);
505 if (raswid > MAX_BITS)
508 printf("\nCharacter index = %d, ID = %d\n", char_index, char_id);
509 printf("set width = %3.1f, %3.1f\n", (real)x_set_width / 65536.0, (real)y_set_width / 65536.0);
510 printf("X offset = %d\n", offhor);
511 printf("Y offset = %d\n\n", offver);
512 for (i = 0; i < raswid; i++)
514 line_of_bits[i << 1] = '.';
515 line_of_bits[(i << 1) + 1] = ' ';
517 line_of_bits[raswid << 1] = '\0';
522 FUNCTION void sp_set_bitmap_bits (sp_global_ptr, y, xbit1, xbit2)
523 SPEEDO_GLOBALS *sp_global_ptr;
525 FUNCTION void sp_set_bitmap_bits (y, xbit1, xbit2)
527 fix15 y; /* Scan line (0 = first row above baseline) */
528 fix15 xbit1; /* Pixel boundary where run starts */
529 fix15 xbit2; /* Pixel boundary where run ends */
532 * Called by Speedo character generator to write one row of pixels
533 * into the generated bitmap character.
540 printf("set_bitmap_bits(%d, %d, %d)\n", (int)y, (int)xbit1, (int)xbit2);
542 /* Clip runs beyond end of buffer */
543 if (xbit1 > MAX_BITS)
546 if (xbit2 > MAX_BITS)
549 /* Output backlog lines if any */
552 printf(" %s\n", line_of_bits);
553 for (i = 0; i < raswid; i++)
555 line_of_bits[i << 1] = '.';
560 /* Add bits to current line */
561 for (i = xbit1; i < xbit2; i++)
563 line_of_bits[i << 1] = 'X';
568 FUNCTION void sp_close_bitmap(sp_global_ptr)
569 SPEEDO_GLOBALS *sp_global_ptr;
571 FUNCTION void sp_close_bitmap()
574 * Called by Speedo character generator to indicate all bitmap data
575 * has been generated.
579 printf("close_bitmap()\n");
581 printf(" %s\n", line_of_bits);
586 FUNCTION void sp_open_outline(sp_global_ptr, x_set_width, y_set_width, xmin, xmax, ymin, ymax)
587 SPEEDO_GLOBALS *sp_global_ptr;
589 FUNCTION void sp_open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax)
592 fix31 y_set_width; /* Transformed escapement vector */
593 fix31 xmin; /* Minimum X value in outline */
594 fix31 xmax; /* Maximum X value in outline */
595 fix31 ymin; /* Minimum Y value in outline */
596 fix31 ymax; /* Maximum Y value in outline */
598 * Called by Speedo character generator to initialize prior to
599 * outputting scaled outline data.
602 printf("\nopen_outline(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
603 (real)x_set_width / 65536.0, (real)y_set_width / 65536.0,
604 (real)xmin / 65536.0, (real)xmax / 65536.0, (real)ymin / 65536.0, (real)ymax / 65536.0);
609 FUNCTION void sp_start_new_char(sp_global_ptr)
610 SPEEDO_GLOBALS *sp_global_ptr;
612 FUNCTION void sp_start_new_char()
615 * Called by Speedo character generator to initialize prior to
616 * outputting scaled outline data for a sub-character in a compound
620 printf("start_new_char()\n");
624 FUNCTION void sp_start_contour(sp_global_ptr, x, y, outside)
625 SPEEDO_GLOBALS *sp_global_ptr;
627 FUNCTION void sp_start_contour(x, y, outside)
629 fix31 x; /* X coordinate of start point in 1/65536 pixels */
630 fix31 y; /* Y coordinate of start point in 1/65536 pixels */
631 boolean outside; /* TRUE if curve encloses ink (Counter-clockwise) */
633 * Called by Speedo character generator at the start of each contour
634 * in the outline data of the character.
637 printf("start_contour(%3.1f, %3.1f, %s)\n",
638 (real)x / 65536.0, (real)y / 65536.0,
639 outside? "outside": "inside");
643 FUNCTION void sp_curve_to(sp_global_ptr, x1, y1, x2, y2, x3, y3)
644 SPEEDO_GLOBALS *sp_global_ptr;
646 FUNCTION void sp_curve_to(x1, y1, x2, y2, x3, y3)
648 fix31 x1; /* X coordinate of first control point in 1/65536 pixels */
649 fix31 y1; /* Y coordinate of first control point in 1/65536 pixels */
650 fix31 x2; /* X coordinate of second control point in 1/65536 pixels */
651 fix31 y2; /* Y coordinate of second control point in 1/65536 pixels */
652 fix31 x3; /* X coordinate of curve end point in 1/65536 pixels */
653 fix31 y3; /* Y coordinate of curve end point in 1/65536 pixels */
655 * Called by Speedo character generator onece for each curve in the
656 * scaled outline data of the character. This function is only called if curve
657 * output is enabled in the set_specs() call.
660 printf("curve_to(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
661 (real)x1 / 65536.0, (real)y1 / 65536.0,
662 (real)x2 / 65536.0, (real)y2 / 65536.0,
663 (real)x3 / 65536.0, (real)y3 / 65536.0);
667 FUNCTION void sp_line_to(sp_global_ptr, x, y)
668 SPEEDO_GLOBALS *sp_global_ptr;
670 FUNCTION void sp_line_to(x, y)
672 fix31 x; /* X coordinate of vector end point in 1/65536 pixels */
673 fix31 y; /* Y coordinate of vector end point in 1/65536 pixels */
675 * Called by Speedo character generator onece for each vector in the
676 * scaled outline data for the character. This include curve data that has
677 * been sub-divided into vectors if curve output has not been enabled
678 * in the set_specs() call.
681 printf("line_to(%3.1f, %3.1f)\n",
682 (real)x / 65536.0, (real)y / 65536.0);
687 FUNCTION void sp_close_contour(sp_global_ptr)
688 SPEEDO_GLOBALS *sp_global_ptr;
690 FUNCTION void sp_close_contour()
693 * Called by Speedo character generator at the end of each contour
694 * in the outline data of the character.
697 printf("close_contour()\n");
701 FUNCTION void sp_close_outline(sp_global_ptr)
702 SPEEDO_GLOBALS *sp_global_ptr;
704 FUNCTION void sp_close_outline()
707 * Called by Speedo character generator at the end of output of the
708 * scaled outline of the character.
711 printf("close_outline()\n");
716 FUNCTION fix15 read_2b(pointer)
717 ufix8 FONTFAR *pointer;
719 * Reads 2-byte field from font buffer
725 temp = (temp << 8) + *(pointer);
730 \fFUNCTION fix31 read_4b(pointer)
731 ufix8 FONTFAR *pointer;
733 * Reads 4-byte field from font buffer
739 temp = (temp << 8) + *(pointer++);
740 temp = (temp << 8) + *(pointer++);
741 temp = (temp << 8) + *(pointer);