From a195728c51a34e68b4361cb685d3e20acbbecbe0 Mon Sep 17 00:00:00 2001 From: Ole Loots Date: Sat, 31 Dec 2011 15:21:49 +0000 Subject: Added support for 8bit displays, having big problems with transparent plots ( snapshot of background isn't always taken from correct position, maybe a bug in fvdi) svn path=/trunk/netsurf/; revision=13359 --- atari/plot/plotter.c | 29 +- atari/plot/plotter.h | 8 +- atari/plot/plotter_vdi.c | 1609 ++++++++++++++++++++++++++-------------------- atari/plot/plotter_vdi.h | 9 +- 4 files changed, 965 insertions(+), 690 deletions(-) (limited to 'atari') diff --git a/atari/plot/plotter.c b/atari/plot/plotter.c index 44183d938..8359215c1 100755 --- a/atari/plot/plotter.c +++ b/atari/plot/plotter.c @@ -627,10 +627,20 @@ void rgb_to_vdi1000( unsigned char * in, unsigned short * out ) out[2] = 1000 * b + 0.5; return; } + +void vdi1000_to_rgb( unsigned short * in, unsigned char * out ) +{ + double r = ((double)in[0]/1000); /* prozentsatz red */ + double g = ((double)in[1]/1000); /* prozentsatz green */ + double b = ((double)in[2]/1000); /* prozentsatz blue */ + out[2] = 255 * r + 0.5; + out[1] = 255 * g + 0.5; + out[0] = 255 * b + 0.5; + return; +} - -static short web_std_colors[6] = {0, 51, 102, 153, 204, 255}; +static short web_std_colors[6] = {0, 51, 102, 153, 204, 255}; /* Convert an RGB color into an index into the 216 colors web pallette @@ -640,7 +650,20 @@ short rgb_to_666_index(unsigned char r, unsigned char g, unsigned char b) short ret = 0; short i; unsigned char rgb[3] = {r,g,b}; - unsigned char tval[3]; + unsigned char tval[3]; + + int diff_a, diff_b, diff_c; + diff_a = abs(r-g); + diff_b = abs(r-b); + diff_c = abs(r-b); + if( diff_a < 2 && diff_b < 2 && diff_c < 2 ){ + if( (r!=0XFF) && (g!=0XFF) && (g!=0XFF) ){ + if( ((r&0xF0)>>4) != 0 ) + //printf("conv gray: %x -> %d\n", ((r&0xF0)>>4) , (OFFSET_CUST_PAL) + ((r&0xF0)>>4) ); + return( (OFFSET_CUST_PAL - OFFSET_WEB_PAL) + ((r&0xF0)>>4) ); + } + } + /* convert each 8bit color to 6bit web color: */ for( i=0; i<3; i++) { if(0 == rgb[i] % web_std_colors[1] ) { diff --git a/atari/plot/plotter.h b/atari/plot/plotter.h index 0c0f17f40..848004fd6 100755 --- a/atari/plot/plotter.h +++ b/atari/plot/plotter.h @@ -164,6 +164,8 @@ typedef int (*_pmf_rectangle)(GEM_PLOTTER self, int x0, int y0, int x1, int y1, typedef int (*_pmf_polygon)(GEM_PLOTTER self, const int *p, unsigned int n, const plot_style_t * pstyle); typedef int (*_pmf_path)(GEM_PLOTTER self, const float *p, unsigned int n, int fill, float width, int c, const float transform[6]); typedef int (*_pmf_bitmap_resize) ( GEM_PLOTTER self, struct bitmap * bm, int nw, int nh ); +typedef int (*_pmf_bitmap_convert)( GEM_PLOTTER self, struct bitmap * img, int x, int y, + GRECT * clip, uint32_t bg, uint32_t flags, MFDB *out ); 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); @@ -208,7 +210,9 @@ struct s_gem_plotter _pmf_polygon polygon; _pmf_path path; /* scale an netsurf bitmap: */ - _pmf_bitmap_resize bitmap_resize; + _pmf_bitmap_resize bitmap_resize; + /* convert an ABGR (netsurf) bitmap to screen format, ready for vro_cpyfm */ + _pmf_bitmap_convert bitmap_convert; /* plot an netsurf bitmap into the buffer / screen: */ _pmf_bitmap bitmap; /* plot an mfdb into the buffer / screen: */ @@ -290,6 +294,7 @@ const char* plotter_err_str(int i) ; void dump_font_drivers(void); void dump_plot_drivers(void); void dump_vdi_info(short); + /* convert an rgb color to vdi1000 color */ void rgb_to_vdi1000( unsigned char * in, unsigned short * out ); @@ -351,6 +356,7 @@ void plotter_vdi_clip( GEM_PLOTTER self, bool set); #define OFFSET_CUST_PAL 232 #define OFFSET_CUSTOM_COLOR 255 /* this one is used by the TC renderer */ #define RGB_TO_VDI(c) rgb_to_666_index( (c&0xFF),(c&0xFF00)>>8,(c&0xFF0000)>>16)+OFFSET_WEB_PAL +/* the name of this macro is crap - it should be named bgr_to_rgba ... or so */ #define ABGR_TO_RGB(c) ( ((c&0xFF)<<16) | (c&0xFF00) | ((c&0xFF0000)>>16) ) << 8 /* calculate MFDB compatible rowstride (in number of bits) */ diff --git a/atari/plot/plotter_vdi.c b/atari/plot/plotter_vdi.c index bb599084f..5a6ad0ee2 100755 --- a/atari/plot/plotter_vdi.c +++ b/atari/plot/plotter_vdi.c @@ -1,27 +1,27 @@ -/* - * Copyright 2010 Ole Loots - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include +/* + * Copyright 2010 Ole Loots + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include #include #include "atari/plot/eddi.h" @@ -43,621 +43,612 @@ default:\ dst = 1;\ break;\ - }\ + }\ + +static int dtor( GEM_PLOTTER self ); +static int resize( GEM_PLOTTER self, int w, int h ); +static int move( GEM_PLOTTER self, short x, short y ); +static int lock( GEM_PLOTTER self ); +static int unlock( GEM_PLOTTER self ); +static int update_region( GEM_PLOTTER self, GRECT region ); +static int update_screen_region( GEM_PLOTTER self, GRECT region ); +static int update_screen( GEM_PLOTTER self ); +static int put_pixel(GEM_PLOTTER self, int x, int y, int color ); +static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst ); +static int arc(GEM_PLOTTER self,int x, int y, int radius, int angle1, int angle2, const plot_style_t * pstyle); +static int disc(GEM_PLOTTER self,int x, int y, int radius, const plot_style_t * pstyle); +static int line(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle); +static int rectangle(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle); +static int polygon(GEM_PLOTTER self,const int *p, unsigned int n, const plot_style_t * pstyle); +static int path(GEM_PLOTTER self,const float *p, unsigned int n, int fill, float width, int c, const float transform[6]); +static int bitmap_resize( GEM_PLOTTER self, struct bitmap * img, int nw, int nh ); +static int bitmap_convert( GEM_PLOTTER self, struct bitmap * img, int x, int y, + GRECT * clip,uint32_t bg,uint32_t flags, MFDB *out ); +static int bitmap_convert_8( GEM_PLOTTER self, struct bitmap * img,int x, int y, + GRECT * clip,uint32_t bg,uint32_t flags, MFDB *out ); +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 int dtor( GEM_PLOTTER self ); -static int resize( GEM_PLOTTER self, int w, int h ); -static int move( GEM_PLOTTER self, short x, short y ); -static int lock( GEM_PLOTTER self ); -static int unlock( GEM_PLOTTER self ); -static int update_region( GEM_PLOTTER self, GRECT region ); -static int update_screen_region( GEM_PLOTTER self, GRECT region ); -static int update_screen( GEM_PLOTTER self ); -static int put_pixel(GEM_PLOTTER self, int x, int y, int color ); -static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst ); -static int arc(GEM_PLOTTER self,int x, int y, int radius, int angle1, int angle2, const plot_style_t * pstyle); -static int disc(GEM_PLOTTER self,int x, int y, int radius, const plot_style_t * pstyle); -static int line(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle); -static int rectangle(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle); -static int polygon(GEM_PLOTTER self,const int *p, unsigned int n, const plot_style_t * pstyle); -static int path(GEM_PLOTTER self,const float *p, unsigned int n, int fill, float width, int c, const float transform[6]); -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); - -#ifdef WITH_8BPP_SUPPORT -static unsigned short sys_pal[256][3]; /*RGB*/ -static unsigned short pal[256][3]; /*RGB*/ -extern unsigned char rgb_web_pal[126][3]; + +#ifdef WITH_8BPP_SUPPORT +static unsigned short sys_pal[256][3]; /*RGB*/ +static unsigned short pal[256][3]; /*RGB*/ extern unsigned short vdi_web_pal[126][3]; -int32 * hermes_pal_p; #endif extern struct s_vdi_sysinfo vdi_sysinfo; static HermesHandle hermes_pal_h; /* hermes palette handle */ static HermesHandle hermes_cnv_h; /* hermes converter instance handle */ -static HermesHandle hermes_res_h; - - -static inline void vsl_rgbcolor( short vdih, uint32_t cin ) -{ - if( vdi_sysinfo.scr_bpp > 8 ) { - unsigned short c[4]; - rgb_to_vdi1000( (unsigned char*)&cin, (unsigned short*)&c ); - vs_color( vdih, OFFSET_CUSTOM_COLOR, (unsigned short*)&c[0] ); - vsl_color( vdih, OFFSET_CUSTOM_COLOR ); - } else { - if( vdi_sysinfo.scr_bpp >= 4 ) - vsl_color( vdih, RGB_TO_VDI(cin) ); - else - vsl_color( vdih, BLACK ); - } -} - -static inline void vsf_rgbcolor( short vdih, uint32_t cin ) -{ - if( vdi_sysinfo.scr_bpp > 8 ) { - unsigned short c[4]; - rgb_to_vdi1000( (unsigned char*)&cin, (unsigned short*)&c ); - vs_color( vdih, OFFSET_CUSTOM_COLOR, &c[0] ); - vsf_color( vdih, OFFSET_CUSTOM_COLOR ); - } else { - if( vdi_sysinfo.scr_bpp >= 4 ) - vsf_color( vdih, RGB_TO_VDI(cin) ); - else - vsf_color( vdih, WHITE ); - } -} - -int ctor_plotter_vdi(GEM_PLOTTER self ) -{ - int retval = 0; - int i; - struct rect clip; - - self->dtor = dtor; - self->resize= resize; - self->move = move; - self->lock = lock; - self->unlock = unlock; - self->update_region = update_region; - self->update_screen_region = update_screen_region; - self->update_screen = update_screen; - self->put_pixel = put_pixel; - self->copy_rect = copy_rect; - self->clip = plotter_std_clip; - self->arc = arc; - self->disc = disc; - self->line = line; - self->rectangle = rectangle; - self->polygon = polygon; - 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)); - - self->priv_data = malloc( sizeof(struct s_vdi_priv_data) ); - if( self->priv_data == NULL ) - return( 0-ERR_NO_MEM ); - memset( self->priv_data, 0, sizeof(struct s_vdi_priv_data) ); - DUMMY_PRIV(self)->bufops = 0; - DUMMY_PRIV(self)->size_buf_packed = 0; - DUMMY_PRIV(self)->size_buf_planar = 0; - DUMMY_PRIV(self)->buf_packed = NULL; - DUMMY_PRIV(self)->buf_planar = NULL; - if( vdi_sysinfo.vdiformat == VDI_FORMAT_PACK ) { - self->bpp_virt = vdi_sysinfo.scr_bpp; - } else { - DUMMY_PRIV(self)->bufops = C2P; - self->bpp_virt = 8; - } - if( FIRSTFB(self).w > vdi_sysinfo.scr_w || FIRSTFB(self).h > vdi_sysinfo.scr_h ){ - return( 0-ERR_BUFFERSIZE_EXCEEDS_SCREEN ); - } - - FIRSTFB(self).size = calc_chunked_buffer_size( FIRSTFB(self).w, FIRSTFB(self).h, FIRSTFB(self).w, self->bpp_virt ); - /* offscreen: FIRSTFB(self).mem = malloc( FIRSTFB(self).size ); */ - FIRSTFB(self).mem = NULL; - update_visible_rect( self ); - - clip.x0 = 0; - clip.y0 = 0; - clip.x1 = FIRSTFB(self).w; - clip.y1 = FIRSTFB(self).h; - self->clip( self, &clip ); +static HermesHandle hermes_res_h; + + +static inline void vsl_rgbcolor( short vdih, uint32_t cin ) +{ + if( vdi_sysinfo.scr_bpp > 8 ) { + unsigned short c[4]; + rgb_to_vdi1000( (unsigned char*)&cin, (unsigned short*)&c ); + vs_color( vdih, OFFSET_CUSTOM_COLOR, (unsigned short*)&c[0] ); + vsl_color( vdih, OFFSET_CUSTOM_COLOR ); + } else { + if( vdi_sysinfo.scr_bpp >= 4 ){ + vsl_color( vdih, RGB_TO_VDI(cin) ); + } + else + vsl_color( vdih, BLACK ); + } +} + +static inline void vsf_rgbcolor( short vdih, uint32_t cin ) +{ + if( vdi_sysinfo.scr_bpp > 8 ) { + unsigned short c[4]; + rgb_to_vdi1000( (unsigned char*)&cin, (unsigned short*)&c ); + vs_color( vdih, OFFSET_CUSTOM_COLOR, &c[0] ); + vsf_color( vdih, OFFSET_CUSTOM_COLOR ); + } else { + if( vdi_sysinfo.scr_bpp >= 4 ){ + vsf_color( vdih, RGB_TO_VDI(cin) ); + } + else + vsf_color( vdih, WHITE ); + } +} + +int ctor_plotter_vdi(GEM_PLOTTER self ) +{ + int retval = 0; + int i; + struct rect clip; + + self->dtor = dtor; + self->resize= resize; + self->move = move; + self->lock = lock; + self->unlock = unlock; + self->update_region = update_region; + self->update_screen_region = update_screen_region; + self->update_screen = update_screen; + self->put_pixel = put_pixel; + self->copy_rect = copy_rect; + self->clip = plotter_std_clip; + self->arc = arc; + self->disc = disc; + self->line = line; + self->rectangle = rectangle; + self->polygon = polygon; + self->path = path; + self->bitmap = bitmap; + self->bitmap_resize = bitmap_resize; + self->bitmap_convert =(app.nplanes > 8) ? bitmap_convert : bitmap_convert_8; + //self->bitmap_convert =bitmap_convert; + self->plot_mfdb = plot_mfdb; + self->text = text; + LOG(("Screen: x: %d, y: %d\n", vdi_sysinfo.scr_w, vdi_sysinfo.scr_h)); + + self->priv_data = malloc( sizeof(struct s_vdi_priv_data) ); + if( self->priv_data == NULL ) + return( 0-ERR_NO_MEM ); + memset( self->priv_data, 0, sizeof(struct s_vdi_priv_data) ); + DUMMY_PRIV(self)->bufops = 0; + DUMMY_PRIV(self)->size_buf_packed = 0; + DUMMY_PRIV(self)->size_buf_planar = 0; + DUMMY_PRIV(self)->buf_packed = NULL; + DUMMY_PRIV(self)->buf_planar = NULL; + if( vdi_sysinfo.vdiformat == VDI_FORMAT_PACK ) { + self->bpp_virt = vdi_sysinfo.scr_bpp; + } else { + DUMMY_PRIV(self)->bufops = C2P; + self->bpp_virt = 8; + } + if( FIRSTFB(self).w > vdi_sysinfo.scr_w || FIRSTFB(self).h > vdi_sysinfo.scr_h ){ + return( 0-ERR_BUFFERSIZE_EXCEEDS_SCREEN ); + } + + FIRSTFB(self).size = calc_chunked_buffer_size( FIRSTFB(self).w, FIRSTFB(self).h, FIRSTFB(self).w, self->bpp_virt ); + /* offscreen: FIRSTFB(self).mem = malloc( FIRSTFB(self).size ); */ + FIRSTFB(self).mem = NULL; + update_visible_rect( self ); + + clip.x0 = 0; + clip.y0 = 0; + clip.x1 = FIRSTFB(self).w; + clip.y1 = FIRSTFB(self).h; + self->clip( self, &clip ); + + assert( Hermes_Init() ); /* store system palette & setup the new (web) palette: */ -#ifdef WITH_8BPP_SUPPORT - i = 0; - if( app.nplanes <= 8 ){ - for( i=0; i<=255; i++ ) { - vq_color(self->vdi_handle, i, 1, (unsigned short*)&sys_pal[i][0] ); - if( i= 8 ) { - if ( i < OFFSET_CUST_PAL ){ - pal[i][0] = vdi_web_pal[i-OFFSET_WEB_PAL][0]; - pal[i][1] = vdi_web_pal[i-OFFSET_WEB_PAL][1]; - pal[i][2] = vdi_web_pal[i-OFFSET_WEB_PAL][2]; - } - if( i >= OFFSET_CUST_PAL ) { - /* here we could define 22 additional colors... */ - } - vs_color( self->vdi_handle, i, &pal[i][0] ); - } - } - } else { - /* no need to change the palette - its application specific */ +#ifdef WITH_8BPP_SUPPORT + i = 0; + + unsigned char * col; + unsigned char rgbcol[4]; + unsigned char graytone=0; + if( app.nplanes <= 8 ){ + for( i=0; i<=255; i++ ) { + + // get the current color and save it for restore: + vq_color(self->vdi_handle, i, 1, (unsigned short*)&sys_pal[i][0] ); + if( i= 8 ) { + if ( i < OFFSET_CUST_PAL ){ + pal[i][0] = vdi_web_pal[i-OFFSET_WEB_PAL][0]; + pal[i][1] = vdi_web_pal[i-OFFSET_WEB_PAL][1]; + pal[i][2] = vdi_web_pal[i-OFFSET_WEB_PAL][2]; + //set the new palette color to websafe value: + vs_color( self->vdi_handle, i, &pal[i][0] ); + } + if( i >= OFFSET_CUST_PAL && ivdi_handle, i, &pal[i][0] ); + graytone++; + } + + } + } + } else { + /* no need to change the palette - its application specific */ } -#endif - - unsigned char * col; - assert( Hermes_Init() ); -/* - hermes_pal_h = Hermes_PaletteInstance(); - hermes_pal_p = Hermes_PaletteGet(hermes_pal_h); - assert(hermes_pal_p); - - for( i = 0; i= OFFSET_WEB_PAL ) { - col[0] = rgb_web_pal[i-OFFSET_WEB_PAL][0]; - col[1] = rgb_web_pal[i-OFFSET_WEB_PAL][1]; - col[2] = rgb_web_pal[i-OFFSET_WEB_PAL][2]; - } - col[3] = 0; - } - Hermes_PaletteInvalidateCache(hermes_pal_h); -*/ - - unsigned long flags = ( self->flags & PLOT_FLAG_DITHER ) ? HERMES_CONVERT_DITHER : 0; - hermes_cnv_h = Hermes_ConverterInstance( flags ); - assert( hermes_cnv_h ); - hermes_res_h = Hermes_ConverterInstance( flags ); - assert( hermes_res_h ); - - /* set up the src & dst format: */ - /* netsurf uses RGBA ... */ - DUMMY_PRIV(self)->nsfmt.a = 0xFFUL; - DUMMY_PRIV(self)->nsfmt.b = 0x0FF00UL; - DUMMY_PRIV(self)->nsfmt.g = 0x0FF0000UL; - DUMMY_PRIV(self)->nsfmt.r = 0x0FF000000UL; - DUMMY_PRIV(self)->nsfmt.bits = 32; - DUMMY_PRIV(self)->nsfmt.indexed = false; - DUMMY_PRIV(self)->nsfmt.has_colorkey = false; - - DUMMY_PRIV(self)->vfmt.r = vdi_sysinfo.mask_r; - DUMMY_PRIV(self)->vfmt.g = vdi_sysinfo.mask_g; - DUMMY_PRIV(self)->vfmt.b = vdi_sysinfo.mask_b; - DUMMY_PRIV(self)->vfmt.a = vdi_sysinfo.mask_a; - DUMMY_PRIV(self)->vfmt.bits = self->bpp_virt; - DUMMY_PRIV(self)->vfmt.indexed = false; - DUMMY_PRIV(self)->vfmt.has_colorkey = false; - - return( 1 ); -} - -static int dtor( GEM_PLOTTER self ) -{ - int i=0; - LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); - for( i=0; ifbuf[i].mem != NULL ) - free( self->fbuf[i].mem ); - } - - /* close Hermes stuff: */ + +#endif + + unsigned long flags = ( self->flags & PLOT_FLAG_DITHER ) ? HERMES_CONVERT_DITHER : 0; + hermes_cnv_h = Hermes_ConverterInstance( flags ); + assert( hermes_cnv_h ); + hermes_res_h = Hermes_ConverterInstance( flags ); + assert( hermes_res_h ); + + /* set up the src & dst format: */ + /* netsurf uses RGBA ... */ + DUMMY_PRIV(self)->nsfmt.a = 0xFFUL; + DUMMY_PRIV(self)->nsfmt.b = 0x0FF00UL; + DUMMY_PRIV(self)->nsfmt.g = 0x0FF0000UL; + DUMMY_PRIV(self)->nsfmt.r = 0x0FF000000UL; + DUMMY_PRIV(self)->nsfmt.bits = 32; + DUMMY_PRIV(self)->nsfmt.indexed = false; + DUMMY_PRIV(self)->nsfmt.has_colorkey = false; + + DUMMY_PRIV(self)->vfmt.r = vdi_sysinfo.mask_r; + DUMMY_PRIV(self)->vfmt.g = vdi_sysinfo.mask_g; + DUMMY_PRIV(self)->vfmt.b = vdi_sysinfo.mask_b; + DUMMY_PRIV(self)->vfmt.a = vdi_sysinfo.mask_a; + DUMMY_PRIV(self)->vfmt.bits = self->bpp_virt; + DUMMY_PRIV(self)->vfmt.indexed = ( app.nplanes <= 8 ) ? 1 : 0; + DUMMY_PRIV(self)->vfmt.has_colorkey = 0; + + return( 1 ); +} + +static int dtor( GEM_PLOTTER self ) +{ + int i=0; + LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); + for( i=0; ifbuf[i].mem != NULL ) + free( self->fbuf[i].mem ); + } + + + /* close Hermes stuff: */ Hermes_ConverterReturn( hermes_cnv_h ); -#ifdef WITH_8BPP_SUPPORT - if( app.nplanes <= 8 ){ - /* restore system palette */ - for( i=0; i<=255; i++ ) { - vs_color( self->vdi_handle, i, &sys_pal[i][0] ); - } + Hermes_Done(); + + if( self->priv_data != NULL ){ + if( DUMMY_PRIV(self)->buf_packed ) + free( DUMMY_PRIV(self)->buf_packed ); + if( DUMMY_PRIV(self)->buf_planar ) + free( DUMMY_PRIV(self)->buf_planar ); + free( self->priv_data ); } - Hermes_PaletteReturn( hermes_pal_h ); -#endif - - Hermes_Done(); - - if( self->priv_data != NULL ){ - if( DUMMY_PRIV(self)->buf_packed ) - free( DUMMY_PRIV(self)->buf_packed ); - if( DUMMY_PRIV(self)->buf_planar ) - free( DUMMY_PRIV(self)->buf_planar ); - free( self->priv_data ); - } - return( 1 ); -} - -static int resize( GEM_PLOTTER self, int w, int h ) -{ - if( w == CURFB(self).w && h == CURFB(self).h ) - return( 1 ); - /* todo: needed when using offscreen buffers... + snapshot_destroy( self ); + return( 1 ); +} + +static int resize( GEM_PLOTTER self, int w, int h ) +{ + if( w == CURFB(self).w && h == CURFB(self).h ) + return( 1 ); + /* todo: needed when using offscreen buffers... int newsize = calc_chunked_buffer_size( w, h, w, self->bpp_virt ); LOG(("%s: %s, oldsize: %d\n", (char*)__FILE__, __FUNCTION__, CURFB(self).size )); - if( newsize > self->screen_buffer_size ) { - self->screen_buffer_size = newsize; - self->screen_buffer =realloc( self->screen_buffer , self->screen_buffer_size ); - } - */ - CURFB(self).w = w; - CURFB(self).h = h; - update_visible_rect( self ); - LOG(("%s: %s, newsize: %d\n", (char*)__FILE__, (char*)__FUNCTION__, CURFB(self).size )); - return( 1 ); -} -static int move( GEM_PLOTTER self,short x, short y ) -{ - bool upd; - if(x == CURFB(self).x && y == CURFB(self).y ){ - return 1; - } - LOG(("%s: x: %d, y: %d\n",(char*)__FUNCTION__, x, y)); - CURFB(self).x = x; - CURFB(self).y = y; - update_visible_rect( self ); - return( 1 ); -} - - -static int lock( GEM_PLOTTER self ) -{ + if( newsize > self->screen_buffer_size ) { + self->screen_buffer_size = newsize; + self->screen_buffer =realloc( self->screen_buffer , self->screen_buffer_size ); + } + */ + CURFB(self).w = w; + CURFB(self).h = h; + update_visible_rect( self ); + LOG(("%s: %s, newsize: %d\n", (char*)__FILE__, (char*)__FUNCTION__, CURFB(self).size )); + return( 1 ); +} +static int move( GEM_PLOTTER self,short x, short y ) +{ + bool upd; + if(x == CURFB(self).x && y == CURFB(self).y ){ + return 1; + } + LOG(("%s: x: %d, y: %d\n",(char*)__FUNCTION__, x, y)); + CURFB(self).x = x; + CURFB(self).y = y; + update_visible_rect( self ); + return( 1 ); +} + + +static int lock( GEM_PLOTTER self ) +{ LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); if( (self->flags & PLOT_FLAG_LOCKED) != 0 ) - return(1); - self->flags |= PLOT_FLAG_LOCKED; + return(1); + self->flags |= PLOT_FLAG_LOCKED; if( !wind_update(BEG_UPDATE|0x100) ) return(0); if( !wind_update(BEG_MCTRL|0x100) ){ wind_update(END_UPDATE); return(0); - } - graf_mouse(M_OFF, NULL); - return( 1 ); -} - -static int unlock( GEM_PLOTTER self ) -{ + } + graf_mouse(M_OFF, NULL); + return( 1 ); +} + +static int unlock( GEM_PLOTTER self ) +{ LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); if( (self->flags & PLOT_FLAG_LOCKED) == 0 ) - return(1); - self->flags &= ~PLOT_FLAG_LOCKED; - wind_update(END_MCTRL); - wind_update(END_UPDATE); - graf_mouse(M_ON, NULL); - return( 1 ); -} - -/* - region specifies an rectangle within the framebuffer - calculation of screen coords is done automatically. -*/ -static int update_region( GEM_PLOTTER self, GRECT region ) -{ - int src_offs; - GRECT screen_area, tmp, visible; - short pxy[10]; - plotter_get_visible_grect( self, &visible ); - -/* - LOG(("%s: %s %d\n", (char*)__FILE__, __FUNCTION__, __LINE__)); - LOG(("region: x:%d, y:%d, w:%d, h:%d\n", region.g_x, region.g_y, region.g_w, region.g_h )); - LOG(("visible: x:%d, y:%d, w:%d, h:%d\n", visible.g_x, visible.g_y, visible.g_w, visible.g_h )); -*/ - /* sanitize region: */ - tmp = region; - if( !rc_intersect(&visible, &tmp) ) - return( 0 ); -/* - region is partially out of bottom or left: - if( region.g_x < self->visible.g_x ) - { - region.g_w = self->visible.g_x - region.g_x; - region.g_x = self->visible.g_x; - } - if( region.g_y < self->visible.g_y ) - { - region.g_h = self->visible.g_y - region.g_y; - region.g_y = self->visible.g_y; - } - region is partially out of top or right: - if( region.g_x + region.g_w > self->visible.g_x + self->visible.g_w ) - { - region.g_w = self->visible.g_w - region.g_x; - } - if( region.g_y + region.g_h > self->visible.g_y + self->visible.g_h ) - { - region.g_h = self->visible.g_h - region.g_y; - } - now region contains coords of framebuffer that needs redraw. -*/ - if( fbrect_to_screen( self, tmp, &screen_area) ) { - pxy[0] = screen_area.g_x; - pxy[1] = screen_area.g_y; - pxy[2] = screen_area.g_x + screen_area.g_w; - pxy[3] = screen_area.g_y; - pxy[4] = screen_area.g_x + screen_area.g_w; - pxy[5] = screen_area.g_y + screen_area.g_h; - pxy[6] = screen_area.g_x; - pxy[7] = screen_area.g_y + screen_area.g_h; - pxy[8] = screen_area.g_x; - pxy[9] = screen_area.g_y; - } - return( 1 ); -} - -/* - region specifies an rectangle within the screen, - calculation of framebuffer coords is done automatically. -*/ -static int update_screen_region( GEM_PLOTTER self, GRECT region ) -{ - LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); - - return( 1 ); -} - -/* Updates all visible parts of the framebuffer */ -static int update_screen( GEM_PLOTTER self ) -{ - GRECT target, src; - int src_offset; - int i,x; - LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); - if( !(PLOT_FLAG_OFFSCREEN & self->flags) ) - return( 0 ); - target.g_x = src.g_x = 0; - target.g_y = src.g_y = 0; - target.g_w = src.g_w = CURFB(self).w; - target.g_h = src.g_h = CURFB(self).h; - if( !fbrect_to_screen( self, target, &target ) ) - return( -1 ); - src_offset = get_pixel_offset( CURFB(self).vis_x, CURFB(self).vis_y, CURFB(self).w, self->bpp_virt ); - LOG(("area: x:%d ,y:%d ,w:%d ,h:%d, from: %p (offset: %d) \n", - target.g_x, target.g_y, - target.g_w, target.g_h, - ((char*)CURFB(self).mem)+src_offset, src_offset - )); - - return( 1 ); -} -static int put_pixel(GEM_PLOTTER self, int x, int y, int color ) -{ - LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); - return( 1 ); -} + return(1); + self->flags &= ~PLOT_FLAG_LOCKED; + wind_update(END_MCTRL); + wind_update(END_UPDATE); + graf_mouse(M_ON, NULL); + return( 1 ); +} + +/* + region specifies an rectangle within the framebuffer + calculation of screen coords is done automatically. +*/ +static int update_region( GEM_PLOTTER self, GRECT region ) +{ + int src_offs; + GRECT screen_area, tmp, visible; + short pxy[10]; + plotter_get_visible_grect( self, &visible ); + +/* + LOG(("%s: %s %d\n", (char*)__FILE__, __FUNCTION__, __LINE__)); + LOG(("region: x:%d, y:%d, w:%d, h:%d\n", region.g_x, region.g_y, region.g_w, region.g_h )); + LOG(("visible: x:%d, y:%d, w:%d, h:%d\n", visible.g_x, visible.g_y, visible.g_w, visible.g_h )); +*/ + /* sanitize region: */ + tmp = region; + if( !rc_intersect(&visible, &tmp) ) + return( 0 ); +/* + region is partially out of bottom or left: + if( region.g_x < self->visible.g_x ) + { + region.g_w = self->visible.g_x - region.g_x; + region.g_x = self->visible.g_x; + } + if( region.g_y < self->visible.g_y ) + { + region.g_h = self->visible.g_y - region.g_y; + region.g_y = self->visible.g_y; + } + region is partially out of top or right: + if( region.g_x + region.g_w > self->visible.g_x + self->visible.g_w ) + { + region.g_w = self->visible.g_w - region.g_x; + } + if( region.g_y + region.g_h > self->visible.g_y + self->visible.g_h ) + { + region.g_h = self->visible.g_h - region.g_y; + } + now region contains coords of framebuffer that needs redraw. +*/ + if( fbrect_to_screen( self, tmp, &screen_area) ) { + pxy[0] = screen_area.g_x; + pxy[1] = screen_area.g_y; + pxy[2] = screen_area.g_x + screen_area.g_w; + pxy[3] = screen_area.g_y; + pxy[4] = screen_area.g_x + screen_area.g_w; + pxy[5] = screen_area.g_y + screen_area.g_h; + pxy[6] = screen_area.g_x; + pxy[7] = screen_area.g_y + screen_area.g_h; + pxy[8] = screen_area.g_x; + pxy[9] = screen_area.g_y; + } + return( 1 ); +} + +/* + region specifies an rectangle within the screen, + calculation of framebuffer coords is done automatically. +*/ +static int update_screen_region( GEM_PLOTTER self, GRECT region ) +{ + LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); + + return( 1 ); +} + +/* Updates all visible parts of the framebuffer */ +static int update_screen( GEM_PLOTTER self ) +{ + GRECT target, src; + int src_offset; + int i,x; + LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); + if( !(PLOT_FLAG_OFFSCREEN & self->flags) ) + return( 0 ); + target.g_x = src.g_x = 0; + target.g_y = src.g_y = 0; + target.g_w = src.g_w = CURFB(self).w; + target.g_h = src.g_h = CURFB(self).h; + if( !fbrect_to_screen( self, target, &target ) ) + return( -1 ); + src_offset = get_pixel_offset( CURFB(self).vis_x, CURFB(self).vis_y, CURFB(self).w, self->bpp_virt ); + LOG(("area: x:%d ,y:%d ,w:%d ,h:%d, from: %p (offset: %d) \n", + target.g_x, target.g_y, + target.g_w, target.g_h, + ((char*)CURFB(self).mem)+src_offset, src_offset + )); + + return( 1 ); +} +static int put_pixel(GEM_PLOTTER self, int x, int y, int color ) +{ + LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__)); + return( 1 ); +} /* copy an rectangle from the plot buffer to screen */ -/* because this is an on-screen plotter, this is an screen to screen copy. */ -static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst ) -{ - MFDB devmf; - MFDB scrmf; - short pxy[8]; - GRECT vis; - - /* clip to visible rect, only needed for onscreen renderer: */ - plotter_get_visible_grect( self, &vis ); - - if( !rc_intersect(&vis, &src) ) - return 1; - if( !rc_intersect(&vis, &dst) ) - return 1; - - src.g_x = CURFB(self).x + src.g_x; - src.g_y = CURFB(self).y + src.g_y; - dst.g_x = CURFB(self).x + dst.g_x; - dst.g_y = CURFB(self).y + dst.g_y; - - devmf.fd_addr = NULL; - devmf.fd_w = src.g_w; - devmf.fd_h = src.g_h; - devmf.fd_wdwidth = 0; - devmf.fd_stand = 0; - devmf.fd_nplanes = 0; - devmf.fd_r1 = devmf.fd_r2 = devmf.fd_r3 = 0; - - scrmf.fd_addr = NULL; - scrmf.fd_w = dst.g_w; - scrmf.fd_h = dst.g_h; - scrmf.fd_wdwidth = 0 ; - scrmf.fd_stand = 0; - scrmf.fd_nplanes = 0; - scrmf.fd_r1 = scrmf.fd_r2 = scrmf.fd_r3 = 0; - - pxy[0] = src.g_x; - pxy[1] = src.g_y; - pxy[2] = pxy[0] + src.g_w-1; - pxy[3] = pxy[1] + src.g_h-1; - pxy[4] = dst.g_x; - pxy[5] = dst.g_y; - pxy[6] = pxy[4] + dst.g_w-1; - pxy[7] = pxy[5] + dst.g_h-1; - self->lock( self ); - vro_cpyfm( self->vdi_handle, S_ONLY, (short*)&pxy, &devmf, &scrmf); - self->unlock( self ); - - return( 1 ); -} - -static int arc(GEM_PLOTTER self,int x, int y, int radius, int angle1, int angle2, const plot_style_t * pstyle) -{ - //plotter_vdi_clip( self, 1); - vswr_mode( self->vdi_handle, MD_REPLACE ); - if( pstyle->fill_type == PLOT_OP_TYPE_NONE ) - return 1; - if( pstyle->fill_type != PLOT_OP_TYPE_SOLID) { - vsl_rgbcolor( self->vdi_handle, pstyle->stroke_colour); - vsf_perimeter( self->vdi_handle, 1); - vsf_interior( self->vdi_handle, 1 ); - v_arc( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius, angle1*10, angle2*10 ); - } else { - vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour); - vsl_width( self->vdi_handle, 1 ); - vsf_perimeter( self->vdi_handle, 1); - v_arc( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius, angle1*10, angle2*10 ); - } - //plotter_vdi_clip( self, 0); - return ( 1 ); -} - -static int disc(GEM_PLOTTER self,int x, int y, int radius, const plot_style_t * pstyle) -{ - plotter_vdi_clip( self, 1); - if( pstyle->fill_type != PLOT_OP_TYPE_SOLID) { - vsf_rgbcolor( self->vdi_handle, pstyle->stroke_colour ); - vsf_perimeter( self->vdi_handle, 1); - vsf_interior( self->vdi_handle, 0 ); - v_circle( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius ); - } else { - vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour ); - vsf_perimeter( self->vdi_handle, 0); - vsf_interior( self->vdi_handle, FIS_SOLID ); - v_circle( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius ); - } - plotter_vdi_clip( self, 0); - return ( 1 ); -} - - -static int line(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle) -{ - short pxy[4]; - uint32_t lt; - int sw = pstyle->stroke_width; - - pxy[0] = CURFB(self).x + x0; - pxy[1] = CURFB(self).y + y0; - pxy[2] = CURFB(self).x + x1; - pxy[3] = CURFB(self).y + y1; - - plotter_vdi_clip( self, 1); - if( sw == 0) - sw = 1; - NSLT2VDI(lt, pstyle) +/* because this is an on-screen plotter, this is an screen to screen copy. */ +static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst ) +{ + MFDB devmf; + MFDB scrmf; + short pxy[8]; + GRECT vis; + + /* clip to visible rect, only needed for onscreen renderer: */ + plotter_get_visible_grect( self, &vis ); + + if( !rc_intersect(&vis, &src) ) + return 1; + if( !rc_intersect(&vis, &dst) ) + return 1; + + src.g_x = CURFB(self).x + src.g_x; + src.g_y = CURFB(self).y + src.g_y; + dst.g_x = CURFB(self).x + dst.g_x; + dst.g_y = CURFB(self).y + dst.g_y; + + devmf.fd_addr = NULL; + devmf.fd_w = src.g_w; + devmf.fd_h = src.g_h; + devmf.fd_wdwidth = 0; + devmf.fd_stand = 0; + devmf.fd_nplanes = 0; + devmf.fd_r1 = devmf.fd_r2 = devmf.fd_r3 = 0; + + scrmf.fd_addr = NULL; + scrmf.fd_w = dst.g_w; + scrmf.fd_h = dst.g_h; + scrmf.fd_wdwidth = 0 ; + scrmf.fd_stand = 0; + scrmf.fd_nplanes = 0; + scrmf.fd_r1 = scrmf.fd_r2 = scrmf.fd_r3 = 0; + + pxy[0] = src.g_x; + pxy[1] = src.g_y; + pxy[2] = pxy[0] + src.g_w-1; + pxy[3] = pxy[1] + src.g_h-1; + pxy[4] = dst.g_x; + pxy[5] = dst.g_y; + pxy[6] = pxy[4] + dst.g_w-1; + pxy[7] = pxy[5] + dst.g_h-1; + self->lock( self ); + vro_cpyfm( self->vdi_handle, S_ONLY, (short*)&pxy, &devmf, &scrmf); + self->unlock( self ); + + return( 1 ); +} + +static int arc(GEM_PLOTTER self,int x, int y, int radius, int angle1, int angle2, const plot_style_t * pstyle) +{ + //plotter_vdi_clip( self, 1); + vswr_mode( self->vdi_handle, MD_REPLACE ); + if( pstyle->fill_type == PLOT_OP_TYPE_NONE ) + return 1; + if( pstyle->fill_type != PLOT_OP_TYPE_SOLID) { + vsl_rgbcolor( self->vdi_handle, pstyle->stroke_colour); + vsf_perimeter( self->vdi_handle, 1); + vsf_interior( self->vdi_handle, 1 ); + v_arc( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius, angle1*10, angle2*10 ); + } else { + vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour); + vsl_width( self->vdi_handle, 1 ); + vsf_perimeter( self->vdi_handle, 1); + v_arc( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius, angle1*10, angle2*10 ); + } + //plotter_vdi_clip( self, 0); + return ( 1 ); +} + +static int disc(GEM_PLOTTER self,int x, int y, int radius, const plot_style_t * pstyle) +{ + plotter_vdi_clip( self, 1); + if( pstyle->fill_type != PLOT_OP_TYPE_SOLID) { + vsf_rgbcolor( self->vdi_handle, pstyle->stroke_colour ); + vsf_perimeter( self->vdi_handle, 1); + vsf_interior( self->vdi_handle, 0 ); + v_circle( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius ); + } else { + vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour ); + vsf_perimeter( self->vdi_handle, 0); + vsf_interior( self->vdi_handle, FIS_SOLID ); + v_circle( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius ); + } + plotter_vdi_clip( self, 0); + return ( 1 ); +} + + +static int line(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle) +{ + short pxy[4]; + uint32_t lt; + int sw = pstyle->stroke_width; + + pxy[0] = CURFB(self).x + x0; + pxy[1] = CURFB(self).y + y0; + pxy[2] = CURFB(self).x + x1; + pxy[3] = CURFB(self).y + y1; + + plotter_vdi_clip( self, 1); + if( sw == 0) + sw = 1; + NSLT2VDI(lt, pstyle) vsl_type( self->vdi_handle, (lt&0x0F) ); - /* if the line style is not available within VDI system,define own style: */ - if( (lt&0x0F) == 7 ){ - vsl_udsty(self->vdi_handle, ((lt&0xFFFF00) >> 8) ); - } - vsl_width( self->vdi_handle, (short)sw ); - vsl_rgbcolor( self->vdi_handle, pstyle->stroke_colour ); - v_pline(self->vdi_handle, 2, (short *)&pxy ); - plotter_vdi_clip( self, 0); - return ( 1 ); -} - -static int rectangle(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle) -{ - short pxy[4]; + /* if the line style is not available within VDI system,define own style: */ + if( (lt&0x0F) == 7 ){ + vsl_udsty(self->vdi_handle, ((lt&0xFFFF00) >> 8) ); + } + vsl_width( self->vdi_handle, (short)sw ); + vsl_rgbcolor( self->vdi_handle, pstyle->stroke_colour ); + v_pline(self->vdi_handle, 2, (short *)&pxy ); + plotter_vdi_clip( self, 0); + return ( 1 ); +} + +static int rectangle(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle) +{ + short pxy[4]; GRECT r, rclip, sclip; - int sw = pstyle->stroke_width; + int sw = pstyle->stroke_width; uint32_t lt; - /* current canvas clip: */ - rclip.g_x = self->clipping.x0; - rclip.g_y = self->clipping.y0; - rclip.g_w = self->clipping.x1 - self->clipping.x0; - rclip.g_h = self->clipping.y1 - self->clipping.y0; - - /* physical clipping: */ - sclip.g_x = rclip.g_x; - sclip.g_y = rclip.g_y; - sclip.g_w = CURFB(self).vis_w; - sclip.g_h = CURFB(self).vis_h; - - rc_intersect(&sclip, &rclip); - r.g_x = x0; - r.g_y = y0; - r.g_w = x1 - x0; + /* current canvas clip: */ + rclip.g_x = self->clipping.x0; + rclip.g_y = self->clipping.y0; + rclip.g_w = self->clipping.x1 - self->clipping.x0; + rclip.g_h = self->clipping.y1 - self->clipping.y0; + + /* physical clipping: */ + sclip.g_x = rclip.g_x; + sclip.g_y = rclip.g_y; + sclip.g_w = CURFB(self).vis_w; + sclip.g_h = CURFB(self).vis_h; + + rc_intersect(&sclip, &rclip); + r.g_x = x0; + r.g_y = y0; + r.g_w = x1 - x0; r.g_h = y1 - y0; if( !rc_intersect( &rclip, &r ) ) { - return( 1 ); + return( 1 ); } if( pstyle->stroke_type != PLOT_OP_TYPE_NONE ){ /* manually draw the line, because we do not need vdi clipping for vertical / horizontal line draws. */ - if( sw == 0) + if( sw == 0) sw = 1; - NSLT2VDI(lt, pstyle); + NSLT2VDI(lt, pstyle); vsl_type( self->vdi_handle, (lt&0x0F) ); /* if the line style is not available within VDI system, define own style: - */ - if( (lt&0x0F) == 7 ){ - vsl_udsty(self->vdi_handle, ((lt&0xFFFF00) >> 8) ); - } - vsl_width( self->vdi_handle, (short)sw ); + */ + if( (lt&0x0F) == 7 ){ + vsl_udsty(self->vdi_handle, ((lt&0xFFFF00) >> 8) ); + } + vsl_width( self->vdi_handle, (short)sw ); vsl_rgbcolor( self->vdi_handle, pstyle->stroke_colour ); /* top border: */ if( r.g_y == y0){ - pxy[0] = CURFB(self).x + r.g_x; - pxy[1] = CURFB(self).y + r.g_y ; - pxy[2] = CURFB(self).x + r.g_x + r.g_w; + pxy[0] = CURFB(self).x + r.g_x; + pxy[1] = CURFB(self).y + r.g_y ; + pxy[2] = CURFB(self).x + r.g_x + r.g_w; pxy[3] = CURFB(self).y + r.g_y; v_pline(self->vdi_handle, 2, (short *)&pxy ); } /* right border: */ if( r.g_x + r.g_w == x1 ){ - pxy[0] = CURFB(self).x + r.g_x + r.g_w; - pxy[1] = CURFB(self).y + r.g_y; - pxy[2] = CURFB(self).x + r.g_x + r.g_w; + pxy[0] = CURFB(self).x + r.g_x + r.g_w; + pxy[1] = CURFB(self).y + r.g_y; + pxy[2] = CURFB(self).x + r.g_x + r.g_w; pxy[3] = CURFB(self).y + r.g_y + r.g_h; v_pline(self->vdi_handle, 2, (short *)&pxy ); } /* bottom border: */ if( r.g_y+r.g_h == y1 ){ - pxy[0] = CURFB(self).x + r.g_x; - pxy[1] = CURFB(self).y + r.g_y+r.g_h; - pxy[2] = CURFB(self).x + r.g_x+r.g_w; + pxy[0] = CURFB(self).x + r.g_x; + pxy[1] = CURFB(self).y + r.g_y+r.g_h; + pxy[2] = CURFB(self).x + r.g_x+r.g_w; pxy[3] = CURFB(self).y + r.g_y+r.g_h; v_pline(self->vdi_handle, 2, (short *)&pxy ); } /* left border: */ if( r.g_x == x0 ){ - pxy[0] = CURFB(self).x + r.g_x; - pxy[1] = CURFB(self).y + r.g_y; - pxy[2] = CURFB(self).x + r.g_x; + pxy[0] = CURFB(self).x + r.g_x; + pxy[1] = CURFB(self).y + r.g_y; + pxy[2] = CURFB(self).x + r.g_x; pxy[3] = CURFB(self).y + r.g_y + r.g_h; v_pline(self->vdi_handle, 2, (short *)&pxy ); } } - if( pstyle->fill_type != PLOT_OP_TYPE_NONE ){ - vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour ); - vsf_perimeter( self->vdi_handle, 0); - vsf_interior( self->vdi_handle, FIS_SOLID ); - - pxy[0] = CURFB(self).x + r.g_x+pstyle->stroke_width; - pxy[1] = CURFB(self).y + r.g_y+pstyle->stroke_width; - pxy[2] = CURFB(self).x + r.g_x + r.g_w -1 - pstyle->stroke_width ; - pxy[3] = CURFB(self).y + r.g_y + r.g_h -1 - pstyle->stroke_width; + if( pstyle->fill_type != PLOT_OP_TYPE_NONE ){ + vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour ); + vsf_perimeter( self->vdi_handle, 0); + vsf_interior( self->vdi_handle, FIS_SOLID ); + + pxy[0] = CURFB(self).x + r.g_x+pstyle->stroke_width; + pxy[1] = CURFB(self).y + r.g_y+pstyle->stroke_width; + pxy[2] = CURFB(self).x + r.g_x + r.g_w -1 - pstyle->stroke_width ; + pxy[3] = CURFB(self).y + r.g_y + r.g_h -1 - pstyle->stroke_width; vsf_style( self->vdi_handle, 1); v_bar( self->vdi_handle, (short*)&pxy ); } - + return ( 1 ); } @@ -766,128 +757,378 @@ static int bitmap_resize( GEM_PLOTTER self, struct bitmap * img, int nw, int nh return( 0 ); } + +// create snapshot, native screen format +static MFDB * snapshot_create_native_mfdb( GEM_PLOTTER self, int x, int y, int w, int h) +{ + MFDB scr; + short pxy[8]; + + /* allocate memory for the snapshot */ + { + int scr_stride = MFDB_STRIDE( w ); + int scr_size = ( ((scr_stride >> 3) * h) * vdi_sysinfo.scr_bpp ); + if( DUMMY_PRIV(self)->size_buf_scr == 0 ){ + /* init screen mfdb */ + DUMMY_PRIV(self)->buf_scr.fd_addr = malloc( scr_size ); + DUMMY_PRIV(self)->size_buf_scr = scr_size; + } else { + if( scr_size > DUMMY_PRIV(self)->size_buf_scr ) { + DUMMY_PRIV(self)->buf_scr.fd_addr = realloc( + DUMMY_PRIV(self)->buf_scr.fd_addr, scr_size + ); + DUMMY_PRIV(self)->size_buf_scr = scr_size; + } + } + if( DUMMY_PRIV(self)->buf_scr.fd_addr == NULL ) { + DUMMY_PRIV(self)->size_buf_scr = 0; + return( NULL ); + } + DUMMY_PRIV(self)->buf_scr.fd_nplanes = vdi_sysinfo.scr_bpp; + DUMMY_PRIV(self)->buf_scr.fd_w = scr_stride; + DUMMY_PRIV(self)->buf_scr.fd_h = h; + DUMMY_PRIV(self)->buf_scr.fd_wdwidth = scr_stride >> 4; + assert( DUMMY_PRIV(self)->buf_scr.fd_addr != NULL ); + } + init_mfdb( 0, w, h, 0, &scr ); + pxy[0] = x; + pxy[1] = y; + pxy[2] = pxy[0] + w-1; + pxy[3] = pxy[1] + h-1; + pxy[4] = 0; + pxy[5] = 0; + pxy[6] = w-1; + pxy[7] = h-1; + vro_cpyfm( + self->vdi_handle, S_ONLY, (short*)&pxy, + &scr, &DUMMY_PRIV(self)->buf_scr + ); + dbg_pxy("ntv snap", pxy ); + +/* +Debug: output copy to screen: + pxy[0] = 0; + pxy[1] = 0; + pxy[2] = pxy[0] + w-1; + pxy[3] = pxy[1] + h-1; + pxy[4] = x+20; + pxy[5] = y; + pxy[6] = w-1; + pxy[7] = h-1; + vro_cpyfm( + self->vdi_handle, S_ONLY, (short*)&pxy, + &DUMMY_PRIV(self)->buf_scr,&scr + ); +*/ + + return( &DUMMY_PRIV(self)->buf_scr ); +} + +// create snapshot, vdi std. format +static MFDB * snapshot_create_std_mfdb(GEM_PLOTTER self, int x, int y, int w, int h) +{ + /* allocate memory for the snapshot */ + { + int scr_stride = MFDB_STRIDE( w ); + int scr_size = ( ((scr_stride >> 3) * h) * app.nplanes ); + if( DUMMY_PRIV(self)->size_buf_std == 0 ){ + /* init screen mfdb */ + DUMMY_PRIV(self)->buf_std.fd_addr = malloc( scr_size ); + DUMMY_PRIV(self)->size_buf_std = scr_size; + } else { + if( scr_size > DUMMY_PRIV(self)->size_buf_std ) { + DUMMY_PRIV(self)->buf_std.fd_addr = realloc( + DUMMY_PRIV(self)->buf_std.fd_addr, scr_size + ); + DUMMY_PRIV(self)->size_buf_std = scr_size; + } + } + if( DUMMY_PRIV(self)->buf_std.fd_addr == NULL ) { + DUMMY_PRIV(self)->size_buf_std = 0; + return( NULL ); + } + DUMMY_PRIV(self)->buf_std.fd_nplanes = app.nplanes; + DUMMY_PRIV(self)->buf_std.fd_w = scr_stride; + DUMMY_PRIV(self)->buf_std.fd_h = h; + DUMMY_PRIV(self)->buf_std.fd_stand = 1; + DUMMY_PRIV(self)->buf_std.fd_wdwidth = scr_stride >> 4; + assert( DUMMY_PRIV(self)->buf_std.fd_addr != NULL ); + } + MFDB * native = snapshot_create_native_mfdb( self, x,y,w,h ); + assert( native ); + + vr_trnfm( self->vdi_handle, native, &DUMMY_PRIV(self)->buf_std ); + return( &DUMMY_PRIV(self)->buf_std ); +} + +/* + This will create an snapshot of the screen in netsurf ABGR format +*/ +static struct bitmap * snapshot_create(GEM_PLOTTER self, int x, int y, int w, int h) +{ + int err; + MFDB * native; + + native = snapshot_create_native_mfdb( self, x, y, w, h ); + + /* allocate buffer for result bitmap: */ + if( DUMMY_PRIV(self)->buf_scr_compat == NULL ) { + DUMMY_PRIV(self)->buf_scr_compat = bitmap_create(w, h, 0); + } else { + DUMMY_PRIV(self)->buf_scr_compat = bitmap_realloc( w, h, + DUMMY_PRIV(self)->buf_scr_compat->bpp, + w * DUMMY_PRIV(self)->buf_scr_compat->bpp, + BITMAP_GROW, + DUMMY_PRIV(self)->buf_scr_compat ); + } + + /* convert screen buffer to ns format: */ + err = Hermes_ConverterRequest( hermes_cnv_h, + &DUMMY_PRIV(self)->vfmt, + &DUMMY_PRIV(self)->nsfmt + ); + assert( err != 0 ); + err = Hermes_ConverterCopy( hermes_cnv_h, + native->fd_addr, + 0, /* x src coord of top left in pixel coords */ + 0, /* y src coord of top left in pixel coords */ + w, h, + native->fd_w * vdi_sysinfo.pixelsize, /* stride as bytes */ + DUMMY_PRIV(self)->buf_scr_compat->pixdata, + 0, /* x dst coord of top left in pixel coords */ + 0, /* y dst coord of top left in pixel coords */ + w, h, + bitmap_get_rowstride(DUMMY_PRIV(self)->buf_scr_compat) /* stride as bytes */ + ); + assert( err != 0 ); + return( (struct bitmap * )DUMMY_PRIV(self)->buf_scr_compat ); +} + +static void snapshot_suspend(GEM_PLOTTER self ) +{ + if( DUMMY_PRIV(self)->size_buf_scr > CONV_KEEP_LIMIT ) { + DUMMY_PRIV(self)->buf_scr.fd_addr = realloc( + DUMMY_PRIV(self)->buf_scr.fd_addr, CONV_KEEP_LIMIT + ); + if( DUMMY_PRIV(self)->buf_scr.fd_addr != NULL ) { + DUMMY_PRIV(self)->size_buf_scr = CONV_KEEP_LIMIT; + } else { + DUMMY_PRIV(self)->size_buf_scr = 0; + } + } + + if( DUMMY_PRIV(self)->size_buf_std > CONV_KEEP_LIMIT ) { + DUMMY_PRIV(self)->buf_std.fd_addr = realloc( + DUMMY_PRIV(self)->buf_std.fd_addr, CONV_KEEP_LIMIT + ); + if( DUMMY_PRIV(self)->buf_std.fd_addr != NULL ) { + DUMMY_PRIV(self)->size_buf_std = CONV_KEEP_LIMIT; + } else { + DUMMY_PRIV(self)->size_buf_std = 0; + } + } + + if( bitmap_buffer_size( DUMMY_PRIV(self)->buf_scr_compat ) > CONV_KEEP_LIMIT ) { + int w = 0; + int h = 1; + w = (CONV_KEEP_LIMIT / DUMMY_PRIV(self)->buf_scr_compat->bpp); + assert( CONV_KEEP_LIMIT == w*DUMMY_PRIV(self)->buf_scr_compat->bpp ); + DUMMY_PRIV(self)->buf_scr_compat = bitmap_realloc( w, h, + DUMMY_PRIV(self)->buf_scr_compat->bpp, + CONV_KEEP_LIMIT, BITMAP_SHRINK, DUMMY_PRIV(self)->buf_scr_compat + ); + } +} + +static void snapshot_destroy( GEM_PLOTTER self ) +{ + if( DUMMY_PRIV(self)->buf_scr.fd_addr ) { + free( DUMMY_PRIV(self)->buf_scr.fd_addr ); + DUMMY_PRIV(self)->buf_scr.fd_addr = NULL; + } + + if( DUMMY_PRIV(self)->buf_std.fd_addr ) { + free( DUMMY_PRIV(self)->buf_std.fd_addr ); + DUMMY_PRIV(self)->buf_std.fd_addr = NULL; + } + + if( DUMMY_PRIV(self)->buf_scr_compat ) { + bitmap_destroy( DUMMY_PRIV(self)->buf_scr_compat ); + DUMMY_PRIV(self)->buf_scr_compat = NULL; + } +} + -static struct bitmap * snapshot_create(GEM_PLOTTER self, int x, int y, int w, int h) -{ - MFDB scr; - short pxy[8]; - int err; - - /* make sure the screen format is pixel packed... */ - /* no method to convert planar screen to pixel packed ... right now */ - assert( vdi_sysinfo.vdiformat == VDI_FORMAT_PACK ); - - { - int scr_stride = MFDB_STRIDE( w ); - int scr_size = ( ((scr_stride >> 3) * h) * vdi_sysinfo.scr_bpp ); - if( DUMMY_PRIV(self)->size_buf_scr == 0 ){ - /* init screen mfdb */ - DUMMY_PRIV(self)->buf_scr.fd_addr = malloc( scr_size ); - DUMMY_PRIV(self)->size_buf_scr = scr_size; - } else { - if( scr_size > DUMMY_PRIV(self)->size_buf_scr ) { - DUMMY_PRIV(self)->buf_scr.fd_addr = realloc( - DUMMY_PRIV(self)->buf_scr.fd_addr, scr_size - ); - DUMMY_PRIV(self)->size_buf_scr = scr_size; - } - } - if( DUMMY_PRIV(self)->buf_scr.fd_addr == NULL ) { - DUMMY_PRIV(self)->size_buf_scr = 0; - return( NULL ); - } - DUMMY_PRIV(self)->buf_scr.fd_nplanes = vdi_sysinfo.scr_bpp; - DUMMY_PRIV(self)->buf_scr.fd_w = scr_stride; - DUMMY_PRIV(self)->buf_scr.fd_h = h; - DUMMY_PRIV(self)->buf_scr.fd_wdwidth = scr_stride >> 4; - assert( DUMMY_PRIV(self)->buf_scr.fd_addr != NULL ); - } - - init_mfdb( 0, w, h, 0, &scr ); - pxy[0] = x; - pxy[1] = y; - pxy[2] = pxy[0] + w-1; - pxy[3] = pxy[1] + h-1; - pxy[4] = 0; - pxy[5] = 0; - pxy[6] = pxy[2]; - pxy[7] = pxy[3]; - vro_cpyfm( - self->vdi_handle, S_ONLY, (short*)&pxy, - &scr, &DUMMY_PRIV(self)->buf_scr - ); - - /* convert screen buffer to ns format: */ - if( DUMMY_PRIV(self)->buf_scr_compat == NULL ) { - DUMMY_PRIV(self)->buf_scr_compat = bitmap_create(w, h, 0); - } else { - DUMMY_PRIV(self)->buf_scr_compat = bitmap_realloc( w, h, - DUMMY_PRIV(self)->buf_scr_compat->bpp, - w * DUMMY_PRIV(self)->buf_scr_compat->bpp, - BITMAP_GROW, - DUMMY_PRIV(self)->buf_scr_compat ); - } - err = Hermes_ConverterRequest( hermes_cnv_h, - &DUMMY_PRIV(self)->vfmt, - &DUMMY_PRIV(self)->nsfmt - ); - assert( err != 0 ); - err = Hermes_ConverterCopy( hermes_cnv_h, - DUMMY_PRIV(self)->buf_scr.fd_addr, - 0, /* x src coord of top left in pixel coords */ - 0, /* y src coord of top left in pixel coords */ - w, h, - DUMMY_PRIV(self)->buf_scr.fd_w * vdi_sysinfo.pixelsize, /* stride as bytes */ - DUMMY_PRIV(self)->buf_scr_compat->pixdata, - 0, /* x dst coord of top left in pixel coords */ - 0, /* y dst coord of top left in pixel coords */ - w, h, - bitmap_get_rowstride(DUMMY_PRIV(self)->buf_scr_compat) /* stride as bytes */ - ); - assert( err != 0 ); - return( (struct bitmap * )DUMMY_PRIV(self)->buf_scr_compat ); -} - -static void snapshot_suspend(GEM_PLOTTER self ) -{ - if( DUMMY_PRIV(self)->size_buf_scr > CONV_KEEP_LIMIT ) { - DUMMY_PRIV(self)->buf_scr.fd_addr = realloc( - DUMMY_PRIV(self)->buf_scr.fd_addr, CONV_KEEP_LIMIT - ); - if( DUMMY_PRIV(self)->buf_scr.fd_addr != NULL ) { - DUMMY_PRIV(self)->size_buf_scr = CONV_KEEP_LIMIT; - } else { - DUMMY_PRIV(self)->size_buf_scr = 0; - } - } - - if( bitmap_buffer_size( DUMMY_PRIV(self)->buf_scr_compat ) > CONV_KEEP_LIMIT ) { - int w = 0; - int h = 1; - w = (CONV_KEEP_LIMIT / DUMMY_PRIV(self)->buf_scr_compat->bpp); - assert( CONV_KEEP_LIMIT == w*DUMMY_PRIV(self)->buf_scr_compat->bpp ); - DUMMY_PRIV(self)->buf_scr_compat = bitmap_realloc( w, h, - DUMMY_PRIV(self)->buf_scr_compat->bpp, - CONV_KEEP_LIMIT, BITMAP_SHRINK, DUMMY_PRIV(self)->buf_scr_compat - ); - } -} - -static void snapshot_destroy( GEM_PLOTTER self ) +void set_stdpx( MFDB * dst, int x, int y, unsigned char val ) { - if( DUMMY_PRIV(self)->buf_scr.fd_addr ) { - free( DUMMY_PRIV(self)->buf_scr.fd_addr ); - DUMMY_PRIV(self)->buf_scr.fd_addr = NULL; + int p; + short * buf; + int wdplanesz = dst->fd_wdwidth*dst->fd_h; + short whichbit = (1<<(15-(x%16))); + + buf = dst->fd_addr; + buf += ((dst->fd_wdwidth*(y))+(x>>4)); + for( p=0; p<=dst->fd_nplanes-1; p++) { + *buf = (val&(1<buf_scr_compat ) { - bitmap_destroy( DUMMY_PRIV(self)->buf_scr_compat ); - DUMMY_PRIV(self)->buf_scr_compat = NULL; - } -} - +} + +unsigned char get_stdpx(MFDB * dst, int x, int y ) +{ + unsigned char ret=0; + int p; + short * buf; + int wdplanesz = dst->fd_wdwidth*dst->fd_h; + short whichbit = (1<<(15-(x%16))); + + buf = dst->fd_addr; + buf += ((dst->fd_wdwidth*(y))+(x>>4)); + for( p=0; p<=dst->fd_nplanes-1; p++) { + if( *buf & whichbit ) + ret |= (01<g_h > 0 ); + assert( clip->g_w > 0 ); + + bm = img; + bw = bitmap_get_width( img ); + + dststride = MFDB_STRIDE( clip->g_w ); + dstsize = ( ((dststride >> 3) * clip->g_h) * self->bpp_virt ); + + /* (re)allocate buffer for out image: */ + /* altough the buffer is named "buf_packed" on 8bit systems */ + /* it's not... */ + if( dstsize > DUMMY_PRIV(self)->size_buf_packed) { + int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1; + if( DUMMY_PRIV(self)->buf_packed == NULL ) + DUMMY_PRIV(self)->buf_packed =(void*)malloc( blocks * CONV_BLOCK_SIZE ); + else + DUMMY_PRIV(self)->buf_packed =(void*)realloc( + DUMMY_PRIV(self)->buf_packed, + blocks * CONV_BLOCK_SIZE + ); + assert( DUMMY_PRIV(self)->buf_packed ); + if( DUMMY_PRIV(self)->buf_packed == NULL ) { + return( 0-ERR_NO_MEM ); + } + DUMMY_PRIV(self)->size_buf_packed = blocks * CONV_BLOCK_SIZE; + } + + + /* + on 8 bit systems we must convert the TC (ABGR) image + to vdi standard format. ( only tested for 256 colors ) + and then convert it to native format + */ + + // realloc mem for stdform + MFDB stdform; + if( ((self->flags & PLOT_FLAG_TRANS) != 0) || ( (flags & BITMAP_MONOGLYPH) != 0) ) { + // point image to snapshot buffer, otherwise allocate mem + MFDB * bg = snapshot_create_std_mfdb( self, x+clip->g_x,y+clip->g_y, clip->g_w, clip->g_h ); + stdform.fd_addr = bg->fd_addr; + } else { + if( dstsize > DUMMY_PRIV(self)->size_buf_planar) { + int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1; + if( DUMMY_PRIV(self)->buf_planar == NULL ) + DUMMY_PRIV(self)->buf_planar =(void*)malloc( blocks * CONV_BLOCK_SIZE ); + else + DUMMY_PRIV(self)->buf_planar =(void*)realloc( + DUMMY_PRIV(self)->buf_planar, + blocks * CONV_BLOCK_SIZE + ); + assert( DUMMY_PRIV(self)->buf_planar ); + if( DUMMY_PRIV(self)->buf_planar == NULL ) { + return( 0-ERR_NO_MEM ); + } + DUMMY_PRIV(self)->size_buf_planar = blocks * CONV_BLOCK_SIZE; + } + stdform.fd_addr = DUMMY_PRIV(self)->buf_planar; + } + stdform.fd_w = dststride; + stdform.fd_h = clip->g_h; + stdform.fd_wdwidth = dststride >> 4; + stdform.fd_stand = 1; + stdform.fd_nplanes = (short)self->bpp_virt; + stdform.fd_r1 = stdform.fd_r2 = stdform.fd_r3 = 0; + /*printf("bpp virt: %d, bytestr: %d, planesize %d\n", + self->bpp_virt, ((dststride >> 3) * self->bpp_virt), stdform.fd_wdwidth*stdform.fd_h ); + */ + // convert pixels to std. format + int wdplanesz = stdform.fd_wdwidth*stdform.fd_h; + int bytestride = (dststride >> 3) * self->bpp_virt; + unsigned long max = ((char*)stdform.fd_addr)+dstsize; + int img_stride = bitmap_get_rowstride(bm); + + // first, get snapshot in planar buffer, + // then apply transparency. + for( y=0; yg_h; y++ ){ + uint32_t * imgpixel; + imgpixel = (uint32_t *)(bm->pixdata + (img_stride * (y+clip->g_y))); + for( x=0; xg_w; x++ ){ + uint32_t pixel = imgpixel[x+clip->g_x]; + unsigned long col = ABGR_TO_RGB( (pixel&0xFFFFFF00)>>8 ); + unsigned char val = RGB_TO_VDI( col>>8 ); + if( (pixel&0xFF) == 0 ){ + set_stdpx( &stdform, x,y, get_stdpx( &stdform,x,y ) ); + continue; + } + + if( (pixel&0xFF) >=128 ){ + set_stdpx( &stdform, x,y, val ); + } else { + char rgb[4]; + col = get_stdpx( &stdform,x,y ); + // TBD: use lookup table! + vdi1000_to_rgb( &pal[col], &rgb[0] ); + pixel = ablend( pixel, ((rgb[2] << 16) | (rgb[1] << 8) | (rgb[0]))<<8 ); + col = ABGR_TO_RGB( (pixel&0xFFFFFF00)>>8 ); + val = RGB_TO_VDI( col>>8 ); + set_stdpx( &stdform, x,y, val ); + } + } + } + + // convert into native format: + MFDB native; + native.fd_addr = DUMMY_PRIV(self)->buf_packed; + native.fd_w = dststride; + native.fd_h = clip->g_h; + native.fd_wdwidth = dststride >> 4; + native.fd_stand = 0; + native.fd_nplanes = (short)self->bpp_virt; + native.fd_r1 = native.fd_r2 = native.fd_r3 = 0; + vr_trnfm( self->vdi_handle, &stdform, &native ); + *out = native; + + return(0); +} + /* convert bitmap to the virutal (chunked) framebuffer format */ -static int convert_bitmap( GEM_PLOTTER self, +static int bitmap_convert( GEM_PLOTTER self, struct bitmap * img, int x, int y, @@ -1057,7 +1298,7 @@ static int bitmap( GEM_PLOTTER self, struct bitmap * bmp, int x, int y, pxy[7] = CURFB(self).y + loc.g_y + off.g_h-1; /* Convert the Bitmap to native screen format - ready for output*/ /* This includes blending transparent pixels */ - if( convert_bitmap( self, bmp, pxy[4], pxy[5], &off, bg, flags, &src_mf) != 0 ) { + if( self->bitmap_convert( self, bmp, pxy[4], pxy[5], &off, bg, flags, &src_mf) != 0 ) { return( true ); } vro_cpyfm( self->vdi_handle, S_ONLY, (short*)&pxy, &src_mf, &scrmf); diff --git a/atari/plot/plotter_vdi.h b/atari/plot/plotter_vdi.h index 82cc42e54..61c49aba1 100755 --- a/atari/plot/plotter_vdi.h +++ b/atari/plot/plotter_vdi.h @@ -32,9 +32,14 @@ struct s_vdi_priv_data { int size_buf_planar; /* buffer for plot operations that require device format, */ - /* currently used for transparent mfdb blits: */ + /* currently used for transparent mfdb blits and snapshots: */ MFDB buf_scr; - int size_buf_scr; + int size_buf_scr; + + /* buffer for std form, used during 8bpp snapshot */ + MFDB buf_std; + int size_buf_std; + struct bitmap * buf_scr_compat; /* intermediate bitmap format */ -- cgit v1.2.3