From b24b7d8de41805242699e4a912fc55b6aee3c4a8 Mon Sep 17 00:00:00 2001 From: Ole Loots Date: Sun, 20 Mar 2011 22:28:53 +0000 Subject: When using onscreen plotter: Collect nsfb internal font characters into a single bitmap instead of plotting each character. svn path=/trunk/netsurf/; revision=12109 --- atari/plot/font_internal.c | 88 ++++++++++++++++++++++++++++++++++++---------- atari/plot/plotter.c | 33 +++++++++++++---- atari/plot/plotter.h | 24 +++++++++++-- atari/plot/plotter_vdi.c | 75 ++++++++++++++++++++++++++++++++------- 4 files changed, 182 insertions(+), 38 deletions(-) (limited to 'atari') diff --git a/atari/plot/font_internal.c b/atari/plot/font_internal.c index d16c6bac3..59b7a996b 100644 --- a/atari/plot/font_internal.c +++ b/atari/plot/font_internal.c @@ -24,6 +24,8 @@ #include "utils/utf8.h" #include "utils/log.h" +#include + static int dtor( FONT_PLOTTER self ); static int str_width( FONT_PLOTTER self,const plot_font_style_t *fstyle, const char * str, size_t length, int * width ); @@ -43,6 +45,10 @@ const struct fb_font_desc font_italic; const struct fb_font_desc font_bold; const struct fb_font_desc font_italic_bold; +static MFDB tmp; +static int tmp_mfdb_size; + +#define FONTDATAMAX 4096 static const struct fb_font_desc* fb_get_font(const plot_font_style_t *fstyle) @@ -92,6 +98,9 @@ int ctor_font_plotter_internal( FONT_PLOTTER self ) static int dtor( FONT_PLOTTER self ) { + if( tmp.fd_addr != NULL ){ + free( tmp.fd_addr ); + } return( 1 ); } @@ -169,28 +178,73 @@ static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t leng utf8_to_font_encoding(fb_font, text, length, &buffer); if (buffer == NULL) - return true; + return 1; /* y is given to the fonts baseline we need it to the fonts top */ - y-=((fb_font->height * 75)/100); + y-=((fb_font->height * 75)/100); - y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make + /* needed? */ + y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make * it work since fb coords are the top-left of pixels */ - c = fstyle->foreground; - /* in -> BGR */ - /* out -> ARGB */ - c = (ABGR_TO_RGB(c) | 0xFF); blen = strlen(buffer); - loc.g_y = y; - loc.g_w = fb_font->width; - loc.g_h = fb_font->height; - for (chr = 0; chr < blen; chr++) { - loc.g_x = x; - chrp = fb_font->data + ((unsigned char)buffer[chr] * fb_font->height); - draw_glyph1(self, &loc, (uint8_t *)chrp, 32, c); - x+=fb_font->width; - } + if ( blen < 1 ) { + return( 1 ); + } + + if( self->plotter->flags & PLOT_FLAG_OFFSCREEN ){ + /* when the plotter is an offscreen plotter the call to + bitmap() isn't that expensive. Draw an 8 bit bitmap into the + offscreen buffer. + */ + c = fstyle->foreground; + /* in -> BGR */ + /* out -> ARGB */ + c = (ABGR_TO_RGB(c) | 0xFF); + loc.g_y = y; + loc.g_x = x; + loc.g_w = fb_font->width; + loc.g_h = fb_font->height; + for (chr = 0; chr < blen; chr++) { + loc.g_x = x; + chrp = fb_font->data + ((unsigned char)buffer[chr] * fb_font->height); + draw_glyph1(self, &loc, (uint8_t *)chrp, 32, c); + x+=fb_font->width; + } + } else { + /* render the whole string into an monochrom mfdb */ + /* and plot that to reduce overhead */ + loc.g_x = x; + loc.g_y = y; + loc.g_w = blen * fb_font->width; + assert( loc.g_w > 0 ); + loc.g_h = fb_font->height; + int stride = MFDB_STRIDE( loc.g_w ); + if( tmp.fd_addr == NULL || tmp_mfdb_size < MFDB_SIZE( 1, stride, loc.g_h) ){ + tmp_mfdb_size = init_mfdb( 1, loc.g_w, loc.g_h+1, MFDB_FLAG_STAND | MFDB_FLAG_ZEROMEM, &tmp ); + } else { + void * buf = tmp.fd_addr; + int size = init_mfdb( 1, loc.g_w, loc.g_h+1, MFDB_FLAG_STAND | MFDB_FLAG_NOALLOC, &tmp ); + tmp.fd_addr = buf; + memset( tmp.fd_addr, 0, size ); + } + int ypos; + int rowsize = tmp.fd_wdwidth << 1; + char * d; + uint32_t * pp; + for (chr = 0; chr < blen; chr++) { + pp = (uint32_t*)fb_font->data + ((unsigned char)buffer[chr] * fb_font->height); + d = ((uint8_t*)tmp.fd_addr) + chr; + for( ypos=0; (unsigned int)yposforeground, (unsigned short*)&out ); + vs_color( self->plotter->vdi_handle, OFFSET_CUSTOM_COLOR, (unsigned short*)&out[0] ); + self->plotter->plot_mfdb( self->plotter, &loc, &tmp, PLOT_FLAG_TRANS ); + } free(buffer); return( 1 ); @@ -200,8 +254,6 @@ static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t leng /* Fontdata */ /* ------------------*/ -#define FONTDATAMAX 4096 - static const uint32_t fontdata_bold[FONTDATAMAX] = { 0x00, 0xFE, 0x00, 0xEE, 0xAA, 0xAA, 0xAA, 0xEE, 0x00, 0xEE, 0xAA, 0xAA, 0xAA, 0xEE, 0x00, 0xFE, diff --git a/atari/plot/plotter.c b/atari/plot/plotter.c index d9f46e8a8..1532bde4d 100755 --- a/atari/plot/plotter.c +++ b/atari/plot/plotter.c @@ -683,16 +683,22 @@ short rgb_to_666_index(unsigned char r, unsigned char g, unsigned char b) } -int init_mfdb(int bpp, int w, int h, bool stand, MFDB * out ) +int init_mfdb(int bpp, int w, int h, uint32_t flags, MFDB * out ) { int dststride; dststride = MFDB_STRIDE( w ); + int size = MFDB_SIZE( bpp, dststride, h ); if( bpp > 0 ) { - out->fd_addr = malloc( ((dststride >> 3) * h) * bpp ); - if( out->fd_addr == NULL ){ - return( 0 ); + if( (flags & MFDB_FLAG_NOALLOC) == 0 ) { + out->fd_addr = malloc( size ); + if( out->fd_addr == NULL ){ + return( 0 ); + } + if( (flags & MFDB_FLAG_ZEROMEM) ){ + memset( out->fd_addr, 0, size ); + } } - out->fd_stand = stand; + out->fd_stand = (flags & MFDB_FLAG_STAND) ? 1 : 0; out->fd_nplanes = (short)bpp; out->fd_r1 = out->fd_r2 = out->fd_r3 = 0; } else { @@ -701,7 +707,7 @@ int init_mfdb(int bpp, int w, int h, bool stand, MFDB * out ) out->fd_w = dststride; out->fd_h = h; out->fd_wdwidth = dststride >> 4; - return( 1 ); + return( size ); } @@ -714,6 +720,21 @@ int plotter_get_clip( GEM_PLOTTER self, struct rect * out ) return( 1 ); } +void plotter_get_clip_grect( GEM_PLOTTER self, GRECT * out ) +{ + out->g_x = self->clipping.x0; + out->g_y = self->clipping.y0; + out->g_w = self->clipping.x1 - self->clipping.x0; + out->g_h = self->clipping.y1 - self->clipping.y0; +} + +void plotter_get_visible_grect( GEM_PLOTTER self, GRECT * out ) +{ + out->g_x = self->clipping.x0; + out->g_y = self->clipping.y0; + out->g_w = self->clipping.x1 - self->clipping.x0; + out->g_h = self->clipping.y1 - self->clipping.y0; +} int plotter_std_clip(GEM_PLOTTER self, const struct rect * clip) { diff --git a/atari/plot/plotter.h b/atari/plot/plotter.h index af3bce45e..394fdfb4f 100755 --- a/atari/plot/plotter.h +++ b/atari/plot/plotter.h @@ -38,6 +38,7 @@ #include "utils/log.h" #ifndef ceilf +#warning "ceilf emulation" #define ceilf(x) (float)ceil((double)x) #endif @@ -55,6 +56,10 @@ #define PLOT_FLAG_DITHER 0x04 #define PLOT_FLAG_TRANS 0x08 +#define MFDB_FLAG_STAND 0x01 +#define MFDB_FLAG_ZEROMEM 0x02 +#define MFDB_FLAG_NOALLOC 0x04 + /* Error codes: */ #define ERR_BUFFERSIZE_EXCEEDS_SCREEN 1 #define ERR_NO_MEM 2 @@ -168,6 +173,7 @@ typedef int (*_pmf_path)(GEM_PLOTTER self, const float *p, unsigned int n, int f typedef int (*_pmf_bitmap_resize) ( GEM_PLOTTER self, struct bitmap * bm, int nw, int nh ); typedef int (*_pmf_bitmap)(GEM_PLOTTER self, struct bitmap * bmp, int x, int y, unsigned long bg, unsigned long flags ); +typedef int (*_pmf_plot_mfdb)(GEM_PLOTTER self, GRECT * loc, MFDB * mfdb, uint32_t flags); typedef int (*_pmf_text)(GEM_PLOTTER self, int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle); typedef int (*_pmf_dtor)(GEM_PLOTTER self); @@ -206,6 +212,7 @@ struct s_gem_plotter _pmf_path path; _pmf_bitmap_resize bitmap_resize; _pmf_bitmap bitmap; + _pmf_plot_mfdb plot_mfdb; _pmf_text text; _pmf_dtor dtor; }; @@ -296,9 +303,10 @@ short rgb_to_666_index(unsigned char r, unsigned char g, unsigned char b); If bpp == 0, this function assumes that the MFDB shall point to the screen and will not allocate any memory (mfdb.fd_addr == 0). The function will return 0 when the memory allocation fails - ( out of memory). + ( out of memory), otherwise it returns the size of the mfdb.fd_addr + as number of bytes. */ -int init_mfdb(int bpp, int w, int h, bool stand, MFDB * out ); +int init_mfdb(int bpp, int w, int h, uint32_t flags, MFDB * out ); /* shared / static methods follows */ @@ -307,11 +315,22 @@ int init_mfdb(int bpp, int w, int h, bool stand, MFDB * out ); */ int plotter_get_clip( GEM_PLOTTER self, struct rect * out ); +/* + Get clipping for current framebuffer as GRECT +*/ +void plotter_get_clip_grect( GEM_PLOTTER self, GRECT * out ); + +/* + Get current visible coords +*/ +void plotter_get_visible_grect( GEM_PLOTTER self, GRECT * out ); + /* Set clipping for current framebuffer */ int plotter_std_clip(GEM_PLOTTER self, const struct rect * clip); + /* convert framebuffer clipping to vdi clipping and activates it */ @@ -358,5 +377,6 @@ void plotter_vdi_clip( GEM_PLOTTER self, bool set); #define OFFSET_CUSTOM_COLOR 255 #define RGB_TO_VDI(c) rgb_to_666_index( (c&0xFF),(c&0xFF00)>>8,(c&0xFF0000)>>16)+OFFSET_WEB_PAL #define ABGR_TO_RGB(c) ( ((c&0xFF)<<16) | (c&0xFF00) | ((c&0xFF0000)>>16) ) << 8 +#define MFDB_SIZE( bpp, stride, h ) ( ((stride >> 3) * h) * bpp ) #endif diff --git a/atari/plot/plotter_vdi.c b/atari/plot/plotter_vdi.c index 39cb406ab..4098e0e4e 100755 --- a/atari/plot/plotter_vdi.c +++ b/atari/plot/plotter_vdi.c @@ -65,6 +65,7 @@ static int path(GEM_PLOTTER self,const float *p, unsigned int n, int fill, float static int bitmap_resize( GEM_PLOTTER self, struct bitmap * img, int nw, int nh ); static int bitmap( GEM_PLOTTER self, struct bitmap * bmp, int x, int y, unsigned long bg, unsigned long flags ); +static int plot_mfdb( GEM_PLOTTER self, GRECT * where, MFDB * mfdb, uint32_t flags); static int text(GEM_PLOTTER self, int x, int y, const char *text,size_t length, const plot_font_style_t *fstyle); static unsigned short sys_pal[256][3]; /*RGB*/ @@ -143,6 +144,7 @@ int ctor_plotter_vdi(GEM_PLOTTER self ) self->path = path; self->bitmap = bitmap; self->bitmap_resize = bitmap_resize; + self->plot_mfdb = plot_mfdb; self->text = text; LOG(("Screen: x: %d, y: %d\n", vdi_sysinfo.scr_w, vdi_sysinfo.scr_h)); @@ -352,10 +354,7 @@ static int update_region( GEM_PLOTTER self, GRECT region ) int src_offs; GRECT screen_area, tmp, visible; short pxy[10]; - visible.g_x = CURFB(self).vis_x; - visible.g_y = CURFB(self).vis_y; - visible.g_w = CURFB(self).vis_w; - visible.g_h = CURFB(self).vis_h; + plotter_get_visible_grect( self, &visible ); /* LOG(("%s: %s %d\n", (char*)__FILE__, __FUNCTION__, __LINE__)); @@ -453,10 +452,7 @@ static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst ) GRECT vis; /* clip to visible rect, only needed for onscreen renderer: */ - vis.g_x = CURFB(self).vis_x; - vis.g_y = CURFB(self).vis_y; - vis.g_w = CURFB(self).vis_w; - vis.g_h = CURFB(self).vis_h; + plotter_get_visible_grect( self, &vis ); if( !rc_intersect(&vis, &src) ) return 1; @@ -990,10 +986,7 @@ static int bitmap( GEM_PLOTTER self, struct bitmap * bmp, int x, int y, return( true ); } - vis.g_x = CURFB(self).vis_x; - vis.g_y = CURFB(self).vis_y; - vis.g_w = CURFB(self).vis_w; - vis.g_h = CURFB(self).vis_h; + plotter_get_visible_grect( self, &vis ); if( !rc_intersect( &vis, &off) ) { return( true ); } @@ -1020,6 +1013,64 @@ static int bitmap( GEM_PLOTTER self, struct bitmap * bmp, int x, int y, return( true ); } +static int plot_mfdb (GEM_PLOTTER self, GRECT * loc, MFDB * insrc, uint32_t flags) +{ + + MFDB screen, tran; + MFDB * src; + short pxy[8]; + short pxyclip[4]; + short c[2] = {OFFSET_CUSTOM_COLOR, WHITE}; + plotter_vdi_clip(self, true); + + init_mfdb( 0, loc->g_w, loc->g_h, 0, &screen ); + + pxy[0] = 0; + pxy[1] = 0; + pxy[2] = loc->g_w -1; + pxy[3] = loc->g_h -1; + pxy[4] = CURFB(self).x + loc->g_x; + pxy[5] = CURFB(self).y + loc->g_y; + pxy[6] = pxy[4] + loc->g_w -1; + pxy[7] = pxy[5] + loc->g_h -1; + + if( insrc->fd_stand ){ + int size = init_mfdb( insrc->fd_nplanes, loc->g_w, loc->g_h, + MFDB_FLAG_NOALLOC, + &tran + ); + if( DUMMY_PRIV(self)->size_buf_scr == 0 ){ + DUMMY_PRIV(self)->buf_scr.fd_addr = malloc( size ); + DUMMY_PRIV(self)->size_buf_scr = size; + } else { + if( size > DUMMY_PRIV(self)->size_buf_scr ) { + DUMMY_PRIV(self)->buf_scr.fd_addr = realloc( + DUMMY_PRIV(self)->buf_scr.fd_addr, size + ); + DUMMY_PRIV(self)->size_buf_scr = size; + } + } + tran.fd_addr = DUMMY_PRIV(self)->buf_scr.fd_addr; + vr_trnfm( self->vdi_handle, insrc, &tran ); + src = &tran; + } else { + src = insrc; + } + + if( flags & PLOT_FLAG_TRANS && src->fd_nplanes == 1){ + vrt_cpyfm( self->vdi_handle, MD_TRANS, (short*)pxy, src, &screen, (short*)&c ); + } else { + + } + if( insrc->fd_stand ){ + // TODO: shrink conv buffer + } + + + plotter_vdi_clip(self, false); + return( 1 ); +} + static int text(GEM_PLOTTER self, int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle) { self->font_plotter->text( self->font_plotter, x, y, -- cgit v1.2.3