From 9c61b3b0bf1d156f9dad25f5f618f1f928ba1be5 Mon Sep 17 00:00:00 2001 From: Bradley Bell Date: Sat, 20 Oct 2001 11:02:22 +0000 Subject: [PATCH] Bringing font stuff more in line with d1x --- 2d/font.c | 372 ++++++++++++++++++++++++++++++++++++++++++++++----- include/gr.h | 4 +- 2 files changed, 341 insertions(+), 35 deletions(-) diff --git a/2d/font.c b/2d/font.c index 7ca67717..eb3b320a 100644 --- a/2d/font.c +++ b/2d/font.c @@ -117,7 +117,7 @@ void get_char_width(ubyte c,ubyte c2,int *width,int *spacing) if (INFONT(letter2)) { - p = find_kern_entry(FONT,letter,letter2); + p = find_kern_entry(FONT,(ubyte)letter,letter2); if (p) *spacing = p[2]; @@ -131,6 +131,11 @@ int get_centered_x(char *s) int w,w2,s2; for (w=0;*s!=0 && *s!='\n';s++) { + if (*s<=0x06) { + if (*s<=0x03) + s++; + continue;//skip color codes. + } get_char_width(s[0],s[1],&w2,&s2); w += s2; } @@ -138,6 +143,24 @@ int get_centered_x(char *s) return ((grd_curcanv->cv_bitmap.bm_w - w) / 2); } +//hack to allow color codes to be embedded in strings -MPM +//note we subtract one from color, since 255 is "transparent" so it'll never be used, and 0 would otherwise end the string. +//function must already have orig_color var set (or they could be passed as args...) +//perhaps some sort of recursive orig_color type thing would be better, but that would be way too much trouble for little gain +int gr_message_color_level=1; +#define CHECK_EMBEDDED_COLORS() if ((*text_ptr >= 0x01) && (*text_ptr <= 0x03)) { \ + text_ptr++; \ + if (*text_ptr){ \ + if (gr_message_color_level >= *(text_ptr-1)) \ + FG_COLOR = *text_ptr - 1; \ + text_ptr++; \ + } \ + } \ + else if ((*text_ptr >= 0x04) && (*text_ptr <= 0x06)){ \ + if (gr_message_color_level >= *text_ptr - 3) \ + FG_COLOR=orig_color; \ + text_ptr++; \ + } int gr_internal_string0(int x, int y, char *s ) { @@ -216,7 +239,7 @@ int gr_internal_string0(int x, int y, char *s ) if (underline) for (i=0; i< width; i++ ) - DATA[VideoOffset++] = FG_COLOR; + DATA[VideoOffset++] = (unsigned char) FG_COLOR; else { fp += BITS_TO_BYTES(width)*r; @@ -231,9 +254,9 @@ int gr_internal_string0(int x, int y, char *s ) } if (bits & BitMask) - DATA[VideoOffset++] = FG_COLOR; + DATA[VideoOffset++] = (unsigned char) FG_COLOR; else - DATA[VideoOffset++] = BG_COLOR; + DATA[VideoOffset++] = (unsigned char) BG_COLOR; BitMask >>= 1; } } @@ -262,6 +285,8 @@ int gr_internal_string0m(int x, int y, char *s ) unsigned int VideoOffset, VideoOffset1; + int orig_color=FG_COLOR;//to allow easy reseting to default string color with colored strings -MPM + bits=0; VideoOffset1 = y * ROWSIZE + x; @@ -317,10 +342,12 @@ int gr_internal_string0m(int x, int y, char *s ) letter = *text_ptr-FMINCHAR; - if (!INFONT(letter)) { //not in font, draw as space + if (!INFONT(letter) || *text_ptr<=0x06) { //not in font, draw as space + CHECK_EMBEDDED_COLORS() else{ VideoOffset += spacing; text_ptr++; continue; + } } if (FFLAGS & FT_PROPORTIONAL) @@ -330,7 +357,7 @@ int gr_internal_string0m(int x, int y, char *s ) if (underline) for (i=0; i< width; i++ ) - DATA[VideoOffset++] = FG_COLOR; + DATA[VideoOffset++] = (unsigned int) FG_COLOR; else { fp += BITS_TO_BYTES(width)*r; @@ -345,7 +372,7 @@ int gr_internal_string0m(int x, int y, char *s ) } if (bits & BitMask) - DATA[VideoOffset++] = FG_COLOR; + DATA[VideoOffset++] = (unsigned int) FG_COLOR; else VideoOffset++; BitMask >>= 1; @@ -356,7 +383,8 @@ int gr_internal_string0m(int x, int y, char *s ) VideoOffset += spacing-width; } - VideoOffset1 += ROWSIZE; y++; + VideoOffset1 += ROWSIZE; + y++; } y += skip_lines; VideoOffset1 += ROWSIZE * skip_lines; @@ -369,13 +397,15 @@ int gr_internal_string0m(int x, int y, char *s ) int gr_internal_string2(int x, int y, char *s ) { unsigned char * fp; - char * text_ptr, * next_row, * text_ptr1; + ubyte * text_ptr, * next_row, * text_ptr1; int r, BitMask, i, bits, width, spacing, letter, underline; int page_switched, skip_lines = 0; unsigned int VideoOffset, VideoOffset1; - VideoOffset1 = (unsigned int)DATA + y * ROWSIZE + x; + VideoOffset1 = (size_t)DATA + y * ROWSIZE + x; + + bits = 0; gr_vesa_setpage(VideoOffset1 >> 16); @@ -437,9 +467,11 @@ int gr_internal_string2(int x, int y, char *s ) letter = *text_ptr-FMINCHAR; - if (!INFONT(letter)) { //not in font, draw as space + if (!INFONT(letter) || *text_ptr<=0x06) { //not in font, draw as space + CHECK_EMBEDDED_COLORS() else{ VideoOffset += spacing; text_ptr++; + } continue; } @@ -595,7 +627,7 @@ int gr_internal_string2m(int x, int y, char *s ) unsigned int VideoOffset, VideoOffset1; - VideoOffset1 = (unsigned int)DATA + y * ROWSIZE + x; + VideoOffset1 = (size_t)DATA + y * ROWSIZE + x; gr_vesa_setpage(VideoOffset1 >> 16); @@ -984,6 +1016,7 @@ int gr_internal_string5m(int x, int y, char *s ) } #endif +#if 1 //ndef OGL //a bitmap for the character grs_bitmap char_bm = { 0,0,0,0, //x,y,w,h @@ -991,7 +1024,11 @@ grs_bitmap char_bm = { BM_FLAG_TRANSPARENT, //flags 0, //rowsize NULL, //data - 0 //selector +#ifdef BITMAP_SELECTOR + 0, //selector +#endif + 0, //avg_color + 0 //unused }; int gr_internal_color_string(int x, int y, char *s ) @@ -1044,9 +1081,7 @@ int gr_internal_color_string(int x, int y, char *s ) else fp = FDATA + letter * BITS_TO_BYTES(width)*FHEIGHT; - char_bm.bm_w = char_bm.bm_rowsize = width; - - char_bm.bm_data = fp; + gr_init_bitmap (&char_bm, BM_LINEAR, 0, 0, width, FHEIGHT, width, fp); gr_bitmapm(xx,yy,&char_bm); xx += spacing; @@ -1058,6 +1093,267 @@ int gr_internal_color_string(int x, int y, char *s ) return 0; } +#else //OGL +#include "../main/inferno.h" +#include "ogl_init.h" +#include "args.h" +//font handling routines for OpenGL - Added 9/25/99 Matthew Mueller - they are here instead of in arch/ogl because they use all these defines + +int pow2ize(int x);//from ogl.c + +int get_font_total_width(grs_font * font){ + if (font->ft_flags & FT_PROPORTIONAL){ + int i,w=0,c=font->ft_minchar; + for (i=0;c<=font->ft_maxchar;i++,c++){ + if (font->ft_widths[i]<0) + Error("heh?\n"); + w+=font->ft_widths[i]; + } + return w; + }else{ + return font->ft_w*(font->ft_maxchar-font->ft_minchar+1); + } +} +void ogl_font_choose_size(grs_font * font,int gap,int *rw,int *rh){ + int nchars = font->ft_maxchar-font->ft_minchar+1; + int r,x,y,nc=0,smallest=999999,smallr=-1,tries; + int smallprop=10000; + int h,w; + for (h=32;h<=256;h*=2){ +// h=pow2ize(font->ft_h*rows+gap*(rows-1)); + if (font->ft_h>h)continue; + r=(h/(font->ft_h+gap)); + w=pow2ize((get_font_total_width(font)+(nchars-r)*gap)/r); + tries=0; + do { + if (tries) + w=pow2ize(w+1); + if(tries>3){ + mprintf((0,"failed to fit (%ix%i, %ic)\n",w,h,nc)); + break; + } + nc=0; + y=0; + while(y+font->ft_h<=h){ + x=0; + while (xft_flags & FT_PROPORTIONAL){ + if (x+font->ft_widths[nc]+gap>w)break; + x+=font->ft_widths[nc++]+gap; + }else{ + if (x+font->ft_w+gap>w)break; + x+=font->ft_w+gap; + nc++; + } + } + if (nc==nchars) + break; + y+=font->ft_h+gap; + } + + tries++; + }while(nc!=nchars); + if (nc!=nchars) + continue; + mprintf((0,"fit: %ix%i %i tries\n",w,h,tries)); + + if (w*h==smallest){//this gives squarer sizes priority (ie, 128x128 would be better than 512*32) + if (w>=h){ + if (w/hft_maxchar-font->ft_minchar+1; + int i,w,h,tw,th,x,y,curx=0,cury=0; + char *fp; + // char data[32*32*4]; + char *data; + int gap=0;//having a gap just wastes ram, since we don't filter text textures at all. + // char s[2]; + ogl_font_choose_size(font,gap,&tw,&th); + data=d_malloc(tw*th); + gr_init_bitmap(&font->ft_parent_bitmap,BM_LINEAR,0,0,tw,th,tw,data); + + font->ft_parent_bitmap.gltexture=ogl_get_free_texture(); + + font->ft_bitmaps=(grs_bitmap*)d_malloc( nchars * sizeof(grs_bitmap)); + mprintf((0,"ogl_init_font %s, %s, nchars=%i, (%ix%i tex)\n",(font->ft_flags & FT_PROPORTIONAL)?"proportional":"fixedwidth",(font->ft_flags & FT_COLOR)?"color":"mono",nchars,tw,th)); + // s[1]=0; + h=font->ft_h; + // sleep(5); + + for(i=0;ift_minchar+i; + // gr_get_string_size(s,&w,&h,&aw); + if (font->ft_flags & FT_PROPORTIONAL) + w=font->ft_widths[i]; + else + w=font->ft_w; +// mprintf((0,"char %i(%ix%i): ",i,w,h)); + if (w<1 || w>256){ + mprintf((0,"grr\n"));continue; + } + if (curx+w+gap>tw){ + cury+=h+gap; + curx=0; + } + if (cury+h>th) + Error("font doesn't really fit (%i/%i)?\n",i,nchars); + if (font->ft_flags & FT_COLOR) { + if (font->ft_flags & FT_PROPORTIONAL) + fp = font->ft_chars[i]; + else + fp = font->ft_data + i * w*h; + for (y=0;yft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=fp[x+y*w]; + } + + // gr_init_bitmap(&font->ft_bitmaps[i],BM_LINEAR,0,0,w,h,w,font->); + }else{ + int BitMask,bits=0,white=gr_find_closest_color(63,63,63); + // if (w*h>sizeof(data)) + // Error("ogl_init_font: toobig\n"); + if (font->ft_flags & FT_PROPORTIONAL) + fp = font->ft_chars[i]; + else + fp = font->ft_data + i * BITS_TO_BYTES(w)*h; + for (y=0;yft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=white; + else + font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=255; + BitMask >>= 1; + } + } + } + gr_init_sub_bitmap(&font->ft_bitmaps[i],&font->ft_parent_bitmap,curx,cury,w,h); + + curx+=w+gap; + } + if (!(font->ft_flags & FT_COLOR)) { + //use GL_INTENSITY instead of GL_RGB + if (ogl_intensity4_ok){ + font->ft_parent_bitmap.gltexture->internalformat=GL_INTENSITY4; + font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE; + }else if (ogl_luminance4_alpha4_ok){ + font->ft_parent_bitmap.gltexture->internalformat=GL_LUMINANCE4_ALPHA4; + font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE_ALPHA; + }else if (ogl_rgba2_ok){ + font->ft_parent_bitmap.gltexture->internalformat=GL_RGBA2; + font->ft_parent_bitmap.gltexture->format=GL_RGBA; + }else{ + font->ft_parent_bitmap.gltexture->internalformat=ogl_rgba_format; + font->ft_parent_bitmap.gltexture->format=GL_RGBA; + } + } + ogl_loadbmtexture_m(&font->ft_parent_bitmap,0); +} + +int ogl_internal_string(int x, int y, char *s ) +{ + ubyte * text_ptr, * next_row, * text_ptr1; + int width, spacing,letter; + int xx,yy; + int orig_color=FG_COLOR;//to allow easy reseting to default string color with colored strings -MPM + + next_row = s; + + yy = y; + + if (grd_curscreen->sc_canvas.cv_bitmap.bm_type != BM_OGL) + Error("carp.\n"); + while (next_row != NULL) + { + text_ptr1 = next_row; + next_row = NULL; + + text_ptr = text_ptr1; + + xx = x; + + if (xx==0x8000) //centered + xx = get_centered_x(text_ptr); + + while (*text_ptr) + { + if (*text_ptr == '\n' ) + { + next_row = &text_ptr[1]; + yy += FHEIGHT; + break; + } + + letter = *text_ptr-FMINCHAR; + + get_char_width(text_ptr[0],text_ptr[1],&width,&spacing); + + if (!INFONT(letter) || *text_ptr<=0x06) { //not in font, draw as space + CHECK_EMBEDDED_COLORS() else{ + xx += spacing; + text_ptr++; + } + continue; + } + +// ogl_ubitblt(FONT->ft_bitmaps[letter].bm_w,FONT->ft_bitmaps[letter].bm_h,xx,yy,0,0,&FONT->ft_bitmaps[letter],NULL); +// if (*text_ptr>='0' && *text_ptr<='9'){ + if (FFLAGS&FT_COLOR) + gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]); + else{ + if (grd_curcanv->cv_bitmap.bm_type==BM_OGL) + ogl_ubitmapm_c(xx,yy,&FONT->ft_bitmaps[letter],FG_COLOR); + else + Error("ogl_internal_string: non-color string to non-ogl dest\n"); +// gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]);//ignores color.. + } + //} + + xx += spacing; + + text_ptr++; + } + + } + return 0; +} + +int gr_internal_color_string(int x, int y, char *s ){ + return ogl_internal_string(x,y,s); +} +#endif //OGL + int gr_string(int x, int y, char *s ) { int w, h, aw; @@ -1102,6 +1398,10 @@ int gr_string(int x, int y, char *s ) } // Partially clipped... +#if 0 //def OGL + if (TYPE==BM_OGL) + return ogl_internal_string(x,y,s); +#endif if (FFLAGS & FT_COLOR) return gr_internal_color_string( x, y, s); @@ -1114,6 +1414,11 @@ int gr_string(int x, int y, char *s ) int gr_ustring(int x, int y, char *s ) { +#if 0 //def OGL + if (TYPE==BM_OGL) + return ogl_internal_string(x,y,s); +#endif + if (FFLAGS & FT_COLOR) { return gr_internal_color_string(x,y,s); @@ -1226,6 +1531,13 @@ void gr_close_font( grs_font * font ) if ( font->ft_chars ) d_free( font->ft_chars ); + d_free( font->oldfont ); +#if 0 //def OGL + if (font->ft_bitmaps) + d_free( font->ft_bitmaps ); + gr_free_bitmap_data(&font->ft_parent_bitmap); +// ogl_freebmtexture(&font->ft_parent_bitmap); +#endif d_free( font ); } @@ -1270,8 +1582,8 @@ grs_font * gr_init_font( char * fontname ) unsigned char * ptr; int nchars; CFILE *fontfile; - char file_id[4]; - int datasize; //size up to (but not including) palette + u_int32_t file_id; + int32_t datasize; //size up to (but not including) palette if (first_time) { int i; @@ -1291,14 +1603,10 @@ grs_font * gr_init_font( char * fontname ) if (!fontfile) Error( "Can't open font file %s", fontname ); - cfread( file_id, 1, 4, fontfile ); + file_id = cfile_read_int(fontfile); datasize = cfile_read_int(fontfile); - - if ((file_id[0] != 'P') || - (file_id[1] != 'S') || - (file_id[2] != 'F') || - (file_id[3] != 'N')) + if (file_id != 0x4e465350) /* 'NFSP' */ Error( "File %s is not a font file", fontname ); font = (grs_font *) d_malloc(datasize); @@ -1405,6 +1713,10 @@ grs_font * gr_init_font( char * fontname ) FG_COLOR = 0; BG_COLOR = 0; +#if 0 //def OGL + ogl_init_font(font); +#endif + return font; } @@ -1415,8 +1727,8 @@ void gr_remap_font( grs_font *font, char * fontname ) int i; int nchars; CFILE *fontfile; - char file_id[4]; - int datasize; //size up to (but not including) palette + u_int32_t file_id; + int32_t datasize; //size up to (but not including) palette int data_ofs,data_len; if (! (font->ft_flags & FT_COLOR)) @@ -1427,14 +1739,10 @@ void gr_remap_font( grs_font *font, char * fontname ) if (!fontfile) Error( "Can't open font file %s", fontname ); - cfread( file_id, 1, 4, fontfile ); + file_id = cfile_read_int(fontfile); datasize = cfile_read_int(fontfile); - - if ((file_id[0] != 'P') || - (file_id[1] != 'S') || - (file_id[2] != 'F') || - (file_id[3] != 'N')) + if (file_id != 0x4e465350) /* 'NFSP' */ Error( "File %s is not a font file", fontname ); nchars = font->ft_maxchar-font->ft_minchar+1; diff --git a/include/gr.h b/include/gr.h index bafc214a..8517039e 100644 --- a/include/gr.h +++ b/include/gr.h @@ -145,10 +145,8 @@ typedef struct _new_grs_font { ubyte ** ft_chars; // Ptrs to data for each char (required for prop font) short * ft_widths; // Array of widths (required for prop font) ubyte * ft_kerndata; // Array of kerning triplet data - - -#ifdef OGL old_grs_font * oldfont; +#ifdef OGL grs_bitmap *ft_bitmaps; grs_bitmap ft_parent_bitmap; #endif -- 2.39.2