summaryrefslogtreecommitdiff
path: root/atari/plot/plotter_vdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'atari/plot/plotter_vdi.c')
-rwxr-xr-xatari/plot/plotter_vdi.c1713
1 files changed, 0 insertions, 1713 deletions
diff --git a/atari/plot/plotter_vdi.c b/atari/plot/plotter_vdi.c
deleted file mode 100755
index 8b4550e80..000000000
--- a/atari/plot/plotter_vdi.c
+++ /dev/null
@@ -1,1713 +0,0 @@
-/*
- * Copyright 2010 Ole Loots <ole@monochrom.net>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <assert.h>
-#include <windom.h>
-#include <Hermes/Hermes.h>
-
-#include "atari/plot/eddi.h"
-#include "atari/plot/plotter.h"
-#include "atari/plot/plotter_vdi.h"
-
-
-/* assign vdi line style to dst ( netsurf type ) */
-#define NSLT2VDI(dst, src) \
- dst = 0;\
- switch( src->stroke_type ) {\
- case PLOT_OP_TYPE_DOT: \
- dst = (0xAAAA00 | 7);\
- break;\
- case PLOT_OP_TYPE_DASH:\
- dst = 3; \
- break;\
- case PLOT_OP_TYPE_SOLID:\
- case PLOT_OP_TYPE_NONE:\
- 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 put_pixel(GEM_PLOTTER self, int x, int y, int color );
-static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst );
-static int set_clip(GEM_PLOTTER self, const struct rect * clip);
-static int get_clip( GEM_PLOTTER self, struct rect * out );
-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, unsigned char fgcolor, 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 inline void set_stdpx( MFDB * dst, int wdplanesz, int x, int y, unsigned char val );
-static inline unsigned char get_stdpx(MFDB * dst, int wdplanesz, int x, int y );
-
-/*
- Set clipping for current framebuffer
-*/
-static int plotter_std_clip(GEM_PLOTTER self, const struct rect * clip);
-
-
-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 short prev_vdi_clip[4];
-static struct bitmap snapshot;
-
-#ifdef WITH_8BPP_SUPPORT
-static unsigned short sys_pal[256][3]; /*RGB*/
-static unsigned short pal[256][3]; /*RGB*/
-static char rgb_lookup[256][4];
-extern unsigned short vdi_web_pal[216][3];
-#endif
-
-
-static inline void vsl_rgbcolor( short vdih, uint32_t cin )
-{
- #ifdef WITH_8BPP_SUPPORT
- if( vdi_sysinfo.scr_bpp > 8 ) {
- #endif
- 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 );
- #ifdef WITH_8BPP_SUPPORT
- } else {
- if( vdi_sysinfo.scr_bpp >= 4 ){
- vsl_color( vdih, RGB_TO_VDI(cin) );
- }
- else
- vsl_color( vdih, BLACK );
- }
- #endif
-}
-
-static inline void vsf_rgbcolor( short vdih, uint32_t cin )
-{
- #ifdef WITH_8BPP_SUPPORT
- if( vdi_sysinfo.scr_bpp > 8 ) {
- #endif
- 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 );
- #ifdef WITH_8BPP_SUPPORT
- } else {
- if( vdi_sysinfo.scr_bpp >= 4 ){
- vsf_color( vdih, RGB_TO_VDI(cin) );
- }
- else
- vsf_color( vdih, WHITE );
- }
- #endif
-}
-
-static int set_clip(GEM_PLOTTER self, const struct rect * clip)
-{
- // FIXME: consider the canvas size
- VIEW( self ).clipping.x0 = clip->x0;
- VIEW( self ).clipping.y0 = clip->y0;
- VIEW( self ).clipping.x1 = clip->x1;
- VIEW( self ).clipping.y1 = clip->y1;
- return ( 1 );
-}
-
-static int get_clip( GEM_PLOTTER self, struct rect * out )
-{
- out->x0 = VIEW( self ).clipping.x0;
- out->y0 = VIEW( self ).clipping.y0;
- out->x1 = VIEW( self ).clipping.x1;
- out->y1 = VIEW( self ).clipping.y1;
- return( 1 );
-}
-
-/*
- Get current visible coords
-*/
-static inline void plotter_get_visible_grect( GEM_PLOTTER self, GRECT * out )
-{
- out->g_x = VIEW( self ).vis_x;
- out->g_y = VIEW( self ).vis_y;
- out->g_w = VIEW( self ).vis_w;
- out->g_h = VIEW( self ).vis_h;
-}
-
-
-/*
- 1. calculate visible area of framebuffer in coords relative to framebuffer position
-
- result:
- this function should calculates an rectangle relative to the plot origin and
- size.
- If the ploter coords do not fall within the screen region,
- all values of the region are set to zero.
-*/
-static inline void update_visible_rect( GEM_PLOTTER p )
-{
- GRECT screen;
- GRECT common;
- GRECT frame;
-
- screen.g_x = 0;
- screen.g_y = 0;
- screen.g_w = vdi_sysinfo.scr_w;
- screen.g_h = vdi_sysinfo.scr_h;
-
- common.g_x = frame.g_x = VIEW(p).x;
- common.g_y = frame.g_y = VIEW(p).y;
- common.g_w = frame.g_w = VIEW(p).w;
- common.g_h = frame.g_h = VIEW(p).h;
-
- if( rc_intersect( &screen, &common ) ) {
- VIEW(p).vis_w = common.g_w;
- VIEW(p).vis_h = common.g_h;
- if( VIEW(p).x < screen.g_x )
- VIEW(p).vis_x = frame.g_w - common.g_w;
- else
- VIEW(p).vis_x = 0;
- if( VIEW(p).y <screen.g_y )
- VIEW(p).vis_y = frame.g_h - common.g_h;
- else
- VIEW(p).vis_y = 0;
- } else {
- VIEW(p).vis_w = VIEW(p).vis_h = 0;
- VIEW(p).vis_x = VIEW(p).vis_y = 0;
- }
-}
-
-/*
- Returns the visible parts of the box (relative coords within framebuffer),
- relative to screen coords (normally starting at 0,0 )
-*/
-static inline bool fbrect_to_screen( GEM_PLOTTER self, GRECT box, GRECT * ret )
-{
- GRECT out, vis, screen;
-
- screen.g_x = 0;
- screen.g_y = 0;
- screen.g_w = vdi_sysinfo.scr_w;
- screen.g_h = vdi_sysinfo.scr_h;
-
- /* get visible region: */
- vis.g_x = VIEW(self).x;
- vis.g_y = VIEW(self).y;
- vis.g_w = VIEW(self).w;
- vis.g_h = VIEW(self).h;
-
- if ( !rc_intersect( &screen, &vis ) ) {
- return( false );
- }
- vis.g_x = VIEW(self).w - vis.g_w;
- vis.g_y = VIEW(self).h - vis.g_h;
-
- /* clip box to visible region: */
- if( !rc_intersect(&vis, &box) ) {
- return( false );
- }
- out.g_x = box.g_x + VIEW(self).x;
- out.g_y = box.g_y + VIEW(self).y;
- out.g_w = box.g_w;
- out.g_h = box.g_h;
- *ret = out;
- return ( true );
-}
-
-/*
- convert framebuffer clipping to vdi clipping and activates it
-*/
-
-static inline void plotter_vdi_clip( GEM_PLOTTER self, bool set)
-{
- return;
- if( set == true ) {
- struct rect c;
- short vdiflags[58];
- short newclip[4];
- self->get_clip( self, &c );
- vq_extnd( self->vdi_handle, 1, (short*)&vdiflags);
- prev_vdi_clip[0] = vdiflags[45];
- prev_vdi_clip[1] = vdiflags[46];
- prev_vdi_clip[2] = vdiflags[47];
- prev_vdi_clip[3] = vdiflags[48];
- newclip[0] = VIEW(self).x + MAX(c.x0, 0);
- newclip[1] = VIEW(self).y + MAX(c.y0, 0);
- newclip[2] = MIN(VIEW(self).x+VIEW(self).w, newclip[0] + (c.x1 - c.x0) )-1;
- newclip[3] = MIN(VIEW(self).y+VIEW(self).h, newclip[1] + (c.y1 - c.y0) )-1;
- vs_clip( self->vdi_handle, 1, (short*)&newclip );
- } else {
- vs_clip( self->vdi_handle, 1, (short *)&prev_vdi_clip );
- }
-}
-
-int ctor_plotter_vdi( GEM_PLOTTER self , GRECT * loc_size )
-{
- int retval = 0;
- int i;
- struct rect clip;
-
- self->dtor = dtor;
- self->resize= resize;
- self->move = move;
- self->lock = lock;
- self->unlock = unlock;
- self->put_pixel = put_pixel;
- self->copy_rect = copy_rect;
- self->set_clip = set_clip;
- self->get_clip = get_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;
- /* override virtual bpp - must be in sync with screen for this driver: */
- self->bpp_virt = app.nplanes;
-#ifdef WITH_8BPP_SUPPORT
- self->bitmap_convert =(app.nplanes > 8) ? bitmap_convert : bitmap_convert_8;
-#else
- self->bitmap_convert = bitmap_convert;
-#endif
- 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) );
- memset( &VIEW(self), 0, sizeof( struct s_view) );
- VIEW( self ).x = loc_size->g_x;
- VIEW( self ).y = loc_size->g_y;
- VIEW( self ).w = loc_size->g_w;
- VIEW( self ).h = loc_size->g_h;
- 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;
- }
-
- VIEW(self).mem = NULL;
- update_visible_rect( self );
-
- clip.x0 = 0;
- clip.y0 = 0;
- clip.x1 = VIEW(self).w;
- clip.y1 = VIEW(self).h;
- self->set_clip( self, &clip );
-
- assert( Hermes_Init() );
- /* store system palette & setup the new (web) palette: */
-#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<OFFSET_WEB_PAL ) {
- pal[i][0] = sys_pal[i][0];
- pal[i][1] = sys_pal[i][1];
- pal[i][2] = sys_pal[i][2];
- } else if( app.nplanes >= 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 && i<OFFSET_CUST_PAL+16 ) {
- /* here we define 20 additional gray colors... */
- rgbcol[1] = rgbcol[2] = rgbcol[3] = ((graytone&0x0F) << 4);
- rgb_to_vdi1000( &rgbcol[0], &pal[i][0] );
- vs_color( self->vdi_handle, i, &pal[i][0] );
- graytone++;
- }
-
- }
- vdi1000_to_rgb( &pal[i][0], &rgb_lookup[i][0] );
- }
-
- } else {
- /* no need to change the palette - its application specific */
- }
-
-
-#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__));
-
- if( VIEW(self).mem )
- free( VIEW(self).mem );
-
-#ifdef WITH_8BPP_SUPPORT
- if( DUMMY_PRIV(self)->vfmt.indexed ){
- for( i=OFFSET_WEB_PAL; i<OFFSET_CUST_PAL+16; i++){
- vs_color( self->vdi_handle, i, &sys_pal[i][0] );
- }
- }
-#endif
-
- /* close Hermes stuff: */
- Hermes_ConverterReturn( hermes_cnv_h );
-
- 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 );
- }
- snapshot_destroy( self );
- return( 1 );
-}
-
-static int resize( GEM_PLOTTER self, int w, int h )
-{
- if( w == VIEW(self).w && h == VIEW(self).h )
- return( 1 );
- struct rect newclip = { 0, 0, w-1, h-1 };
- VIEW(self).w = w;
- VIEW(self).h = h;
- update_visible_rect( self );
- set_clip( self, &newclip);
- LOG(("%s: %s\n", (char*)__FILE__, (char*)__FUNCTION__));
- return( 1 );
-}
-static int move( GEM_PLOTTER self,short x, short y )
-{
- bool upd;
- if(x == VIEW(self).x && y == VIEW(self).y ){
- return 1;
- }
- LOG(("%s: x: %d, y: %d\n",(char*)__FUNCTION__, x, y));
- VIEW(self).x = x;
- VIEW(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;
- 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 )
-{
- 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 );
-}
-
-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 = VIEW(self).x + src.g_x;
- src.g_y = VIEW(self).y + src.g_y;
- dst.g_x = VIEW(self).x + dst.g_x;
- dst.g_y = VIEW(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, VIEW(self).x + x, VIEW(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, VIEW(self).x + x, VIEW(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, VIEW(self).x + x, VIEW(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, VIEW(self).x + x, VIEW(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] = VIEW(self).x + x0;
- pxy[1] = VIEW(self).y + y0;
- pxy[2] = VIEW(self).x + x1;
- pxy[3] = VIEW(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];
- GRECT r, rclip, sclip;
- int sw = pstyle->stroke_width;
- uint32_t lt;
-
- /* current canvas clip: */
- rclip.g_x = VIEW( self ).clipping.x0;
- rclip.g_y = VIEW( self ).clipping.y0;
- rclip.g_w = VIEW( self ).clipping.x1 - VIEW( self ).clipping.x0;
- rclip.g_h = VIEW( self ).clipping.y1 - VIEW( self ).clipping.y0;
-
- /* physical clipping: */
- sclip.g_x = rclip.g_x;
- sclip.g_y = rclip.g_y;
- sclip.g_w = VIEW(self).vis_w;
- sclip.g_h = VIEW(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 );
- }
- 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)
- 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 );
- /* top border: */
- if( r.g_y == y0){
- pxy[0] = VIEW(self).x + r.g_x;
- pxy[1] = VIEW(self).y + r.g_y ;
- pxy[2] = VIEW(self).x + r.g_x + r.g_w;
- pxy[3] = VIEW(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] = VIEW(self).x + r.g_x + r.g_w;
- pxy[1] = VIEW(self).y + r.g_y;
- pxy[2] = VIEW(self).x + r.g_x + r.g_w;
- pxy[3] = VIEW(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] = VIEW(self).x + r.g_x;
- pxy[1] = VIEW(self).y + r.g_y+r.g_h;
- pxy[2] = VIEW(self).x + r.g_x+r.g_w;
- pxy[3] = VIEW(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] = VIEW(self).x + r.g_x;
- pxy[1] = VIEW(self).y + r.g_y;
- pxy[2] = VIEW(self).x + r.g_x;
- pxy[3] = VIEW(self).y + r.g_y + r.g_h;
- v_pline(self->vdi_handle, 2, (short *)&pxy );
- }
- }
-
- if( pstyle->fill_type != PLOT_OP_TYPE_NONE ){
- short stroke_width = (short)(pstyle->stroke_type != PLOT_OP_TYPE_NONE) ?
- pstyle->stroke_width : 0;
-
- vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour );
- vsf_perimeter( self->vdi_handle, 0);
- vsf_interior( self->vdi_handle, FIS_SOLID );
-
-
- pxy[0] = VIEW(self).x + r.g_x + stroke_width;
- pxy[1] = VIEW(self).y + r.g_y + stroke_width;
- pxy[2] = VIEW(self).x + r.g_x + r.g_w -1 - stroke_width ;
- pxy[3] = VIEW(self).y + r.g_y + r.g_h -1 - stroke_width;
-
- vsf_style( self->vdi_handle, 1);
- v_bar( self->vdi_handle, (short*)&pxy );
- }
-
- return ( 1 );
-}
-
-static int polygon(GEM_PLOTTER self,const int *p, unsigned int n, const plot_style_t * pstyle)
-{
- short pxy[n*2];
- unsigned int i=0;
- short d[4];
- if( vdi_sysinfo.maxpolycoords > 0 )
- assert( (signed int)n < vdi_sysinfo.maxpolycoords );
- plotter_vdi_clip( self, 1);
- vsf_interior( self->vdi_handle, FIS_SOLID );
- vsf_style( self->vdi_handle, 1);
- for( i = 0; i<n*2; i=i+2 ) {
- pxy[i] = (short)VIEW(self).x+p[i];
- pxy[i+1] = (short)VIEW(self).y+p[i+1];
- }
- if( pstyle->fill_type == PLOT_OP_TYPE_SOLID){
- vsf_rgbcolor( self->vdi_handle, pstyle->fill_colour);
- v_fillarea(self->vdi_handle, n, (short*)&pxy);
-
- } else {
- pxy[n*2]=pxy[0];
- pxy[n*2+1]=pxy[1];
- vsl_rgbcolor( self->vdi_handle, pstyle->stroke_colour);
- v_pline(self->vdi_handle, n+1, (short *)&pxy );
- }
- plotter_vdi_clip( self, 0);
- return ( 1 );
-}
-
-static int path(GEM_PLOTTER self,const float *p, unsigned int n, int fill, float width,
- int c, const float transform[6])
-{
- LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
- return ( 1 );
-}
-
-
-static inline uint32_t ablend(uint32_t pixel, uint32_t scrpixel)
-{
- int opacity = pixel & 0xFF;
- int transp = 0x100 - opacity;
- uint32_t rb, g;
- pixel >>= 8;
- scrpixel >>= 8;
- rb = ((pixel & 0xFF00FF) * opacity +
- (scrpixel & 0xFF00FF) * transp) >> 8;
- g = ((pixel & 0x00FF00) * opacity +
- (scrpixel & 0x00FF00) * transp) >> 8;
-
- return ((rb & 0xFF00FF) | (g & 0xFF00)) << 8;
-}
-
-static int bitmap_resize( GEM_PLOTTER self, struct bitmap * img, int nw, int nh )
-{
- HermesFormat fmt;
- short bpp = bitmap_get_bpp( img );
- int stride = bitmap_get_rowstride( img );
- int err;
-
- if( img->resized != NULL ) {
- if( img->resized->width != nw || img->resized->height != nh ) {
- bitmap_destroy( img->resized );
- img->resized = NULL;
- } else {
- /* the bitmap is already resized */
- return( 0 );
- }
- }
-
- /* allocate the mem for resized bitmap */
- img->resized = bitmap_create_ex( nw, nh, bpp, nw*bpp, 0, NULL );
- if( img->resized == NULL ) {
- printf("W: %d, H: %d, bpp: %d\n", nw, nh, bpp);
- assert( img->resized );
- return ( -ERR_NO_MEM );
- }
-
- /* allocate an converter, only for resizing */
- err = Hermes_ConverterRequest( hermes_res_h,
- &DUMMY_PRIV(self)->nsfmt,
- &DUMMY_PRIV(self)->nsfmt
- );
- if( err == 0 ) {
- return( -ERR_PLOTTER_NOT_AVAILABLE );
- }
-
- err = Hermes_ConverterCopy( hermes_res_h,
- img->pixdata,
- 0, /* x src coord of top left in pixel coords */
- 0, /* y src coord of top left in pixel coords */
- bitmap_get_width( img ), bitmap_get_height( img ),
- stride, /* stride as bytes */
- img->resized->pixdata,
- 0, /* x dst coord of top left in pixel coords */
- 0, /* y dst coord of top left in pixel coords */
- nw, nh,
- bitmap_get_rowstride( img->resized ) /* stride as bytes */
- );
- if( err == 0 ) {
- bitmap_destroy( img->resized );
- img->resized = NULL;
- return( -2 );
- }
-
- 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
- );
-
- 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;
- uint32_t start = clock();
-
- // FIXME: This can be optimized a lot.
- // 1. do not copy the snapshot to the bitmap buffer
- // when the format of screen and bitmap equals.
- // just point the bitmap to the native mfdb.
- // 2. if we have eddi 1.1, we could optimize that further
- // make snapshot_create_native_mfdb just returning a pointer
- // to the screen.
-
- native = snapshot_create_native_mfdb( self, x, y, w, h );
-
- if( DUMMY_PRIV(self)->vfmt.bits == 32 )
- goto no_copy;
-
- /* 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 );
-
-no_copy:
-
- snapshot.width = w;
- snapshot.height = h;
- snapshot.pixdata = native->fd_addr;
- snapshot.native = *native;
- snapshot.rowstride = MFDB_STRIDE( w )*4;
-
- uint32_t row, col;
- for( row = 0; row<h; row++ ){
- // fd_w matches stride!
- uint32_t *rowptr = ((uint32_t*)native->fd_addr + ((row*native->fd_w)));
- for( col=0; col<w; col++){
- *(rowptr+col) = (*(rowptr+col)<<8);
- }
- }
- return( &snapshot );
-}
-
-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( DUMMY_PRIV(self)->buf_scr_compat != NULL ) {
- size_t bs = bitmap_buffer_size( DUMMY_PRIV(self)->buf_scr_compat );
- if( bs > 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 )
-{
-
- free( DUMMY_PRIV(self)->buf_scr.fd_addr );
- if( DUMMY_PRIV(self)->buf_scr_compat != NULL ) {
- bitmap_destroy( DUMMY_PRIV(self)->buf_scr_compat );
- }
-
- DUMMY_PRIV(self)->buf_scr.fd_addr = NULL;
- DUMMY_PRIV(self)->buf_scr_compat = NULL;
-
-#ifdef WITH_8BPP_SUPPORT
- free( DUMMY_PRIV(self)->buf_std.fd_addr );
- DUMMY_PRIV(self)->buf_std.fd_addr = NULL;
-#endif
-}
-
-
-#ifdef WITH_8BPP_SUPPORT
-
-static inline void set_stdpx( MFDB * dst, int wdplanesz, int x, int y, unsigned char val )
-{
- short * buf;
- short whichbit = (1<<(15-(x%16)));
-
- buf = dst->fd_addr;
- buf += ((dst->fd_wdwidth*(y))+(x>>4));
-
- *buf = (val&1) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-
- buf += wdplanesz;
- *buf = (val&(1<<1)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-
- buf += wdplanesz;
- *buf = (val&(1<<2)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-
- buf += wdplanesz;
- *buf = (val&(1<<3)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-
- buf += wdplanesz;
- *buf = (val&(1<<4)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-
- buf += wdplanesz;
- *buf = (val&(1<<5)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-
- buf += wdplanesz;
- *buf = (val&(1<<6)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-
- buf += wdplanesz;
- *buf = (val&(1<<7)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
-}
-
-static inline unsigned char get_stdpx(MFDB * dst, int wdplanesz, int x, int y )
-{
- unsigned char ret=0;
- short * buf;
- short whichbit = (1<<(15-(x%16)));
-
- buf = dst->fd_addr;
- buf += ((dst->fd_wdwidth*(y))+(x>>4));
-
- if( *buf & whichbit )
- ret |= 1;
-
- buf += wdplanesz;
- if( *buf & whichbit )
- ret |= 2;
-
- buf += wdplanesz;
- if( *buf & whichbit )
- ret |= 4;
-
- buf += wdplanesz;
- if( *buf & whichbit )
- ret |= 8;
-
- buf += wdplanesz;
- if( *buf & whichbit )
- ret |= 16;
-
- buf += wdplanesz;
- if( *buf & whichbit )
- ret |= 32;
-
- buf += wdplanesz;
- if( *buf & whichbit )
- ret |= 64;
-
- buf += wdplanesz;
- if( *buf & whichbit )
- ret |= 128;
-
- return( ret );
-}
-
-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 )
-{
- MFDB native;
- MFDB stdform;
- int dststride; /* stride of dest. image */
- int dstsize; /* size of dest. in byte */
- int err;
- int bw, bh;
- int process_w, process_h;
- struct bitmap * scrbuf = NULL;
- struct bitmap * source;
- bool cache = ( flags & BITMAPF_BUFFER_NATIVE );
- bool opaque = bitmap_get_opaque( img );
-
- if( opaque == false ){
- if( ( (self->flags & PLOT_FLAG_TRANS) == 0)
- &&
- ((flags & (BITMAPF_MONOGLYPH|BITMAPF_BUFFER_NATIVE))==0) ){
- opaque = true;
- }
- }
-
- assert( clip->g_h > 0 );
- assert( clip->g_w > 0 );
-
- process_w = bw = bitmap_get_width( img );
- process_h = bh = bitmap_get_height( img );
-
- // The converted bitmap can be saved for subsequent blits, when
- // the bitmap is fully opaque
-
- if( (opaque == true) || (flags & BITMAPF_BUFFER_NATIVE ) ){
- if( img->converted == true ){
- *out = img->native;
- return( 0 );
- }
- if( ( flags & BITMAPF_MONOGLYPH ) == 0 ){
- cache = true;
- }
- }
- if( ( flags & BITMAPF_MONOGLYPH ) != 0 ){
- assert(cache == false);
- }
-
- /* (re)allocate buffer for out image: */
- /* altough the buffer is named "buf_packed" on 8bit systems */
- /* it's not... */
- if( cache == false ){
- // the size of the output will match the size of the clipping:
- dststride = MFDB_STRIDE( clip->g_w );
- dstsize = ( ((dststride >> 3) * clip->g_h) * self->bpp_virt );
- 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;
- }
- native.fd_addr = DUMMY_PRIV(self)->buf_packed;
- }
- else {
- // the output image will be completly saved, so size of the output
- // image will match the input image size.
- dststride = MFDB_STRIDE( bw );
- dstsize = ( ((dststride >> 3) * bh) * self->bpp_virt );
- assert( out->fd_addr == NULL );
- native.fd_addr = (void*)malloc( dstsize );
- if( native.fd_addr == NULL ){
- if( scrbuf != NULL )
- bitmap_destroy( scrbuf );
- return( 0-ERR_NO_MEM );
- }
- }
-
-
- /*
- 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 with v_trnfm()
- */
- // realloc mem for stdform
- if( opaque == false ){
- // point image to snapshot buffer, otherwise allocate mem
- MFDB * bg = snapshot_create_std_mfdb( self, x, y, clip->g_w,
- clip->g_h );
- stdform.fd_addr = bg->fd_addr;
- bh = clip->g_h;
- } 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 = bh;
- 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;
-
- int img_stride = bitmap_get_rowstride(img);
- uint32_t prev_pixel = 0x12345678;
- unsigned long col = 0;
- unsigned char val = 0;
- uint32_t * row;
- uint32_t pixel;
- int wdplanesize = stdform.fd_wdwidth*stdform.fd_h;
-
- if( opaque == false ){
- // apply transparency and convert to vdi std format
- unsigned long bgcol = 0;
- unsigned char prev_col = 0;
- for( y=0; y<clip->g_h; y++ ){
- row = (uint32_t *)(img->pixdata + (img_stride * (y+clip->g_y)));
- for( x=0; x<clip->g_w; x++ ){
- pixel = row[x+clip->g_x];
- if( (pixel&0xFF) == 0 ){
- continue;
- }
- if( (pixel&0xFF) < 0xF0 ){
- col = get_stdpx( &stdform, wdplanesize,x,y );
- if( (col != prev_col) || (y == 0) )
- bgcol = (((rgb_lookup[col][2] << 16) | (rgb_lookup[col][1] << 8) | (rgb_lookup[col][0]))<<8);
- if( prev_col != col || prev_pixel != pixel ){
- prev_col = col;
- pixel = ablend( pixel, bgcol );
- prev_pixel = pixel;
- pixel = pixel >> 8;
- /* convert pixel value to vdi color index: */
- col = ( ((pixel&0xFF)<<16)
- | (pixel&0xFF00)
- | ((pixel&0xFF0000)>>16) );
- val = RGB_TO_VDI( col );
- }
- set_stdpx( &stdform, wdplanesize, x, y, val );
- } else {
- if( pixel != prev_pixel ){
- /* convert pixel value to vdi color index: */
- pixel = pixel >> 8;
- col = ( ((pixel&0xFF)<<16)
- | (pixel&0xFF00)
- | ((pixel&0xFF0000)>>16) );
- val = RGB_TO_VDI( col );
- prev_pixel = pixel;
- }
- set_stdpx( &stdform, wdplanesize, x, y, val );
- }
- }
- }
- // adjust output position:
- clip->g_x = 0;
- clip->g_y = 0;
- } else {
- // convert the whole image data to vdi std format.
- for( y=0; y < bh; y++ ){
- row = (uint32_t *)(img->pixdata + (img_stride * y));
- for( x=0; x < bw; x++ ){
- pixel = row[x];
- if( pixel != prev_pixel ){
- /* convert pixel value to vdi color index: */
- pixel = pixel >> 8;
- col = ( ((pixel&0xFF)<<16)
- | (pixel&0xFF00)
- | ((pixel&0xFF0000)>>16) );
- val = RGB_TO_VDI( col );
- prev_pixel = pixel;
- }
- set_stdpx( &stdform, wdplanesize, x, y, val );
- }
- }
- }
-
- // convert into native format:
- native.fd_w = stdform.fd_w;
- native.fd_h = stdform.fd_h;
- native.fd_wdwidth = stdform.fd_wdwidth;
- 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;
- if( cache == true ){
- img->native = native;
- img->converted = true;
- }
-
- return(0);
-}
-#endif
-
-/*
- Aplha blends the foreground image (img) onto the
- background images (bg). The background receives the blended
- image pixels.
-*/
-static int ablend_bitmap( struct bitmap * img, struct bitmap * bg,
- GRECT * img_clip, GRECT * bg_clip )
-{
- uint32_t * imgrow;
- uint32_t * screenrow;
- int img_x, img_y, bg_x, bg_y, img_stride, bg_stride;
-
- bg_clip = bg_clip;
- img_stride= bitmap_get_rowstride(img);
- bg_stride = bitmap_get_rowstride(bg);
-
- for( img_y = img_clip->g_y, bg_y = 0; bg_y < img_clip->g_h; bg_y++, img_y++) {
- imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
- screenrow = (uint32_t *)(bg->pixdata + (bg_stride * bg_y));
- for( img_x = img_clip->g_x, bg_x = 0; bg_x < img_clip->g_w; bg_x++, img_x++ ) {
-
- // when the pixel isn't fully transparent,...:
- if( (imgrow[img_x] & 0x0FF) != 0 ){
- screenrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
- }
-
- // FIXME, maybe this loop would be faster??:
- // ---
- //if( (imgrow[img_x] & 0x0FF) != 0xFF ){
- // imgrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
- //}
-
- // or maybe even this???
- // ---
- //if( (imgrow[img_x] & 0x0FF) == 0xFF ){
- // screenrow[bg_x] = imgrow[img_x];
- //} else if( (imgrow[img_x] & 0x0FF) != 0x00 ) {
- // screenrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
- //}
- }
- }
- return( 0 );
-}
-
-/*
- Alpha blends an image, using one pixel as the background.
- The bitmap receives the result.
-*/
-static int ablend_pixel( struct bitmap * img, uint32_t bg, GRECT * clip )
-{
- uint32_t * imgrow;
- int img_x, img_y, img_stride;
-
- img_stride= bitmap_get_rowstride(img);
-
- for( img_y = 0; img_y < clip->g_h; img_y++) {
- imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
- for( img_x = 0; img_x < clip->g_w; img_x++ ) {
- imgrow[img_x] = ablend( imgrow[img_x], bg );
- }
- }
- return( 0 );
-}
-
-/*
-*
-* Convert bitmap to the native screen format
-* self: the plotter instance
-* img: the bitmap
-* x: coordinate where the bitmap REGION (described in clip)
-* shall be drawn (screen coords)
-* y: coordinate where the bitmap REGION (described in clip)
-* shall be drawn (screen coords)
-* clip: which area of the bitmap shall be drawn
-* bg: background color
-* flags: blit flags
-* out: the result MFDB
-*/
-static int bitmap_convert( GEM_PLOTTER self, struct bitmap * img, int x, int y,
- GRECT * clip, uint32_t bg, uint32_t flags, MFDB *out )
-{
- int dststride; /* stride of dest. image */
- int dstsize; /* size of dest. in byte */
- int err;
- int bw, bh;
- struct bitmap * scrbuf = NULL;
- struct bitmap * source = NULL;
- bool cache = ( flags & BITMAPF_BUFFER_NATIVE );
- bool opaque = bitmap_get_opaque( img );
-
- if( opaque == false ){
- if( ( (self->flags & PLOT_FLAG_TRANS) == 0)
- &&
- ((flags & (BITMAPF_MONOGLYPH|BITMAPF_BUFFER_NATIVE))==0) ){
- opaque = true;
- }
- }
-
-
- assert( clip->g_h > 0 );
- assert( clip->g_w > 0 );
-
- bw = bitmap_get_width( img );
- bh = bitmap_get_height( img );
-
- // The converted bitmap can be saved for subsequent blits, WHEN:
- // A.) the bitmap is fully opaque OR
- // B.) the bitmap is completly inside the window
- // the latter one is important for alpha blits,
- // because we must get the window background to apply transparency
- // If the image is not completly within the window,
- // we can't get the whole background for the image.
- // this only works if the image isn't used at several different places.
- // In fact in case of alpha bitmap caching it is only used for the
- // toolbar buttons right now.
-
- if( (opaque == true) || (flags & BITMAPF_BUFFER_NATIVE ) ){
- if( img->converted == true ){
- *out = img->native;
- return( 0 );
- }
- if( ( flags & BITMAPF_MONOGLYPH ) == 0 ){
- cache = true;
- }
- }
-
- /* rem. if eddi xy is installed, we could directly access the screen! */
- /* apply transparency to the image: */
- if( ( opaque == false ) ) {
- /* copy the screen to an temp buffer: */
- if( (flags & BITMAPF_BUFFER_NATIVE) == 0 ){
- scrbuf = snapshot_create(self, x, y, clip->g_w, clip->g_h );
- if( scrbuf != NULL ) {
-
- assert( clip->g_w <= bw );
- assert( clip->g_h <= bh );
-
- // copy blended pixels to the screen buffer:
- ablend_bitmap( img, scrbuf, clip, NULL );
- /* adjust size which gets converted: */
- bw = clip->g_w;
- bh = clip->g_h;
- /* adjust output position: */
- clip->g_x = 0;
- clip->g_y = 0;
- /* set the source of conversion: */
- source = scrbuf;
- }
- } else {
- /*
- The whole bitmap can be transformed to an mfdb
- (and get's cached)
- */
- GRECT region = { 0, 0, bw, bh };
- ablend_pixel( img, bg, &region );
- source = img;
- }
- } else {
- source = img;
- }
- /* (re)allocate buffer for converted image: */
- dststride = MFDB_STRIDE( bw );
- dstsize = ( ((dststride >> 3) * bh) * self->bpp_virt );
- if( cache == false ){
- 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 ) {
- if( scrbuf != NULL )
- bitmap_destroy( scrbuf );
- return( 0-ERR_NO_MEM );
- }
- DUMMY_PRIV(self)->size_buf_packed = blocks * CONV_BLOCK_SIZE;
- }
- out->fd_addr = DUMMY_PRIV(self)->buf_packed;
- } else {
- assert( out->fd_addr == NULL );
- out->fd_addr = (void*)malloc( dstsize );
- if( out->fd_addr == NULL ){
- if( scrbuf != NULL )
- bitmap_destroy( scrbuf );
- return( 0-ERR_NO_MEM );
- }
- }
-
- out->fd_w = dststride;
- out->fd_h = bh;
- out->fd_wdwidth = dststride >> 4;
- out->fd_stand = 0;
- out->fd_nplanes = (short)self->bpp_virt;
- out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
-
- err = Hermes_ConverterRequest(
- hermes_cnv_h,
- &DUMMY_PRIV(self)->nsfmt,
- &DUMMY_PRIV(self)->vfmt
- );
- assert( err != 0 );
-
- // FIXME: here we can use the same optimization which is used for
- // the snapshot creation.
-
- /* convert image to virtual format: */
- err = Hermes_ConverterCopy( hermes_cnv_h,
- source->pixdata,
- 0, /* x src coord of top left in pixel coords */
- 0, /* y src coord of top left in pixel coords */
- bw, bh,
- source->rowstride, /* stride as bytes */
- out->fd_addr,
- 0, /* x dst coord of top left in pixel coords */
- 0, /* y dst coord of top left in pixel coords */
- bw, bh,
- (dststride >> 3) * self->bpp_virt /* stride as bytes */
- );
- assert( err != 0 );
-
- if( cache == true ){
- img->native = *out;
- img->converted = true;
- }
- return( 0 );
-
-}
-
-static void convert_bitmap_done( GEM_PLOTTER self )
-{
- if( DUMMY_PRIV(self)->size_buf_packed > CONV_KEEP_LIMIT ) {
- /* free the mem if it was an large allocation ... */
- DUMMY_PRIV(self)->buf_packed = realloc( DUMMY_PRIV(self)->buf_packed, CONV_KEEP_LIMIT );
- DUMMY_PRIV(self)->size_buf_packed = CONV_KEEP_LIMIT;
- }
- snapshot_suspend( self );
-}
-
-
-static int bitmap( GEM_PLOTTER self, struct bitmap * bmp, int x, int y,
- unsigned long bg, unsigned long flags )
-{
- MFDB src_mf;
- MFDB scrmf;
- short pxy[8];
- GRECT off, clip, vis;
- int screen_x, screen_y;
-
- src_mf.fd_addr = NULL;
- scrmf.fd_addr = NULL;
-
- off.g_x = x;
- off.g_y = y;
- off.g_h = bmp->height;
- off.g_w = bmp->width;
-
- // clip plotter clip rectangle:
- clip.g_x = VIEW( self ).clipping.x0;
- clip.g_y = VIEW( self ).clipping.y0;
- clip.g_w = VIEW( self ).clipping.x1 - VIEW( self ).clipping.x0;
- clip.g_h = VIEW( self ).clipping.y1 - VIEW( self ).clipping.y0;
-
- if( !rc_intersect( &clip, &off) ) {
- return( 1 );
- }
-
- // clip the visible rectangle of the plot area
- // this is the area of the plotter which falls into
- // screen region:
- plotter_get_visible_grect( self, &vis );
- if( !rc_intersect( &vis, &off) ) {
- return( 1 );
- }
-
- screen_x = VIEW(self).x + off.g_x;
- screen_y = VIEW(self).y + off.g_y;
-
- // convert the clipping relative to bitmap:
- off.g_x = off.g_x - x;
- off.g_y = off.g_y - y;
- assert( (off.g_x >= 0) && (off.g_y >= 0) );
-
- /* Convert the Bitmap to native screen format - ready for output. */
- /* This includes blending transparent pixels: */
- if( self->bitmap_convert( self, bmp, screen_x, screen_y, &off, bg, flags, &src_mf) != 0 ) {
- return( 1 );
- }
-
- // setup the src region:
- pxy[0] = off.g_x;
- pxy[1] = off.g_y;
- pxy[2] = off.g_x + off.g_w-1;
- pxy[3] = off.g_y + off.g_h-1;
-
- // setup the target region:
- pxy[4] = screen_x;
- pxy[5] = screen_y;
- pxy[6] = screen_x + off.g_w-1;
- pxy[7] = screen_y + off.g_h-1;
-
- vro_cpyfm( self->vdi_handle, S_ONLY, (short*)&pxy, &src_mf, &scrmf);
- convert_bitmap_done( self );
- return( 1 );
-}
-
-static int plot_mfdb (GEM_PLOTTER self, GRECT * loc, MFDB * insrc, unsigned char fgcolor, uint32_t flags)
-{
-
- MFDB screen, tran;
- MFDB * src;
- short pxy[8];
- short c[2] = {fgcolor, WHITE};
- GRECT off;
-
- plotter_get_clip_grect( self, &off );
- if( rc_intersect(loc, &off) == 0 ){
- return( 1 );
- }
-
- init_mfdb( 0, loc->g_w, loc->g_h, 0, &screen );
-
- 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;
- }
-
- pxy[0] = off.g_x - loc->g_x;
- pxy[1] = off.g_y - loc->g_y;
- pxy[2] = pxy[0] + off.g_w - 1;
- pxy[3] = pxy[1] + off.g_h - 1;
- pxy[4] = VIEW(self).x + off.g_x;
- pxy[5] = VIEW(self).y + off.g_y;
- pxy[6] = pxy[4] + off.g_w-1;
- pxy[7] = pxy[5] + off.g_h-1;
-
-
- if( flags & PLOT_FLAG_TRANS && src->fd_nplanes == 1){
- vrt_cpyfm( self->vdi_handle, MD_TRANS, (short*)pxy, src, &screen, (short*)&c );
- } else {
- /* this method only plots transparent bitmaps, right now... */
- }
- 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,
- text, length, fstyle
- );
- return ( 1 );
-}