2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
23 #include "pa_enabl.h" //$$POLY_ACC
39 #define MAX_OPEN_FONTS 50
40 #define FILENAME_LEN 13
42 typedef struct openfont {
43 char filename[FILENAME_LEN];
47 //list of open fonts, for use (for now) for palette remapping
48 openfont open_font[MAX_OPEN_FONTS];
50 #define FONT grd_curcanv->cv_font
51 #define FG_COLOR grd_curcanv->cv_font_fg_color
52 #define BG_COLOR grd_curcanv->cv_font_bg_color
53 #define FWIDTH FONT->ft_w
54 #define FHEIGHT FONT->ft_h
55 #define FBASELINE FONT->ft_baseline
56 #define FFLAGS FONT->ft_flags
57 #define FMINCHAR FONT->ft_minchar
58 #define FMAXCHAR FONT->ft_maxchar
59 #define FDATA FONT->ft_data
60 #define FCHARS FONT->ft_chars
61 #define FWIDTHS FONT->ft_widths
63 #define BITS_TO_BYTES(x) (((x)+7)>>3)
65 int gr_internal_string_clipped(int x, int y, char *s );
66 int gr_internal_string_clipped_m(int x, int y, char *s );
68 ubyte *find_kern_entry(grs_font *font,ubyte first,ubyte second)
70 ubyte *p=font->ft_kerndata;
73 if (p[0]==first && p[1]==second)
81 //takes the character AFTER being offset into font
82 #define INFONT(_c) ((_c >= 0) && (_c <= FMAXCHAR-FMINCHAR))
84 //takes the character BEFORE being offset into current font
85 void get_char_width(ubyte c,ubyte c2,int *width,int *spacing)
91 if (!INFONT(letter)) { //not in font, draw as space
93 if (FFLAGS & FT_PROPORTIONAL)
100 if (FFLAGS & FT_PROPORTIONAL)
101 *width = FWIDTHS[letter];
107 if (FFLAGS & FT_KERNED) {
110 if (!(c2==0 || c2=='\n')) {
113 letter2 = c2-FMINCHAR;
115 if (INFONT(letter2)) {
117 p = find_kern_entry(FONT,letter,letter2);
126 int get_centered_x(char *s)
130 for (w=0;*s!=0 && *s!='\n';s++) {
131 get_char_width(s[0],s[1],&w2,&s2);
135 return ((grd_curcanv->cv_bitmap.bm_w - w) / 2);
139 int gr_internal_string0(int x, int y, char *s )
142 ubyte * text_ptr, * next_row, * text_ptr1;
143 int r, BitMask, i, bits, width, spacing, letter, underline;
146 unsigned int VideoOffset, VideoOffset1;
148 VideoOffset1 = y * ROWSIZE + x;
152 while (next_row != NULL )
154 text_ptr1 = next_row;
157 if (x==0x8000) { //centered
158 int xx = get_centered_x(text_ptr1);
159 VideoOffset1 = y * ROWSIZE + xx;
162 for (r=0; r<FHEIGHT; r++)
165 text_ptr = text_ptr1;
167 VideoOffset = VideoOffset1;
171 if (*text_ptr == '\n' )
173 next_row = &text_ptr[1];
177 if (*text_ptr == CC_COLOR) {
178 FG_COLOR = *(text_ptr+1);
183 if (*text_ptr == CC_LSPACING) {
184 skip_lines = *(text_ptr+1) - '0';
190 if (*text_ptr == CC_UNDERLINE )
192 if ((r==FBASELINE+2) || (r==FBASELINE+3))
197 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
199 letter = *text_ptr-FMINCHAR;
201 if (!INFONT(letter)) { //not in font, draw as space
202 VideoOffset += spacing;
207 if (FFLAGS & FT_PROPORTIONAL)
210 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
213 for (i=0; i< width; i++ )
214 DATA[VideoOffset++] = FG_COLOR;
217 fp += BITS_TO_BYTES(width)*r;
221 for (i=0; i< width; i++ )
229 DATA[VideoOffset++] = FG_COLOR;
231 DATA[VideoOffset++] = BG_COLOR;
236 VideoOffset += spacing-width; //for kerning
241 VideoOffset1 += ROWSIZE; y++;
245 VideoOffset1 += ROWSIZE * skip_lines;
251 int gr_internal_string0m(int x, int y, char *s )
254 ubyte * text_ptr, * next_row, * text_ptr1;
255 int r, BitMask, i, bits, width, spacing, letter, underline;
258 unsigned int VideoOffset, VideoOffset1;
260 VideoOffset1 = y * ROWSIZE + x;
264 while (next_row != NULL )
266 text_ptr1 = next_row;
269 if (x==0x8000) { //centered
270 int xx = get_centered_x(text_ptr1);
271 VideoOffset1 = y * ROWSIZE + xx;
274 for (r=0; r<FHEIGHT; r++)
277 text_ptr = text_ptr1;
279 VideoOffset = VideoOffset1;
283 if (*text_ptr == '\n' )
285 next_row = &text_ptr[1];
289 if (*text_ptr == CC_COLOR) {
290 FG_COLOR = *(text_ptr+1);
295 if (*text_ptr == CC_LSPACING) {
296 skip_lines = *(text_ptr+1) - '0';
302 if (*text_ptr == CC_UNDERLINE )
304 if ((r==FBASELINE+2) || (r==FBASELINE+3))
309 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
311 letter = *text_ptr-FMINCHAR;
313 if (!INFONT(letter)) { //not in font, draw as space
314 VideoOffset += spacing;
319 if (FFLAGS & FT_PROPORTIONAL)
322 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
325 for (i=0; i< width; i++ )
326 DATA[VideoOffset++] = FG_COLOR;
329 fp += BITS_TO_BYTES(width)*r;
333 for (i=0; i< width; i++ )
341 DATA[VideoOffset++] = FG_COLOR;
349 VideoOffset += spacing-width;
352 VideoOffset1 += ROWSIZE; y++;
355 VideoOffset1 += ROWSIZE * skip_lines;
362 int gr_internal_string2(int x, int y, char *s )
365 char * text_ptr, * next_row, * text_ptr1;
366 int r, BitMask, i, bits, width, spacing, letter, underline;
367 int page_switched, skip_lines = 0;
369 unsigned int VideoOffset, VideoOffset1;
371 VideoOffset1 = (unsigned int)DATA + y * ROWSIZE + x;
373 gr_vesa_setpage(VideoOffset1 >> 16);
375 VideoOffset1 &= 0xFFFF;
379 while (next_row != NULL )
381 text_ptr1 = next_row;
384 if (x==0x8000) { //centered
385 int xx = get_centered_x(text_ptr1);
386 VideoOffset1 = y * ROWSIZE + xx;
387 gr_vesa_setpage(VideoOffset1 >> 16);
388 VideoOffset1 &= 0xFFFF;
391 for (r=0; r<FHEIGHT; r++)
393 text_ptr = text_ptr1;
395 VideoOffset = VideoOffset1;
401 if (*text_ptr == '\n' )
403 next_row = &text_ptr[1];
407 if (*text_ptr == CC_COLOR) {
408 FG_COLOR = *(text_ptr+1);
413 if (*text_ptr == CC_LSPACING) {
414 skip_lines = *(text_ptr+1) - '0';
420 if (*text_ptr == CC_UNDERLINE )
422 if ((r==FBASELINE+2) || (r==FBASELINE+3))
427 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
429 Assert(width==spacing); //no kerning support here
431 letter = *text_ptr-FMINCHAR;
433 if (!INFONT(letter)) { //not in font, draw as space
434 VideoOffset += spacing;
439 if (FFLAGS & FT_PROPORTIONAL)
442 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
446 if ( VideoOffset+width > 0xFFFF )
448 for (i=0; i< width; i++ )
450 gr_video_memory[VideoOffset++] = FG_COLOR;
452 if (VideoOffset > 0xFFFF )
454 VideoOffset -= 0xFFFF + 1;
462 for (i=0; i< width; i++ )
463 gr_video_memory[VideoOffset++] = FG_COLOR;
472 fp += BITS_TO_BYTES(width)*r;
476 if ( VideoOffset+width > 0xFFFF )
478 for (i=0; i< width; i++ )
486 gr_video_memory[VideoOffset++] = FG_COLOR;
488 gr_video_memory[VideoOffset++] = BG_COLOR;
492 if (VideoOffset > 0xFFFF )
494 VideoOffset -= 0xFFFF + 1;
506 if (bits & 0x80) gr_video_memory[VideoOffset+0] = FG_COLOR;
507 else gr_video_memory[VideoOffset+0] = BG_COLOR;
509 if (bits & 0x40) gr_video_memory[VideoOffset+1] = FG_COLOR;
510 else gr_video_memory[VideoOffset+1] = BG_COLOR;
512 if (bits & 0x20) gr_video_memory[VideoOffset+2] = FG_COLOR;
513 else gr_video_memory[VideoOffset+2] = BG_COLOR;
515 if (bits & 0x10) gr_video_memory[VideoOffset+3] = FG_COLOR;
516 else gr_video_memory[VideoOffset+3] = BG_COLOR;
518 if (bits & 0x08) gr_video_memory[VideoOffset+4] = FG_COLOR;
519 else gr_video_memory[VideoOffset+4] = BG_COLOR;
521 if (bits & 0x04) gr_video_memory[VideoOffset+5] = FG_COLOR;
522 else gr_video_memory[VideoOffset+5] = BG_COLOR;
524 if (bits & 0x02) gr_video_memory[VideoOffset+6] = FG_COLOR;
525 else gr_video_memory[VideoOffset+6] = BG_COLOR;
527 if (bits & 0x01) gr_video_memory[VideoOffset+7] = FG_COLOR;
528 else gr_video_memory[VideoOffset+7] = BG_COLOR;
532 for (i=0; i< width/2 ; i++ )
540 gr_video_memory[VideoOffset++] = FG_COLOR;
542 gr_video_memory[VideoOffset++] = BG_COLOR;
554 gr_video_memory[VideoOffset++] = FG_COLOR;
556 gr_video_memory[VideoOffset++] = BG_COLOR;
566 VideoOffset1 += ROWSIZE;
568 if (VideoOffset1 > 0xFFFF ) {
569 VideoOffset1 -= 0xFFFF + 1;
576 VideoOffset1 += ROWSIZE * skip_lines;
582 int gr_internal_string2m(int x, int y, char *s )
585 char * text_ptr, * next_row, * text_ptr1;
586 int r, BitMask, i, bits, width, spacing, letter, underline;
587 int page_switched, skip_lines = 0;
589 unsigned int VideoOffset, VideoOffset1;
591 VideoOffset1 = (unsigned int)DATA + y * ROWSIZE + x;
593 gr_vesa_setpage(VideoOffset1 >> 16);
595 VideoOffset1 &= 0xFFFF;
599 while (next_row != NULL )
601 text_ptr1 = next_row;
604 if (x==0x8000) { //centered
605 int xx = get_centered_x(text_ptr1);
606 VideoOffset1 = y * ROWSIZE + xx;
607 gr_vesa_setpage(VideoOffset1 >> 16);
608 VideoOffset1 &= 0xFFFF;
611 for (r=0; r<FHEIGHT; r++)
613 text_ptr = text_ptr1;
615 VideoOffset = VideoOffset1;
621 if (*text_ptr == '\n' )
623 next_row = &text_ptr[1];
627 if (*text_ptr == CC_COLOR) {
628 FG_COLOR = *(text_ptr+1);
633 if (*text_ptr == CC_LSPACING) {
634 skip_lines = *(text_ptr+1) - '0';
640 if (*text_ptr == CC_UNDERLINE )
642 if ((r==FBASELINE+2) || (r==FBASELINE+3))
647 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
649 letter = *text_ptr-FMINCHAR;
651 if (!INFONT(letter)) { //not in font, draw as space
652 VideoOffset += width;
657 if (FFLAGS & FT_PROPORTIONAL)
660 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
664 if ( VideoOffset+width > 0xFFFF )
666 for (i=0; i< width; i++ )
668 gr_video_memory[VideoOffset++] = FG_COLOR;
670 if (VideoOffset > 0xFFFF )
672 VideoOffset -= 0xFFFF + 1;
680 for (i=0; i< width; i++ )
681 gr_video_memory[VideoOffset++] = FG_COLOR;
686 fp += BITS_TO_BYTES(width)*r;
690 if ( VideoOffset+width > 0xFFFF )
692 for (i=0; i< width; i++ )
700 gr_video_memory[VideoOffset++] = FG_COLOR;
706 if (VideoOffset > 0xFFFF )
708 VideoOffset -= 0xFFFF + 1;
715 for (i=0; i< width; i++ )
723 gr_video_memory[VideoOffset++] = FG_COLOR;
732 VideoOffset += spacing-width;
736 VideoOffset1 += ROWSIZE;
738 if (VideoOffset1 > 0xFFFF ) {
739 VideoOffset1 -= 0xFFFF + 1;
746 VideoOffset1 += ROWSIZE * skip_lines;
752 #endif // __ENV_MSDOS__
754 #if defined(POLY_ACC)
755 int gr_internal_string5(int x, int y, char *s )
758 ubyte * text_ptr, * next_row, * text_ptr1;
759 int r, BitMask, i, bits, width, spacing, letter, underline;
762 unsigned int VideoOffset, VideoOffset1;
765 VideoOffset1 = y * ROWSIZE + x * PA_BPP;
769 while (next_row != NULL )
771 text_ptr1 = next_row;
774 if (x==0x8000) { //centered
775 int xx = get_centered_x(text_ptr1);
776 VideoOffset1 = y * ROWSIZE + xx * PA_BPP;
779 for (r=0; r<FHEIGHT; r++)
782 text_ptr = text_ptr1;
784 VideoOffset = VideoOffset1;
788 if (*text_ptr == '\n' )
790 next_row = &text_ptr[1];
794 if (*text_ptr == CC_COLOR) {
795 FG_COLOR = *(text_ptr+1);
800 if (*text_ptr == CC_LSPACING) {
801 skip_lines = *(text_ptr+1) - '0';
807 if (*text_ptr == CC_UNDERLINE )
809 if ((r==FBASELINE+2) || (r==FBASELINE+3))
814 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
816 letter = *text_ptr-FMINCHAR;
818 if (!INFONT(letter)) { //not in font, draw as space
819 VideoOffset += spacing * PA_BPP;
824 if (FFLAGS & FT_PROPORTIONAL)
827 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
830 for (i=0; i< width; i++ )
831 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
834 fp += BITS_TO_BYTES(width)*r;
838 for (i=0; i< width; i++ )
846 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
848 { *(short *)(DATA + VideoOffset) = pa_clut[BG_COLOR]; VideoOffset += PA_BPP; }
853 VideoOffset += PA_BPP * (spacing-width); //for kerning
858 VideoOffset1 += ROWSIZE; y++;
862 VideoOffset1 += ROWSIZE * skip_lines;
868 int gr_internal_string5m(int x, int y, char *s )
871 ubyte * text_ptr, * next_row, * text_ptr1;
872 int r, BitMask, i, bits, width, spacing, letter, underline;
875 unsigned int VideoOffset, VideoOffset1;
878 VideoOffset1 = y * ROWSIZE + x * PA_BPP;
882 while (next_row != NULL )
884 text_ptr1 = next_row;
887 if (x==0x8000) { //centered
888 int xx = get_centered_x(text_ptr1);
889 VideoOffset1 = y * ROWSIZE + xx * PA_BPP;
892 for (r=0; r<FHEIGHT; r++)
895 text_ptr = text_ptr1;
897 VideoOffset = VideoOffset1;
901 if (*text_ptr == '\n' )
903 next_row = &text_ptr[1];
907 if (*text_ptr == CC_COLOR) {
908 FG_COLOR = *(text_ptr+1);
913 if (*text_ptr == CC_LSPACING) {
914 skip_lines = *(text_ptr+1) - '0';
920 if (*text_ptr == CC_UNDERLINE )
922 if ((r==FBASELINE+2) || (r==FBASELINE+3))
927 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
929 letter = *text_ptr-FMINCHAR;
931 if (!INFONT(letter)) { //not in font, draw as space
932 VideoOffset += spacing * PA_BPP;
937 if (FFLAGS & FT_PROPORTIONAL)
940 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
943 for (i=0; i< width; i++ )
944 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
947 fp += BITS_TO_BYTES(width)*r;
951 for (i=0; i< width; i++ )
959 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
961 VideoOffset += PA_BPP;
967 VideoOffset += PA_BPP * (spacing-width);
970 VideoOffset1 += ROWSIZE; y++;
973 VideoOffset1 += ROWSIZE * skip_lines;
980 //a bitmap for the character
981 grs_bitmap char_bm = {
984 BM_FLAG_TRANSPARENT, //flags
990 int gr_internal_color_string(int x, int y, char *s )
993 ubyte * text_ptr, * next_row, * text_ptr1;
994 int width, spacing,letter;
997 char_bm.bm_h = FHEIGHT; //set height for chars of this font
1004 while (next_row != NULL)
1006 text_ptr1 = next_row;
1009 text_ptr = text_ptr1;
1013 if (xx==0x8000) //centered
1014 xx = get_centered_x(text_ptr);
1018 if (*text_ptr == '\n' )
1020 next_row = &text_ptr[1];
1025 letter = *text_ptr-FMINCHAR;
1027 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
1029 if (!INFONT(letter)) { //not in font, draw as space
1035 if (FFLAGS & FT_PROPORTIONAL)
1036 fp = FCHARS[letter];
1038 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
1040 char_bm.bm_w = char_bm.bm_rowsize = width;
1042 char_bm.bm_data = fp;
1043 gr_bitmapm(xx,yy,&char_bm);
1054 int gr_string(int x, int y, char *s )
1059 Assert(FONT != NULL);
1061 if ( x == 0x8000 ) {
1062 if ( y<0 ) clipped |= 1;
1063 gr_get_string_size(s, &w, &h, &aw );
1064 // for x, since this will be centered, only look at
1066 if ( w > grd_curcanv->cv_bitmap.bm_w ) clipped |= 1;
1067 if ( (y+h) > grd_curcanv->cv_bitmap.bm_h ) clipped |= 1;
1069 if ( (y+h) < 0 ) clipped |= 2;
1070 if ( y > grd_curcanv->cv_bitmap.bm_h ) clipped |= 2;
1073 if ( (x<0) || (y<0) ) clipped |= 1;
1074 gr_get_string_size(s, &w, &h, &aw );
1075 if ( (x+w) > grd_curcanv->cv_bitmap.bm_w ) clipped |= 1;
1076 if ( (y+h) > grd_curcanv->cv_bitmap.bm_h ) clipped |= 1;
1077 if ( (x+w) < 0 ) clipped |= 2;
1078 if ( (y+h) < 0 ) clipped |= 2;
1079 if ( x > grd_curcanv->cv_bitmap.bm_w ) clipped |= 2;
1080 if ( y > grd_curcanv->cv_bitmap.bm_h ) clipped |= 2;
1084 return gr_ustring(x, y, s );
1086 if ( clipped & 2 ) {
1087 // Completely clipped...
1088 mprintf( (1, "Text '%s' at (%d,%d) is off screen!\n", s, x, y ));
1092 if ( clipped & 1 ) {
1093 // Partially clipped...
1094 //mprintf( (0, "Text '%s' at (%d,%d) is getting clipped!\n", s, x, y ));
1097 // Partially clipped...
1099 if (FFLAGS & FT_COLOR)
1100 return gr_internal_color_string( x, y, s);
1102 if ( BG_COLOR == -1)
1103 return gr_internal_string_clipped_m( x, y, s );
1105 return gr_internal_string_clipped( x, y, s );
1108 int gr_ustring(int x, int y, char *s )
1110 if (FFLAGS & FT_COLOR) {
1112 return gr_internal_color_string(x,y,s);
1119 if ( BG_COLOR == -1)
1120 return gr_internal_string0m(x,y,s);
1122 return gr_internal_string0(x,y,s);
1123 #ifdef __ENV_MSDOS__
1125 if ( BG_COLOR == -1)
1126 return gr_internal_string2m(x,y,s);
1128 return gr_internal_string2(x,y,s);
1129 #endif // __ENV_MSDOS__
1130 #if defined(POLY_ACC)
1132 if ( BG_COLOR == -1)
1133 return gr_internal_string5m(x,y,s);
1135 return gr_internal_string5(x,y,s);
1143 void gr_get_string_size(char *s, int *string_width, int *string_height, int *average_width )
1145 int i = 0, longest_width = 0;
1148 *string_height = FHEIGHT;
1150 *average_width = FWIDTH;
1157 // if (*s == CC_UNDERLINE)
1162 *string_height += FHEIGHT;
1168 // 1 = next byte specifies color, so skip the 1 and the color value
1171 else if (*s == CC_LSPACING) {
1172 *string_height += *(s+1)-'0';
1175 get_char_width(s[0],s[1],&width,&spacing);
1176 *string_width += spacing;
1177 if (*string_width > longest_width)
1178 longest_width = *string_width;
1184 *string_width = longest_width;
1188 int gr_uprintf( int x, int y, char * format, ... )
1193 va_start(args, format );
1194 vsprintf(buffer,format,args);
1195 return gr_ustring( x, y, buffer );
1198 int gr_printf( int x, int y, char * format, ... )
1203 va_start(args, format );
1204 vsprintf(buffer,format,args);
1205 return gr_string( x, y, buffer );
1208 void gr_close_font( grs_font * font )
1215 for (fontnum=0;fontnum<MAX_OPEN_FONTS && open_font[fontnum].ptr!=font;fontnum++);
1216 Assert(fontnum<MAX_OPEN_FONTS); //did we find slot?
1218 open_font[fontnum].ptr = NULL;
1220 if ( font->ft_chars )
1221 d_free( font->ft_chars );
1227 //remap (by re-reading) all the color fonts
1228 void gr_remap_color_fonts()
1232 for (fontnum=0;fontnum<MAX_OPEN_FONTS;fontnum++) {
1235 font = open_font[fontnum].ptr;
1237 if (font && (font->ft_flags & FT_COLOR))
1238 gr_remap_font(font,open_font[fontnum].filename);
1242 void build_colormap_good( ubyte * palette, ubyte * colormap, int * freq );
1243 void decode_data_asm(ubyte *data, int num_pixels, ubyte * colormap, int * count );
1245 #pragma aux decode_data_asm parm [esi] [ecx] [edi] [ebx] modify exact [esi edi eax ebx ecx] = \
1249 "inc dword ptr [ebx+eax*4]" \
1250 "mov al,[edi+eax]" \
1258 grs_font * gr_init_font( char * fontname )
1260 static int first_time=1;
1263 unsigned char * ptr;
1267 int datasize; //size up to (but not including) palette
1271 for (i=0;i<MAX_OPEN_FONTS;i++)
1272 open_font[i].ptr = NULL;
1276 //find free font slot
1277 for (fontnum=0;fontnum<MAX_OPEN_FONTS && open_font[fontnum].ptr!=NULL;fontnum++);
1278 Assert(fontnum<MAX_OPEN_FONTS); //did we find one?
1280 strncpy(open_font[fontnum].filename,fontname,FILENAME_LEN);
1282 fontfile = cfopen(fontname, "rb");
1285 Error( "Can't open font file %s", fontname );
1287 cfread( file_id, 1, 4, fontfile );
1288 datasize = cfile_read_int(fontfile);
1291 if ((file_id[0] != 'P') ||
1292 (file_id[1] != 'S') ||
1293 (file_id[2] != 'F') ||
1294 (file_id[3] != 'N'))
1295 Error( "File %s is not a font file", fontname );
1297 font = (grs_font *) d_malloc(datasize);
1299 open_font[fontnum].ptr = font;
1301 cfread(font,1,datasize,fontfile);
1304 // gotta translate those endian things
1306 font->ft_w = SWAPSHORT(font->ft_w);
1307 font->ft_h = SWAPSHORT(font->ft_h);
1308 font->ft_flags = SWAPSHORT(font->ft_flags);
1309 font->ft_bytewidth = SWAPSHORT(font->ft_bytewidth);
1310 font->ft_data = (ubyte *)SWAPINT((int)(font->ft_data));
1311 font->ft_chars = (ubyte **)SWAPINT((int)(font->ft_chars));
1312 font->ft_widths = (short *)SWAPINT((int)(font->ft_widths));
1313 font->ft_kerndata = (ubyte *)SWAPINT((int)(font->ft_kerndata));
1316 nchars = font->ft_maxchar-font->ft_minchar+1;
1318 if (font->ft_flags & FT_PROPORTIONAL) {
1320 font->ft_widths = (short *) (((int) font->ft_widths) + ((ubyte *) font));
1323 for (i = 0; i < nchars; i++)
1324 font->ft_widths[i] = SWAPSHORT(font->ft_widths[i]);
1327 font->ft_data = ((int) font->ft_data) + ((ubyte *) font);
1329 font->ft_chars = (unsigned char **)d_malloc( nchars * sizeof(unsigned char *));
1331 ptr = font->ft_data;
1333 for (i=0; i< nchars; i++ ) {
1334 font->ft_chars[i] = ptr;
1335 if (font->ft_flags & FT_COLOR)
1336 ptr += font->ft_widths[i] * font->ft_h;
1338 ptr += BITS_TO_BYTES(font->ft_widths[i]) * font->ft_h;
1343 font->ft_data = ((unsigned char *) font) + sizeof(*font);
1345 font->ft_chars = NULL;
1346 font->ft_widths = NULL;
1348 ptr = font->ft_data + (nchars * font->ft_w * font->ft_h);
1351 if (font->ft_flags & FT_KERNED)
1352 font->ft_kerndata = ((int) font->ft_kerndata) + ((ubyte *) font);
1355 if (font->ft_flags & FT_COLOR) { //remap palette
1356 ubyte palette[256*3];
1357 ubyte colormap[256];
1360 cfread(palette,3,256,fontfile); //read the palette
1362 #ifdef MACINTOSH // swap the first and last palette entries (black and white)
1367 for (i = 0; i < 3; i++) {
1369 palette[i] = palette[765+i];
1373 // we also need to swap the data entries as well. black is white and white is black
1375 for (i = 0; i < ptr-font->ft_data; i++) {
1376 if (font->ft_data[i] == 0)
1377 font->ft_data[i] = 255;
1378 else if (font->ft_data[i] == 255)
1379 font->ft_data[i] = 0;
1385 build_colormap_good( (ubyte *)&palette, colormap, freq );
1387 colormap[TRANSPARENCY_COLOR] = TRANSPARENCY_COLOR; // chaged from colormap[255] = 255 to this for macintosh
1389 decode_data_asm(font->ft_data, ptr-font->ft_data, colormap, freq );
1405 //remap a font by re-reading its data & palette
1406 void gr_remap_font( grs_font *font, char * fontname )
1412 int datasize; //size up to (but not including) palette
1413 int data_ofs,data_len;
1415 if (! (font->ft_flags & FT_COLOR))
1418 fontfile = cfopen(fontname, "rb");
1421 Error( "Can't open font file %s", fontname );
1423 cfread( file_id, 1, 4, fontfile );
1424 datasize = cfile_read_int(fontfile);
1427 if ((file_id[0] != 'P') ||
1428 (file_id[1] != 'S') ||
1429 (file_id[2] != 'F') ||
1430 (file_id[3] != 'N'))
1431 Error( "File %s is not a font file", fontname );
1433 nchars = font->ft_maxchar-font->ft_minchar+1;
1435 //compute data length
1437 if (font->ft_flags & FT_PROPORTIONAL) {
1439 for (i=0; i< nchars; i++ ) {
1440 if (font->ft_flags & FT_COLOR)
1441 data_len += font->ft_widths[i] * font->ft_h;
1443 data_len += BITS_TO_BYTES(font->ft_widths[i]) * font->ft_h;
1447 data_len = nchars * font->ft_w * font->ft_h;
1449 data_ofs = font->ft_data - ((ubyte *) font);
1451 cfseek(fontfile,data_ofs,SEEK_CUR);
1452 cfread(font->ft_data,1,data_len,fontfile); //read raw data
1454 if (font->ft_flags & FT_COLOR) { //remap palette
1455 ubyte palette[256*3];
1456 ubyte colormap[256];
1459 cfseek(fontfile,-sizeof(palette),SEEK_END);
1461 cfread(palette,3,256,fontfile); //read the palette
1463 #ifdef MACINTOSH // swap the first and last palette entries (black and white)
1468 for (i = 0; i < 3; i++) {
1470 palette[i] = palette[765+i];
1474 // we also need to swap the data entries as well. black is white and white is black
1476 for (i = 0; i < data_len; i++) {
1477 if (font->ft_data[i] == 0)
1478 font->ft_data[i] = 255;
1479 else if (font->ft_data[i] == 255)
1480 font->ft_data[i] = 0;
1486 build_colormap_good( (ubyte *)&palette, colormap, freq );
1488 colormap[TRANSPARENCY_COLOR] = TRANSPARENCY_COLOR; // changed from colormap[255] = 255;
1490 decode_data_asm(font->ft_data, data_len, colormap, freq );
1499 void gr_set_fontcolor( int fg, int bg )
1505 void gr_set_curfont( grs_font * new )
1511 int gr_internal_string_clipped(int x, int y, char *s )
1514 char * text_ptr, * next_row, * text_ptr1;
1515 int r, BitMask, i, bits, width, spacing, letter, underline;
1520 while (next_row != NULL )
1522 text_ptr1 = next_row;
1526 if (x==0x8000) //centered
1527 x = get_centered_x(text_ptr1);
1531 for (r=0; r<FHEIGHT; r++) {
1532 text_ptr = text_ptr1;
1536 if (*text_ptr == '\n' ) {
1537 next_row = &text_ptr[1];
1541 if (*text_ptr == CC_COLOR) {
1542 FG_COLOR = *(text_ptr+1);
1547 if (*text_ptr == CC_LSPACING) {
1548 Int3(); // Warning: skip lines not supported for clipped strings.
1554 if (*text_ptr == CC_UNDERLINE ) {
1555 if ((r==FBASELINE+2) || (r==FBASELINE+3))
1560 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
1562 letter = *text_ptr-FMINCHAR;
1564 if (!INFONT(letter)) { //not in font, draw as space
1570 if (FFLAGS & FT_PROPORTIONAL)
1571 fp = FCHARS[letter];
1573 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
1576 for (i=0; i< width; i++ ) {
1577 gr_setcolor(FG_COLOR);
1581 fp += BITS_TO_BYTES(width)*r;
1585 for (i=0; i< width; i++ ) {
1591 gr_setcolor(FG_COLOR);
1593 gr_setcolor(BG_COLOR);
1599 x += spacing-width; //for kerning
1609 int gr_internal_string_clipped_m(int x, int y, char *s )
1612 char * text_ptr, * next_row, * text_ptr1;
1613 int r, BitMask, i, bits, width, spacing, letter, underline;
1618 while (next_row != NULL )
1620 text_ptr1 = next_row;
1624 if (x==0x8000) //centered
1625 x = get_centered_x(text_ptr1);
1629 for (r=0; r<FHEIGHT; r++) {
1632 text_ptr = text_ptr1;
1635 if (*text_ptr == '\n' ) {
1636 next_row = &text_ptr[1];
1640 if (*text_ptr == CC_COLOR) {
1641 FG_COLOR = *(text_ptr+1);
1646 if (*text_ptr == CC_LSPACING) {
1647 Int3(); // Warning: skip lines not supported for clipped strings.
1653 if (*text_ptr == CC_UNDERLINE ) {
1654 if ((r==FBASELINE+2) || (r==FBASELINE+3))
1659 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
1661 letter = *text_ptr-FMINCHAR;
1663 if (!INFONT(letter)) { //not in font, draw as space
1669 if (FFLAGS & FT_PROPORTIONAL)
1670 fp = FCHARS[letter];
1672 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
1675 for (i=0; i< width; i++ ) {
1676 gr_setcolor(FG_COLOR);
1680 fp += BITS_TO_BYTES(width)*r;
1684 for (i=0; i< width; i++ ) {
1689 if (bits & BitMask) {
1690 gr_setcolor(FG_COLOR);
1699 x += spacing-width; //for kerning