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.
26 #include "pa_enabl.h" //$$POLY_ACC
42 #define MAX_OPEN_FONTS 50
43 #define FILENAME_LEN 13
45 typedef struct openfont {
46 char filename[FILENAME_LEN];
50 //list of open fonts, for use (for now) for palette remapping
51 openfont open_font[MAX_OPEN_FONTS];
53 #define FONT grd_curcanv->cv_font
54 #define FG_COLOR grd_curcanv->cv_font_fg_color
55 #define BG_COLOR grd_curcanv->cv_font_bg_color
56 #define FWIDTH FONT->ft_w
57 #define FHEIGHT FONT->ft_h
58 #define FBASELINE FONT->ft_baseline
59 #define FFLAGS FONT->ft_flags
60 #define FMINCHAR FONT->ft_minchar
61 #define FMAXCHAR FONT->ft_maxchar
62 #define FDATA FONT->ft_data
63 #define FCHARS FONT->ft_chars
64 #define FWIDTHS FONT->ft_widths
66 #define BITS_TO_BYTES(x) (((x)+7)>>3)
68 int gr_internal_string_clipped(int x, int y, char *s );
69 int gr_internal_string_clipped_m(int x, int y, char *s );
71 ubyte *find_kern_entry(grs_font *font,ubyte first,ubyte second)
73 ubyte *p=font->ft_kerndata;
76 if (p[0]==first && p[1]==second)
84 //takes the character AFTER being offset into font
85 #define INFONT(_c) ((_c >= 0) && (_c <= FMAXCHAR-FMINCHAR))
87 //takes the character BEFORE being offset into current font
88 void get_char_width(ubyte c,ubyte c2,int *width,int *spacing)
94 if (!INFONT(letter)) { //not in font, draw as space
96 if (FFLAGS & FT_PROPORTIONAL)
103 if (FFLAGS & FT_PROPORTIONAL)
104 *width = FWIDTHS[letter];
110 if (FFLAGS & FT_KERNED) {
113 if (!(c2==0 || c2=='\n')) {
116 letter2 = c2-FMINCHAR;
118 if (INFONT(letter2)) {
120 p = find_kern_entry(FONT,letter,letter2);
129 int get_centered_x(char *s)
133 for (w=0;*s!=0 && *s!='\n';s++) {
134 get_char_width(s[0],s[1],&w2,&s2);
138 return ((grd_curcanv->cv_bitmap.bm_w - w) / 2);
142 int gr_internal_string0(int x, int y, char *s )
145 ubyte * text_ptr, * next_row, * text_ptr1;
146 int r, BitMask, i, bits, width, spacing, letter, underline;
149 unsigned int VideoOffset, VideoOffset1;
153 VideoOffset1 = y * ROWSIZE + x;
157 while (next_row != NULL )
159 text_ptr1 = next_row;
162 if (x==0x8000) { //centered
163 int xx = get_centered_x(text_ptr1);
164 VideoOffset1 = y * ROWSIZE + xx;
167 for (r=0; r<FHEIGHT; r++)
170 text_ptr = text_ptr1;
172 VideoOffset = VideoOffset1;
176 if (*text_ptr == '\n' )
178 next_row = &text_ptr[1];
182 if (*text_ptr == CC_COLOR) {
183 FG_COLOR = *(text_ptr+1);
188 if (*text_ptr == CC_LSPACING) {
189 skip_lines = *(text_ptr+1) - '0';
195 if (*text_ptr == CC_UNDERLINE )
197 if ((r==FBASELINE+2) || (r==FBASELINE+3))
202 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
204 letter = *text_ptr-FMINCHAR;
206 if (!INFONT(letter)) { //not in font, draw as space
207 VideoOffset += spacing;
212 if (FFLAGS & FT_PROPORTIONAL)
215 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
218 for (i=0; i< width; i++ )
219 DATA[VideoOffset++] = FG_COLOR;
222 fp += BITS_TO_BYTES(width)*r;
226 for (i=0; i< width; i++ )
234 DATA[VideoOffset++] = FG_COLOR;
236 DATA[VideoOffset++] = BG_COLOR;
241 VideoOffset += spacing-width; //for kerning
246 VideoOffset1 += ROWSIZE; y++;
250 VideoOffset1 += ROWSIZE * skip_lines;
256 int gr_internal_string0m(int x, int y, char *s )
259 ubyte * text_ptr, * next_row, * text_ptr1;
260 int r, BitMask, i, bits, width, spacing, letter, underline;
263 unsigned int VideoOffset, VideoOffset1;
267 VideoOffset1 = y * ROWSIZE + x;
271 while (next_row != NULL )
273 text_ptr1 = next_row;
276 if (x==0x8000) { //centered
277 int xx = get_centered_x(text_ptr1);
278 VideoOffset1 = y * ROWSIZE + xx;
281 for (r=0; r<FHEIGHT; r++)
284 text_ptr = text_ptr1;
286 VideoOffset = VideoOffset1;
290 if (*text_ptr == '\n' )
292 next_row = &text_ptr[1];
296 if (*text_ptr == CC_COLOR) {
297 FG_COLOR = *(text_ptr+1);
302 if (*text_ptr == CC_LSPACING) {
303 skip_lines = *(text_ptr+1) - '0';
309 if (*text_ptr == CC_UNDERLINE )
311 if ((r==FBASELINE+2) || (r==FBASELINE+3))
316 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
318 letter = *text_ptr-FMINCHAR;
320 if (!INFONT(letter)) { //not in font, draw as space
321 VideoOffset += spacing;
326 if (FFLAGS & FT_PROPORTIONAL)
329 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
332 for (i=0; i< width; i++ )
333 DATA[VideoOffset++] = FG_COLOR;
336 fp += BITS_TO_BYTES(width)*r;
340 for (i=0; i< width; i++ )
348 DATA[VideoOffset++] = FG_COLOR;
356 VideoOffset += spacing-width;
359 VideoOffset1 += ROWSIZE; y++;
362 VideoOffset1 += ROWSIZE * skip_lines;
369 int gr_internal_string2(int x, int y, char *s )
372 char * text_ptr, * next_row, * text_ptr1;
373 int r, BitMask, i, bits, width, spacing, letter, underline;
374 int page_switched, skip_lines = 0;
376 unsigned int VideoOffset, VideoOffset1;
378 VideoOffset1 = (unsigned int)DATA + y * ROWSIZE + x;
380 gr_vesa_setpage(VideoOffset1 >> 16);
382 VideoOffset1 &= 0xFFFF;
386 while (next_row != NULL )
388 text_ptr1 = next_row;
391 if (x==0x8000) { //centered
392 int xx = get_centered_x(text_ptr1);
393 VideoOffset1 = y * ROWSIZE + xx;
394 gr_vesa_setpage(VideoOffset1 >> 16);
395 VideoOffset1 &= 0xFFFF;
398 for (r=0; r<FHEIGHT; r++)
400 text_ptr = text_ptr1;
402 VideoOffset = VideoOffset1;
408 if (*text_ptr == '\n' )
410 next_row = &text_ptr[1];
414 if (*text_ptr == CC_COLOR) {
415 FG_COLOR = *(text_ptr+1);
420 if (*text_ptr == CC_LSPACING) {
421 skip_lines = *(text_ptr+1) - '0';
427 if (*text_ptr == CC_UNDERLINE )
429 if ((r==FBASELINE+2) || (r==FBASELINE+3))
434 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
436 Assert(width==spacing); //no kerning support here
438 letter = *text_ptr-FMINCHAR;
440 if (!INFONT(letter)) { //not in font, draw as space
441 VideoOffset += spacing;
446 if (FFLAGS & FT_PROPORTIONAL)
449 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
453 if ( VideoOffset+width > 0xFFFF )
455 for (i=0; i< width; i++ )
457 gr_video_memory[VideoOffset++] = FG_COLOR;
459 if (VideoOffset > 0xFFFF )
461 VideoOffset -= 0xFFFF + 1;
469 for (i=0; i< width; i++ )
470 gr_video_memory[VideoOffset++] = FG_COLOR;
479 fp += BITS_TO_BYTES(width)*r;
483 if ( VideoOffset+width > 0xFFFF )
485 for (i=0; i< width; i++ )
493 gr_video_memory[VideoOffset++] = FG_COLOR;
495 gr_video_memory[VideoOffset++] = BG_COLOR;
499 if (VideoOffset > 0xFFFF )
501 VideoOffset -= 0xFFFF + 1;
513 if (bits & 0x80) gr_video_memory[VideoOffset+0] = FG_COLOR;
514 else gr_video_memory[VideoOffset+0] = BG_COLOR;
516 if (bits & 0x40) gr_video_memory[VideoOffset+1] = FG_COLOR;
517 else gr_video_memory[VideoOffset+1] = BG_COLOR;
519 if (bits & 0x20) gr_video_memory[VideoOffset+2] = FG_COLOR;
520 else gr_video_memory[VideoOffset+2] = BG_COLOR;
522 if (bits & 0x10) gr_video_memory[VideoOffset+3] = FG_COLOR;
523 else gr_video_memory[VideoOffset+3] = BG_COLOR;
525 if (bits & 0x08) gr_video_memory[VideoOffset+4] = FG_COLOR;
526 else gr_video_memory[VideoOffset+4] = BG_COLOR;
528 if (bits & 0x04) gr_video_memory[VideoOffset+5] = FG_COLOR;
529 else gr_video_memory[VideoOffset+5] = BG_COLOR;
531 if (bits & 0x02) gr_video_memory[VideoOffset+6] = FG_COLOR;
532 else gr_video_memory[VideoOffset+6] = BG_COLOR;
534 if (bits & 0x01) gr_video_memory[VideoOffset+7] = FG_COLOR;
535 else gr_video_memory[VideoOffset+7] = BG_COLOR;
539 for (i=0; i< width/2 ; i++ )
547 gr_video_memory[VideoOffset++] = FG_COLOR;
549 gr_video_memory[VideoOffset++] = BG_COLOR;
561 gr_video_memory[VideoOffset++] = FG_COLOR;
563 gr_video_memory[VideoOffset++] = BG_COLOR;
573 VideoOffset1 += ROWSIZE;
575 if (VideoOffset1 > 0xFFFF ) {
576 VideoOffset1 -= 0xFFFF + 1;
583 VideoOffset1 += ROWSIZE * skip_lines;
589 int gr_internal_string2m(int x, int y, char *s )
592 char * text_ptr, * next_row, * text_ptr1;
593 int r, BitMask, i, bits, width, spacing, letter, underline;
594 int page_switched, skip_lines = 0;
596 unsigned int VideoOffset, VideoOffset1;
598 VideoOffset1 = (unsigned int)DATA + y * ROWSIZE + x;
600 gr_vesa_setpage(VideoOffset1 >> 16);
602 VideoOffset1 &= 0xFFFF;
606 while (next_row != NULL )
608 text_ptr1 = next_row;
611 if (x==0x8000) { //centered
612 int xx = get_centered_x(text_ptr1);
613 VideoOffset1 = y * ROWSIZE + xx;
614 gr_vesa_setpage(VideoOffset1 >> 16);
615 VideoOffset1 &= 0xFFFF;
618 for (r=0; r<FHEIGHT; r++)
620 text_ptr = text_ptr1;
622 VideoOffset = VideoOffset1;
628 if (*text_ptr == '\n' )
630 next_row = &text_ptr[1];
634 if (*text_ptr == CC_COLOR) {
635 FG_COLOR = *(text_ptr+1);
640 if (*text_ptr == CC_LSPACING) {
641 skip_lines = *(text_ptr+1) - '0';
647 if (*text_ptr == CC_UNDERLINE )
649 if ((r==FBASELINE+2) || (r==FBASELINE+3))
654 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
656 letter = *text_ptr-FMINCHAR;
658 if (!INFONT(letter)) { //not in font, draw as space
659 VideoOffset += width;
664 if (FFLAGS & FT_PROPORTIONAL)
667 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
671 if ( VideoOffset+width > 0xFFFF )
673 for (i=0; i< width; i++ )
675 gr_video_memory[VideoOffset++] = FG_COLOR;
677 if (VideoOffset > 0xFFFF )
679 VideoOffset -= 0xFFFF + 1;
687 for (i=0; i< width; i++ )
688 gr_video_memory[VideoOffset++] = FG_COLOR;
693 fp += BITS_TO_BYTES(width)*r;
697 if ( VideoOffset+width > 0xFFFF )
699 for (i=0; i< width; i++ )
707 gr_video_memory[VideoOffset++] = FG_COLOR;
713 if (VideoOffset > 0xFFFF )
715 VideoOffset -= 0xFFFF + 1;
722 for (i=0; i< width; i++ )
730 gr_video_memory[VideoOffset++] = FG_COLOR;
739 VideoOffset += spacing-width;
743 VideoOffset1 += ROWSIZE;
745 if (VideoOffset1 > 0xFFFF ) {
746 VideoOffset1 -= 0xFFFF + 1;
753 VideoOffset1 += ROWSIZE * skip_lines;
759 #endif // __ENV_MSDOS__
761 #if defined(POLY_ACC)
762 int gr_internal_string5(int x, int y, char *s )
765 ubyte * text_ptr, * next_row, * text_ptr1;
766 int r, BitMask, i, bits, width, spacing, letter, underline;
769 unsigned int VideoOffset, VideoOffset1;
772 VideoOffset1 = y * ROWSIZE + x * PA_BPP;
776 while (next_row != NULL )
778 text_ptr1 = next_row;
781 if (x==0x8000) { //centered
782 int xx = get_centered_x(text_ptr1);
783 VideoOffset1 = y * ROWSIZE + xx * PA_BPP;
786 for (r=0; r<FHEIGHT; r++)
789 text_ptr = text_ptr1;
791 VideoOffset = VideoOffset1;
795 if (*text_ptr == '\n' )
797 next_row = &text_ptr[1];
801 if (*text_ptr == CC_COLOR) {
802 FG_COLOR = *(text_ptr+1);
807 if (*text_ptr == CC_LSPACING) {
808 skip_lines = *(text_ptr+1) - '0';
814 if (*text_ptr == CC_UNDERLINE )
816 if ((r==FBASELINE+2) || (r==FBASELINE+3))
821 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
823 letter = *text_ptr-FMINCHAR;
825 if (!INFONT(letter)) { //not in font, draw as space
826 VideoOffset += spacing * PA_BPP;
831 if (FFLAGS & FT_PROPORTIONAL)
834 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
837 for (i=0; i< width; i++ )
838 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
841 fp += BITS_TO_BYTES(width)*r;
845 for (i=0; i< width; i++ )
853 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
855 { *(short *)(DATA + VideoOffset) = pa_clut[BG_COLOR]; VideoOffset += PA_BPP; }
860 VideoOffset += PA_BPP * (spacing-width); //for kerning
865 VideoOffset1 += ROWSIZE; y++;
869 VideoOffset1 += ROWSIZE * skip_lines;
875 int gr_internal_string5m(int x, int y, char *s )
878 ubyte * text_ptr, * next_row, * text_ptr1;
879 int r, BitMask, i, bits, width, spacing, letter, underline;
882 unsigned int VideoOffset, VideoOffset1;
885 VideoOffset1 = y * ROWSIZE + x * PA_BPP;
889 while (next_row != NULL )
891 text_ptr1 = next_row;
894 if (x==0x8000) { //centered
895 int xx = get_centered_x(text_ptr1);
896 VideoOffset1 = y * ROWSIZE + xx * PA_BPP;
899 for (r=0; r<FHEIGHT; r++)
902 text_ptr = text_ptr1;
904 VideoOffset = VideoOffset1;
908 if (*text_ptr == '\n' )
910 next_row = &text_ptr[1];
914 if (*text_ptr == CC_COLOR) {
915 FG_COLOR = *(text_ptr+1);
920 if (*text_ptr == CC_LSPACING) {
921 skip_lines = *(text_ptr+1) - '0';
927 if (*text_ptr == CC_UNDERLINE )
929 if ((r==FBASELINE+2) || (r==FBASELINE+3))
934 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
936 letter = *text_ptr-FMINCHAR;
938 if (!INFONT(letter)) { //not in font, draw as space
939 VideoOffset += spacing * PA_BPP;
944 if (FFLAGS & FT_PROPORTIONAL)
947 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
950 for (i=0; i< width; i++ )
951 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
954 fp += BITS_TO_BYTES(width)*r;
958 for (i=0; i< width; i++ )
966 { *(short *)(DATA + VideoOffset) = pa_clut[FG_COLOR]; VideoOffset += PA_BPP; }
968 VideoOffset += PA_BPP;
974 VideoOffset += PA_BPP * (spacing-width);
977 VideoOffset1 += ROWSIZE; y++;
980 VideoOffset1 += ROWSIZE * skip_lines;
987 //a bitmap for the character
988 grs_bitmap char_bm = {
991 BM_FLAG_TRANSPARENT, //flags
997 int gr_internal_color_string(int x, int y, char *s )
1000 ubyte * text_ptr, * next_row, * text_ptr1;
1001 int width, spacing,letter;
1004 char_bm.bm_h = FHEIGHT; //set height for chars of this font
1011 while (next_row != NULL)
1013 text_ptr1 = next_row;
1016 text_ptr = text_ptr1;
1020 if (xx==0x8000) //centered
1021 xx = get_centered_x(text_ptr);
1025 if (*text_ptr == '\n' )
1027 next_row = &text_ptr[1];
1032 letter = *text_ptr-FMINCHAR;
1034 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
1036 if (!INFONT(letter)) { //not in font, draw as space
1042 if (FFLAGS & FT_PROPORTIONAL)
1043 fp = FCHARS[letter];
1045 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
1047 char_bm.bm_w = char_bm.bm_rowsize = width;
1049 char_bm.bm_data = fp;
1050 gr_bitmapm(xx,yy,&char_bm);
1061 int gr_string(int x, int y, char *s )
1066 Assert(FONT != NULL);
1068 if ( x == 0x8000 ) {
1069 if ( y<0 ) clipped |= 1;
1070 gr_get_string_size(s, &w, &h, &aw );
1071 // for x, since this will be centered, only look at
1073 if ( w > grd_curcanv->cv_bitmap.bm_w ) clipped |= 1;
1074 if ( (y+h) > grd_curcanv->cv_bitmap.bm_h ) clipped |= 1;
1076 if ( (y+h) < 0 ) clipped |= 2;
1077 if ( y > grd_curcanv->cv_bitmap.bm_h ) clipped |= 2;
1080 if ( (x<0) || (y<0) ) clipped |= 1;
1081 gr_get_string_size(s, &w, &h, &aw );
1082 if ( (x+w) > grd_curcanv->cv_bitmap.bm_w ) clipped |= 1;
1083 if ( (y+h) > grd_curcanv->cv_bitmap.bm_h ) clipped |= 1;
1084 if ( (x+w) < 0 ) clipped |= 2;
1085 if ( (y+h) < 0 ) clipped |= 2;
1086 if ( x > grd_curcanv->cv_bitmap.bm_w ) clipped |= 2;
1087 if ( y > grd_curcanv->cv_bitmap.bm_h ) clipped |= 2;
1091 return gr_ustring(x, y, s );
1093 if ( clipped & 2 ) {
1094 // Completely clipped...
1095 mprintf( (1, "Text '%s' at (%d,%d) is off screen!\n", s, x, y ));
1099 if ( clipped & 1 ) {
1100 // Partially clipped...
1101 //mprintf( (0, "Text '%s' at (%d,%d) is getting clipped!\n", s, x, y ));
1104 // Partially clipped...
1106 if (FFLAGS & FT_COLOR)
1107 return gr_internal_color_string( x, y, s);
1109 if ( BG_COLOR == -1)
1110 return gr_internal_string_clipped_m( x, y, s );
1112 return gr_internal_string_clipped( x, y, s );
1115 int gr_ustring(int x, int y, char *s )
1117 if (FFLAGS & FT_COLOR) {
1119 return gr_internal_color_string(x,y,s);
1126 if ( BG_COLOR == -1)
1127 return gr_internal_string0m(x,y,s);
1129 return gr_internal_string0(x,y,s);
1130 #ifdef __ENV_MSDOS__
1132 if ( BG_COLOR == -1)
1133 return gr_internal_string2m(x,y,s);
1135 return gr_internal_string2(x,y,s);
1136 #endif // __ENV_MSDOS__
1137 #if defined(POLY_ACC)
1139 if ( BG_COLOR == -1)
1140 return gr_internal_string5m(x,y,s);
1142 return gr_internal_string5(x,y,s);
1150 void gr_get_string_size(char *s, int *string_width, int *string_height, int *average_width )
1152 int i = 0, longest_width = 0;
1155 *string_height = FHEIGHT;
1157 *average_width = FWIDTH;
1164 // if (*s == CC_UNDERLINE)
1169 *string_height += FHEIGHT;
1175 // 1 = next byte specifies color, so skip the 1 and the color value
1178 else if (*s == CC_LSPACING) {
1179 *string_height += *(s+1)-'0';
1182 get_char_width(s[0],s[1],&width,&spacing);
1183 *string_width += spacing;
1184 if (*string_width > longest_width)
1185 longest_width = *string_width;
1191 *string_width = longest_width;
1195 int gr_uprintf( int x, int y, char * format, ... )
1200 va_start(args, format );
1201 vsprintf(buffer,format,args);
1202 return gr_ustring( x, y, buffer );
1205 int gr_printf( int x, int y, char * format, ... )
1210 va_start(args, format );
1211 vsprintf(buffer,format,args);
1212 return gr_string( x, y, buffer );
1215 void gr_close_font( grs_font * font )
1222 for (fontnum=0;fontnum<MAX_OPEN_FONTS && open_font[fontnum].ptr!=font;fontnum++);
1223 Assert(fontnum<MAX_OPEN_FONTS); //did we find slot?
1225 open_font[fontnum].ptr = NULL;
1227 if ( font->ft_chars )
1228 d_free( font->ft_chars );
1234 //remap (by re-reading) all the color fonts
1235 void gr_remap_color_fonts()
1239 for (fontnum=0;fontnum<MAX_OPEN_FONTS;fontnum++) {
1242 font = open_font[fontnum].ptr;
1244 if (font && (font->ft_flags & FT_COLOR))
1245 gr_remap_font(font,open_font[fontnum].filename);
1249 void build_colormap_good( ubyte * palette, ubyte * colormap, int * freq );
1250 void decode_data_asm(ubyte *data, int num_pixels, ubyte * colormap, int * count );
1252 #pragma aux decode_data_asm parm [esi] [ecx] [edi] [ebx] modify exact [esi edi eax ebx ecx] = \
1256 "inc dword ptr [ebx+eax*4]" \
1257 "mov al,[edi+eax]" \
1265 grs_font * gr_init_font( char * fontname )
1267 static int first_time=1;
1270 unsigned char * ptr;
1274 int datasize; //size up to (but not including) palette
1278 for (i=0;i<MAX_OPEN_FONTS;i++)
1279 open_font[i].ptr = NULL;
1283 //find free font slot
1284 for (fontnum=0;fontnum<MAX_OPEN_FONTS && open_font[fontnum].ptr!=NULL;fontnum++);
1285 Assert(fontnum<MAX_OPEN_FONTS); //did we find one?
1287 strncpy(open_font[fontnum].filename,fontname,FILENAME_LEN);
1289 fontfile = cfopen(fontname, "rb");
1292 Error( "Can't open font file %s", fontname );
1294 cfread( file_id, 1, 4, fontfile );
1295 datasize = cfile_read_int(fontfile);
1298 if ((file_id[0] != 'P') ||
1299 (file_id[1] != 'S') ||
1300 (file_id[2] != 'F') ||
1301 (file_id[3] != 'N'))
1302 Error( "File %s is not a font file", fontname );
1304 font = (grs_font *) d_malloc(datasize);
1306 open_font[fontnum].ptr = font;
1308 cfread(font,1,datasize,fontfile);
1311 // gotta translate those endian things
1313 font->ft_w = SWAPSHORT(font->ft_w);
1314 font->ft_h = SWAPSHORT(font->ft_h);
1315 font->ft_flags = SWAPSHORT(font->ft_flags);
1316 font->ft_bytewidth = SWAPSHORT(font->ft_bytewidth);
1317 font->ft_data = (ubyte *)SWAPINT((int)(font->ft_data));
1318 font->ft_chars = (ubyte **)SWAPINT((int)(font->ft_chars));
1319 font->ft_widths = (short *)SWAPINT((int)(font->ft_widths));
1320 font->ft_kerndata = (ubyte *)SWAPINT((int)(font->ft_kerndata));
1323 nchars = font->ft_maxchar-font->ft_minchar+1;
1325 if (font->ft_flags & FT_PROPORTIONAL) {
1327 font->ft_widths = (short *) (((int) font->ft_widths) + ((ubyte *) font));
1330 for (i = 0; i < nchars; i++)
1331 font->ft_widths[i] = SWAPSHORT(font->ft_widths[i]);
1334 font->ft_data = ((int) font->ft_data) + ((ubyte *) font);
1336 font->ft_chars = (unsigned char **)d_malloc( nchars * sizeof(unsigned char *));
1338 ptr = font->ft_data;
1340 for (i=0; i< nchars; i++ ) {
1341 font->ft_chars[i] = ptr;
1342 if (font->ft_flags & FT_COLOR)
1343 ptr += font->ft_widths[i] * font->ft_h;
1345 ptr += BITS_TO_BYTES(font->ft_widths[i]) * font->ft_h;
1350 font->ft_data = ((unsigned char *) font) + sizeof(*font);
1352 font->ft_chars = NULL;
1353 font->ft_widths = NULL;
1355 ptr = font->ft_data + (nchars * font->ft_w * font->ft_h);
1358 if (font->ft_flags & FT_KERNED)
1359 font->ft_kerndata = ((int) font->ft_kerndata) + ((ubyte *) font);
1362 if (font->ft_flags & FT_COLOR) { //remap palette
1363 ubyte palette[256*3];
1364 ubyte colormap[256];
1367 cfread(palette,3,256,fontfile); //read the palette
1369 #ifdef MACINTOSH // swap the first and last palette entries (black and white)
1374 for (i = 0; i < 3; i++) {
1376 palette[i] = palette[765+i];
1380 // we also need to swap the data entries as well. black is white and white is black
1382 for (i = 0; i < ptr-font->ft_data; i++) {
1383 if (font->ft_data[i] == 0)
1384 font->ft_data[i] = 255;
1385 else if (font->ft_data[i] == 255)
1386 font->ft_data[i] = 0;
1392 build_colormap_good( (ubyte *)&palette, colormap, freq );
1394 colormap[TRANSPARENCY_COLOR] = TRANSPARENCY_COLOR; // chaged from colormap[255] = 255 to this for macintosh
1396 decode_data_asm(font->ft_data, ptr-font->ft_data, colormap, freq );
1412 //remap a font by re-reading its data & palette
1413 void gr_remap_font( grs_font *font, char * fontname )
1419 int datasize; //size up to (but not including) palette
1420 int data_ofs,data_len;
1422 if (! (font->ft_flags & FT_COLOR))
1425 fontfile = cfopen(fontname, "rb");
1428 Error( "Can't open font file %s", fontname );
1430 cfread( file_id, 1, 4, fontfile );
1431 datasize = cfile_read_int(fontfile);
1434 if ((file_id[0] != 'P') ||
1435 (file_id[1] != 'S') ||
1436 (file_id[2] != 'F') ||
1437 (file_id[3] != 'N'))
1438 Error( "File %s is not a font file", fontname );
1440 nchars = font->ft_maxchar-font->ft_minchar+1;
1442 //compute data length
1444 if (font->ft_flags & FT_PROPORTIONAL) {
1446 for (i=0; i< nchars; i++ ) {
1447 if (font->ft_flags & FT_COLOR)
1448 data_len += font->ft_widths[i] * font->ft_h;
1450 data_len += BITS_TO_BYTES(font->ft_widths[i]) * font->ft_h;
1454 data_len = nchars * font->ft_w * font->ft_h;
1456 data_ofs = font->ft_data - ((ubyte *) font);
1458 cfseek(fontfile,data_ofs,SEEK_CUR);
1459 cfread(font->ft_data,1,data_len,fontfile); //read raw data
1461 if (font->ft_flags & FT_COLOR) { //remap palette
1462 ubyte palette[256*3];
1463 ubyte colormap[256];
1466 cfseek(fontfile,-sizeof(palette),SEEK_END);
1468 cfread(palette,3,256,fontfile); //read the palette
1470 #ifdef MACINTOSH // swap the first and last palette entries (black and white)
1475 for (i = 0; i < 3; i++) {
1477 palette[i] = palette[765+i];
1481 // we also need to swap the data entries as well. black is white and white is black
1483 for (i = 0; i < data_len; i++) {
1484 if (font->ft_data[i] == 0)
1485 font->ft_data[i] = 255;
1486 else if (font->ft_data[i] == 255)
1487 font->ft_data[i] = 0;
1493 build_colormap_good( (ubyte *)&palette, colormap, freq );
1495 colormap[TRANSPARENCY_COLOR] = TRANSPARENCY_COLOR; // changed from colormap[255] = 255;
1497 decode_data_asm(font->ft_data, data_len, colormap, freq );
1506 void gr_set_fontcolor( int fg, int bg )
1512 void gr_set_curfont( grs_font * new )
1518 int gr_internal_string_clipped(int x, int y, char *s )
1521 char * text_ptr, * next_row, * text_ptr1;
1522 int r, BitMask, i, bits, width, spacing, letter, underline;
1529 while (next_row != NULL )
1531 text_ptr1 = next_row;
1535 if (x==0x8000) //centered
1536 x = get_centered_x(text_ptr1);
1540 for (r=0; r<FHEIGHT; r++) {
1541 text_ptr = text_ptr1;
1545 if (*text_ptr == '\n' ) {
1546 next_row = &text_ptr[1];
1550 if (*text_ptr == CC_COLOR) {
1551 FG_COLOR = *(text_ptr+1);
1556 if (*text_ptr == CC_LSPACING) {
1557 Int3(); // Warning: skip lines not supported for clipped strings.
1563 if (*text_ptr == CC_UNDERLINE ) {
1564 if ((r==FBASELINE+2) || (r==FBASELINE+3))
1569 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
1571 letter = *text_ptr-FMINCHAR;
1573 if (!INFONT(letter)) { //not in font, draw as space
1579 if (FFLAGS & FT_PROPORTIONAL)
1580 fp = FCHARS[letter];
1582 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
1585 for (i=0; i< width; i++ ) {
1586 gr_setcolor(FG_COLOR);
1590 fp += BITS_TO_BYTES(width)*r;
1594 for (i=0; i< width; i++ ) {
1600 gr_setcolor(FG_COLOR);
1602 gr_setcolor(BG_COLOR);
1608 x += spacing-width; //for kerning
1618 int gr_internal_string_clipped_m(int x, int y, char *s )
1621 char * text_ptr, * next_row, * text_ptr1;
1622 int r, BitMask, i, bits, width, spacing, letter, underline;
1629 while (next_row != NULL )
1631 text_ptr1 = next_row;
1635 if (x==0x8000) //centered
1636 x = get_centered_x(text_ptr1);
1640 for (r=0; r<FHEIGHT; r++) {
1643 text_ptr = text_ptr1;
1646 if (*text_ptr == '\n' ) {
1647 next_row = &text_ptr[1];
1651 if (*text_ptr == CC_COLOR) {
1652 FG_COLOR = *(text_ptr+1);
1657 if (*text_ptr == CC_LSPACING) {
1658 Int3(); // Warning: skip lines not supported for clipped strings.
1664 if (*text_ptr == CC_UNDERLINE ) {
1665 if ((r==FBASELINE+2) || (r==FBASELINE+3))
1670 get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);
1672 letter = *text_ptr-FMINCHAR;
1674 if (!INFONT(letter)) { //not in font, draw as space
1680 if (FFLAGS & FT_PROPORTIONAL)
1681 fp = FCHARS[letter];
1683 fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT;
1686 for (i=0; i< width; i++ ) {
1687 gr_setcolor(FG_COLOR);
1691 fp += BITS_TO_BYTES(width)*r;
1695 for (i=0; i< width; i++ ) {
1700 if (bits & BitMask) {
1701 gr_setcolor(FG_COLOR);
1710 x += spacing-width; //for kerning