summaryrefslogtreecommitdiff
path: root/atari
diff options
context:
space:
mode:
authorOle Loots <ole@monochrom.net>2011-03-20 22:28:53 +0000
committerOle Loots <ole@monochrom.net>2011-03-20 22:28:53 +0000
commitb24b7d8de41805242699e4a912fc55b6aee3c4a8 (patch)
treeec95aff68d3f960f80ac9922a0a925130d6a4d01 /atari
parentdad9306e2a52d4fee80eb1137617704ed8eb659e (diff)
downloadnetsurf-b24b7d8de41805242699e4a912fc55b6aee3c4a8.tar.gz
netsurf-b24b7d8de41805242699e4a912fc55b6aee3c4a8.tar.bz2
When using onscreen plotter: Collect nsfb internal font characters into a single bitmap instead of plotting each character.
svn path=/trunk/netsurf/; revision=12109
Diffstat (limited to 'atari')
-rw-r--r--atari/plot/font_internal.c88
-rwxr-xr-xatari/plot/plotter.c33
-rwxr-xr-xatari/plot/plotter.h24
-rwxr-xr-xatari/plot/plotter_vdi.c75
4 files changed, 182 insertions, 38 deletions
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 <windom.h>
+
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)ypos<loc.g_h; ypos++){
+ *d = (unsigned char)*pp++;
+ d += rowsize;
+ }
+ }
+ unsigned short out[4];
+ rgb_to_vdi1000( (unsigned char*)&fstyle->foreground, (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 */
@@ -308,10 +316,21 @@ 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,