summaryrefslogtreecommitdiff
path: root/atari/plot/plotter.c
diff options
context:
space:
mode:
Diffstat (limited to 'atari/plot/plotter.c')
-rw-r--r--atari/plot/plotter.c723
1 files changed, 723 insertions, 0 deletions
diff --git a/atari/plot/plotter.c b/atari/plot/plotter.c
new file mode 100644
index 000000000..d21b46540
--- /dev/null
+++ b/atari/plot/plotter.c
@@ -0,0 +1,723 @@
+/*
+ * 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 <windom.h>
+#include <assert.h>
+#include <mint/osbind.h>
+#include <mint/cookie.h>
+#include <Hermes/Hermes.h>
+
+#include "desktop/plot_style.h"
+#include "atari/bitmap.h"
+#include "image/bitmap.h"
+#include "atari/plot/eddi.h"
+#include "atari/plot/plotter.h"
+#include "atari/plot/plotter_vdi.h"
+#include "atari/plot/font_vdi.h"
+#include "atari/plot/font_freetype.h"
+#include "utils/log.h"
+
+
+unsigned char rgb_web_pal[216][3] = {
+ {0x00,0x00,0x00}, {0x33,0x00,0x00}, {0x66,0x00,0x00}, {0x99,0x00,0x00}, {0xcc,0x00,0x00}, {0xff,0x00,0x00},
+ {0x00,0x33,0x00}, {0x33,0x33,0x00}, {0x66,0x33,0x00}, {0x99,0x33,0x00}, {0xcc,0x33,0x00}, {0xff,0x33,0x00},
+ {0x00,0x66,0x00}, {0x33,0x66,0x00}, {0x66,0x66,0x00}, {0x99,0x66,0x00}, {0xcc,0x66,0x00}, {0xff,0x66,0x00},
+ {0x00,0x99,0x00}, {0x33,0x99,0x00}, {0x66,0x99,0x00}, {0x99,0x99,0x00}, {0xcc,0x99,0x00}, {0xff,0x99,0x00},
+ {0x00,0xcc,0x00}, {0x33,0xcc,0x00}, {0x66,0xcc,0x00}, {0x99,0xcc,0x00}, {0xcc,0xcc,0x00}, {0xff,0xcc,0x00},
+ {0x00,0xff,0x00}, {0x33,0xff,0x00}, {0x66,0xff,0x00}, {0x99,0xff,0x00}, {0xcc,0xff,0x00}, {0xff,0xff,0x00},
+ {0x00,0x00,0x33}, {0x33,0x00,0x33}, {0x66,0x00,0x33}, {0x99,0x00,0x33}, {0xcc,0x00,0x33}, {0xff,0x00,0x33},
+ {0x00,0x33,0x33}, {0x33,0x33,0x33}, {0x66,0x33,0x33}, {0x99,0x33,0x33}, {0xcc,0x33,0x33}, {0xff,0x33,0x33},
+ {0x00,0x66,0x33}, {0x33,0x66,0x33}, {0x66,0x66,0x33}, {0x99,0x66,0x33}, {0xcc,0x66,0x33}, {0xff,0x66,0x33},
+ {0x00,0x99,0x33}, {0x33,0x99,0x33}, {0x66,0x99,0x33}, {0x99,0x99,0x33}, {0xcc,0x99,0x33}, {0xff,0x99,0x33},
+ {0x00,0xcc,0x33}, {0x33,0xcc,0x33}, {0x66,0xcc,0x33}, {0x99,0xcc,0x33}, {0xcc,0xcc,0x33}, {0xff,0xcc,0x33},
+ {0x00,0xff,0x33}, {0x33,0xff,0x33}, {0x66,0xff,0x33}, {0x99,0xff,0x33}, {0xcc,0xff,0x33}, {0xff,0xff,0x33},
+ {0x00,0x00,0x66}, {0x33,0x00,0x66}, {0x66,0x00,0x66}, {0x99,0x00,0x66}, {0xcc,0x00,0x66}, {0xff,0x00,0x66},
+ {0x00,0x33,0x66}, {0x33,0x33,0x66}, {0x66,0x33,0x66}, {0x99,0x33,0x66}, {0xcc,0x33,0x66}, {0xff,0x33,0x66},
+ {0x00,0x66,0x66}, {0x33,0x66,0x66}, {0x66,0x66,0x66}, {0x99,0x66,0x66}, {0xcc,0x66,0x66}, {0xff,0x66,0x66},
+ {0x00,0x99,0x66}, {0x33,0x99,0x66}, {0x66,0x99,0x66}, {0x99,0x99,0x66}, {0xcc,0x99,0x66}, {0xff,0x99,0x66},
+ {0x00,0xcc,0x66}, {0x33,0xcc,0x66}, {0x66,0xcc,0x66}, {0x99,0xcc,0x66}, {0xcc,0xcc,0x66}, {0xff,0xcc,0x66},
+ {0x00,0xff,0x66}, {0x33,0xff,0x66}, {0x66,0xff,0x66}, {0x99,0xff,0x66}, {0xcc,0xff,0x66}, {0xff,0xff,0x66},
+ {0x00,0x00,0x99}, {0x33,0x00,0x99}, {0x66,0x00,0x99}, {0x99,0x00,0x99}, {0xcc,0x00,0x99}, {0xff,0x00,0x99},
+ {0x00,0x33,0x99}, {0x33,0x33,0x99}, {0x66,0x33,0x99}, {0x99,0x33,0x99}, {0xcc,0x33,0x99}, {0xff,0x33,0x99},
+ {0x00,0x66,0x99}, {0x33,0x66,0x99}, {0x66,0x66,0x99}, {0x99,0x66,0x99}, {0xcc,0x66,0x99}, {0xff,0x66,0x99},
+ {0x00,0x99,0x99}, {0x33,0x99,0x99}, {0x66,0x99,0x99}, {0x99,0x99,0x99}, {0xcc,0x99,0x99}, {0xff,0x99,0x99},
+ {0x00,0xcc,0x99}, {0x33,0xcc,0x99}, {0x66,0xcc,0x99}, {0x99,0xcc,0x99}, {0xcc,0xcc,0x99}, {0xff,0xcc,0x99},
+ {0x00,0xff,0x99}, {0x33,0xff,0x99}, {0x66,0xff,0x99}, {0x99,0xff,0x99}, {0xcc,0xff,0x99}, {0xff,0xff,0x99},
+ {0x00,0x00,0xcc}, {0x33,0x00,0xcc}, {0x66,0x00,0xcc}, {0x99,0x00,0xcc}, {0xcc,0x00,0xcc}, {0xff,0x00,0xcc},
+ {0x00,0x33,0xcc}, {0x33,0x33,0xcc}, {0x66,0x33,0xcc}, {0x99,0x33,0xcc}, {0xcc,0x33,0xcc}, {0xff,0x33,0xcc},
+ {0x00,0x66,0xcc}, {0x33,0x66,0xcc}, {0x66,0x66,0xcc}, {0x99,0x66,0xcc}, {0xcc,0x66,0xcc}, {0xff,0x66,0xcc},
+ {0x00,0x99,0xcc}, {0x33,0x99,0xcc}, {0x66,0x99,0xcc}, {0x99,0x99,0xcc}, {0xcc,0x99,0xcc}, {0xff,0x99,0xcc},
+ {0x00,0xcc,0xcc}, {0x33,0xcc,0xcc}, {0x66,0xcc,0xcc}, {0x99,0xcc,0xcc}, {0xcc,0xcc,0xcc}, {0xff,0xcc,0xcc},
+ {0x00,0xff,0xcc}, {0x33,0xff,0xcc}, {0x66,0xff,0xcc}, {0x99,0xff,0xcc}, {0xcc,0xff,0xcc}, {0xff,0xff,0xcc},
+ {0x00,0x00,0xff}, {0x33,0x00,0xff}, {0x66,0x00,0xff}, {0x99,0x00,0xff}, {0xcc,0x00,0xff}, {0xff,0x00,0xff},
+ {0x00,0x33,0xff}, {0x33,0x33,0xff}, {0x66,0x33,0xff}, {0x99,0x33,0xff}, {0xcc,0x33,0xff}, {0xff,0x33,0xff},
+ {0x00,0x66,0xff}, {0x33,0x66,0xff}, {0x66,0x66,0xff}, {0x99,0x66,0xff}, {0xcc,0x66,0xff}, {0xff,0x66,0xff},
+ {0x00,0x99,0xff}, {0x33,0x99,0xff}, {0x66,0x99,0xff}, {0x99,0x99,0xff}, {0xcc,0x99,0xff}, {0xff,0x99,0xff},
+ {0x00,0xcc,0xff}, {0x33,0xcc,0xff}, {0x66,0xcc,0xff}, {0x99,0xcc,0xff}, {0xcc,0xcc,0xff}, {0xff,0xcc,0xff},
+ {0x00,0xff,0xff}, {0x33,0xff,0xff}, {0x66,0xff,0xff}, {0x99,0xff,0xff}, {0xcc,0xff,0xff}, {0xff,0xff,0xff}
+};
+
+
+unsigned short vdi_web_pal[216][3] = {
+ {0x000,0x000,0x000}, {0x0c8,0x000,0x000}, {0x190,0x000,0x000}, {0x258,0x000,0x000}, {0x320,0x000,0x000}, {0x3e8,0x000,0x000},
+ {0x000,0x0c8,0x000}, {0x0c8,0x0c8,0x000}, {0x190,0x0c8,0x000}, {0x258,0x0c8,0x000}, {0x320,0x0c8,0x000}, {0x3e8,0x0c8,0x000},
+ {0x000,0x190,0x000}, {0x0c8,0x190,0x000}, {0x190,0x190,0x000}, {0x258,0x190,0x000}, {0x320,0x190,0x000}, {0x3e8,0x190,0x000},
+ {0x000,0x258,0x000}, {0x0c8,0x258,0x000}, {0x190,0x258,0x000}, {0x258,0x258,0x000}, {0x320,0x258,0x000}, {0x3e8,0x258,0x000},
+ {0x000,0x320,0x000}, {0x0c8,0x320,0x000}, {0x190,0x320,0x000}, {0x258,0x320,0x000}, {0x320,0x320,0x000}, {0x3e8,0x320,0x000},
+ {0x000,0x3e8,0x000}, {0x0c8,0x3e8,0x000}, {0x190,0x3e8,0x000}, {0x258,0x3e8,0x000}, {0x320,0x3e8,0x000}, {0x3e8,0x3e8,0x000},
+ {0x000,0x000,0x0c8}, {0x0c8,0x000,0x0c8}, {0x190,0x000,0x0c8}, {0x258,0x000,0x0c8}, {0x320,0x000,0x0c8}, {0x3e8,0x000,0x0c8},
+ {0x000,0x0c8,0x0c8}, {0x0c8,0x0c8,0x0c8}, {0x190,0x0c8,0x0c8}, {0x258,0x0c8,0x0c8}, {0x320,0x0c8,0x0c8}, {0x3e8,0x0c8,0x0c8},
+ {0x000,0x190,0x0c8}, {0x0c8,0x190,0x0c8}, {0x190,0x190,0x0c8}, {0x258,0x190,0x0c8}, {0x320,0x190,0x0c8}, {0x3e8,0x190,0x0c8},
+ {0x000,0x258,0x0c8}, {0x0c8,0x258,0x0c8}, {0x190,0x258,0x0c8}, {0x258,0x258,0x0c8}, {0x320,0x258,0x0c8}, {0x3e8,0x258,0x0c8},
+ {0x000,0x320,0x0c8}, {0x0c8,0x320,0x0c8}, {0x190,0x320,0x0c8}, {0x258,0x320,0x0c8}, {0x320,0x320,0x0c8}, {0x3e8,0x320,0x0c8},
+ {0x000,0x3e8,0x0c8}, {0x0c8,0x3e8,0x0c8}, {0x190,0x3e8,0x0c8}, {0x258,0x3e8,0x0c8}, {0x320,0x3e8,0x0c8}, {0x3e8,0x3e8,0x0c8},
+ {0x000,0x000,0x190}, {0x0c8,0x000,0x190}, {0x190,0x000,0x190}, {0x258,0x000,0x190}, {0x320,0x000,0x190}, {0x3e8,0x000,0x190},
+ {0x000,0x0c8,0x190}, {0x0c8,0x0c8,0x190}, {0x190,0x0c8,0x190}, {0x258,0x0c8,0x190}, {0x320,0x0c8,0x190}, {0x3e8,0x0c8,0x190},
+ {0x000,0x190,0x190}, {0x0c8,0x190,0x190}, {0x190,0x190,0x190}, {0x258,0x190,0x190}, {0x320,0x190,0x190}, {0x3e8,0x190,0x190},
+ {0x000,0x258,0x190}, {0x0c8,0x258,0x190}, {0x190,0x258,0x190}, {0x258,0x258,0x190}, {0x320,0x258,0x190}, {0x3e8,0x258,0x190},
+ {0x000,0x320,0x190}, {0x0c8,0x320,0x190}, {0x190,0x320,0x190}, {0x258,0x320,0x190}, {0x320,0x320,0x190}, {0x3e8,0x320,0x190},
+ {0x000,0x3e8,0x190}, {0x0c8,0x3e8,0x190}, {0x190,0x3e8,0x190}, {0x258,0x3e8,0x190}, {0x320,0x3e8,0x190}, {0x3e8,0x3e8,0x190},
+ {0x000,0x000,0x258}, {0x0c8,0x000,0x258}, {0x190,0x000,0x258}, {0x258,0x000,0x258}, {0x320,0x000,0x258}, {0x3e8,0x000,0x258},
+ {0x000,0x0c8,0x258}, {0x0c8,0x0c8,0x258}, {0x190,0x0c8,0x258}, {0x258,0x0c8,0x258}, {0x320,0x0c8,0x258}, {0x3e8,0x0c8,0x258},
+ {0x000,0x190,0x258}, {0x0c8,0x190,0x258}, {0x190,0x190,0x258}, {0x258,0x190,0x258}, {0x320,0x190,0x258}, {0x3e8,0x190,0x258},
+ {0x000,0x258,0x258}, {0x0c8,0x258,0x258}, {0x190,0x258,0x258}, {0x258,0x258,0x258}, {0x320,0x258,0x258}, {0x3e8,0x258,0x258},
+ {0x000,0x320,0x258}, {0x0c8,0x320,0x258}, {0x190,0x320,0x258}, {0x258,0x320,0x258}, {0x320,0x320,0x258}, {0x3e8,0x320,0x258},
+ {0x000,0x3e8,0x258}, {0x0c8,0x3e8,0x258}, {0x190,0x3e8,0x258}, {0x258,0x3e8,0x258}, {0x320,0x3e8,0x258}, {0x3e8,0x3e8,0x258},
+ {0x000,0x000,0x320}, {0x0c8,0x000,0x320}, {0x190,0x000,0x320}, {0x258,0x000,0x320}, {0x320,0x000,0x320}, {0x3e8,0x000,0x320},
+ {0x000,0x0c8,0x320}, {0x0c8,0x0c8,0x320}, {0x190,0x0c8,0x320}, {0x258,0x0c8,0x320}, {0x320,0x0c8,0x320}, {0x3e8,0x0c8,0x320},
+ {0x000,0x190,0x320}, {0x0c8,0x190,0x320}, {0x190,0x190,0x320}, {0x258,0x190,0x320}, {0x320,0x190,0x320}, {0x3e8,0x190,0x320},
+ {0x000,0x258,0x320}, {0x0c8,0x258,0x320}, {0x190,0x258,0x320}, {0x258,0x258,0x320}, {0x320,0x258,0x320}, {0x3e8,0x258,0x320},
+ {0x000,0x320,0x320}, {0x0c8,0x320,0x320}, {0x190,0x320,0x320}, {0x258,0x320,0x320}, {0x320,0x320,0x320}, {0x3e8,0x320,0x320},
+ {0x000,0x3e8,0x320}, {0x0c8,0x3e8,0x320}, {0x190,0x3e8,0x320}, {0x258,0x3e8,0x320}, {0x320,0x3e8,0x320}, {0x3e8,0x3e8,0x320},
+ {0x000,0x000,0x3e8}, {0x0c8,0x000,0x3e8}, {0x190,0x000,0x3e8}, {0x258,0x000,0x3e8}, {0x320,0x000,0x3e8}, {0x3e8,0x000,0x3e8},
+ {0x000,0x0c8,0x3e8}, {0x0c8,0x0c8,0x3e8}, {0x190,0x0c8,0x3e8}, {0x258,0x0c8,0x3e8}, {0x320,0x0c8,0x3e8}, {0x3e8,0x0c8,0x3e8},
+ {0x000,0x190,0x3e8}, {0x0c8,0x190,0x3e8}, {0x190,0x190,0x3e8}, {0x258,0x190,0x3e8}, {0x320,0x190,0x3e8}, {0x3e8,0x190,0x3e8},
+ {0x000,0x258,0x3e8}, {0x0c8,0x258,0x3e8}, {0x190,0x258,0x3e8}, {0x258,0x258,0x3e8}, {0x320,0x258,0x3e8}, {0x3e8,0x258,0x3e8},
+ {0x000,0x320,0x3e8}, {0x0c8,0x320,0x3e8}, {0x190,0x320,0x3e8}, {0x258,0x320,0x3e8}, {0x320,0x320,0x3e8}, {0x3e8,0x320,0x3e8},
+ {0x000,0x3e8,0x3e8}, {0x0c8,0x3e8,0x3e8}, {0x190,0x3e8,0x3e8}, {0x258,0x3e8,0x3e8}, {0x320,0x3e8,0x3e8}, {0x3e8,0x3e8,0x3e8}
+};
+
+static short prev_vdi_clip[4];
+struct s_vdi_sysinfo vdi_sysinfo;
+
+struct s_driver_table_entry screen_driver_table[] =
+{
+ {(char*)"vdi", ctor_plotter_vdi, 0, 32},
+ {(char*)"screen.ldg", ctor_plotter_vdi, PLOT_FLAG_OFFSCREEN, 32 },
+ {(char*)"vdi_offscreen", ctor_plotter_vdi, PLOT_FLAG_OFFSCREEN, 32},
+ {(char*)NULL, NULL, 0, 0 }
+};
+
+const struct s_font_driver_table_entry font_driver_table[] =
+{
+ {(char*)"vdi", ctor_font_plotter_vdi, 0},
+ {(char*)"freetype", ctor_font_plotter_freetype, 0},
+ {(char*)NULL, NULL, 0}
+};
+
+struct s_vdi_sysinfo * read_vdi_sysinfo( short vdih, struct s_vdi_sysinfo * info ) {
+
+ unsigned long cookie_EdDI=0;
+ short out[300];
+ memset( info, 0, sizeof(struct s_vdi_sysinfo) );
+
+ info->vdi_handle = vdih;
+ if ( Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND ) {
+ info->EdDiVersion = 0;
+ } else {
+ info->EdDiVersion = EdDI_version( (void *)cookie_EdDI );
+ }
+
+ memset( &out, 0, sizeof(short)*300 );
+ vq_extnd( vdih, 0, (short*)&out );
+ info->scr_w = out[0]+1;
+ info->scr_h = out[1]+1;
+ if( out[39] == 2 ) {
+ info->scr_bpp = 1;
+ info->colors = out[39];
+ } else {
+ info->colors = out[39];
+ }
+
+ memset( &out, 0, sizeof(short)*300 );
+ vq_extnd( vdih, 1, (short*)&out );
+ info->scr_bpp = out[4];
+ info->maxpolycoords = out[14];
+ info->maxintin = out[15];
+ if( out[30] & 1 ) {
+ info->rasterscale = true;
+ } else {
+ info->rasterscale = false;
+ }
+
+ switch( info->scr_bpp ) {
+ case 8:
+ info->pixelsize=1;
+ break;
+ case 15:
+ case 16:
+ info->pixelsize=2;
+ break;
+ case 24:
+ info->pixelsize=3;
+ break;
+ case 32:
+ info->pixelsize=4;
+ break;
+ case 64:
+ info->pixelsize=8;
+ break;
+ default:
+ info->pixelsize=0;
+ break;
+
+ }
+ info->pitch = info->scr_w * info->pixelsize;
+ info->vdiformat = ( (info->scr_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
+ info->screensize = ( info->scr_w * info->pixelsize ) * info->scr_h;
+
+ if( info->EdDiVersion >= EDDI_10 ) {
+ memset( &out, 0, sizeof(short)*300 );
+ vq_scrninfo(vdih, (short*)&out);
+ info->vdiformat = out[0];
+ info->clut = out[1];
+ info->scr_bpp = out[2];
+ info->hicolors = *((unsigned long*) &out[3]);
+ if( info->EdDiVersion >= EDDI_11 ) {
+ info->pitch = out[5];
+ info->screen = (void *) *((unsigned long *) &out[6]);
+ }
+
+ switch( info->clut ) {
+
+ case VDI_CLUT_HARDWARE:
+ {
+
+ int i;
+ unsigned short *tmp_p;
+/* it's possible to store the vdi painters:
+ tmp_p = (unsigned short *)&work_out[16];
+
+ for (i=0;i<256;i++) {
+ vdi_index[*tmp_p++] = i;
+ }
+*/
+ }
+ break;
+
+ case VDI_CLUT_SOFTWARE:
+ {
+ int component; /* red, green, blue, alpha, overlay */
+ int num_bit;
+ unsigned short *tmp_p;
+
+ /* We can build masks with info here */
+ tmp_p = (unsigned short *) &out[16];
+ for (component=0;component<5;component++) {
+ for (num_bit=0;num_bit<16;num_bit++) {
+ unsigned short val;
+
+ val = *tmp_p++;
+
+ if (val == 0xffff) {
+ continue;
+ }
+
+ switch(component) {
+ case 0:
+ info->mask_r |= 1<< val;
+ break;
+ case 1:
+ info->mask_g |= 1<< val;
+ break;
+ case 2:
+ info->mask_b |= 1<< val;
+ break;
+ case 3:
+ info->mask_a |= 1<< val;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Remove lower green bits for Intel endian screen */
+ if ((info->mask_g == ((7<<13)|3)) || (info->mask_g == ((7<<13)|7))) {
+ info->mask_g &= ~(7<<13);
+ }
+ break;
+
+ case VDI_CLUT_NONE:
+ break;
+ }
+ }
+}
+
+
+/*
+ lookup an plotter ID by name
+*/
+static int drvrname_idx( char * name )
+{
+ int i;
+ for( i = 0; ; i++) {
+ if( screen_driver_table[i].name == NULL ) {
+ return( -1 );
+ }
+ else {
+ if( strcmp(name, screen_driver_table[i].name) == 0 ) {
+ return( i );
+ }
+ }
+ }
+}
+
+/*
+ lookup of font plotter ID by name
+*/
+static int font_drvrname_idx( char * name )
+{
+ int i;
+ for( i = 0; ; i++) {
+ if( font_driver_table[i].name == NULL ) {
+ return( -1 );
+ }
+ else {
+ if( strcmp(name, font_driver_table[i].name) == 0 ) {
+ return( i );
+ }
+ }
+ }
+}
+
+/*
+ Get an plotter info entry, the entry contains an pointer to ctor
+*/
+struct s_driver_table_entry * get_screen_driver_entry( char * name )
+{
+ int idx = drvrname_idx( name );
+ if( idx < 0 )
+ return( 0 );
+ else
+ return( &screen_driver_table[idx] );
+}
+
+/*
+ Get an font plotter info entry, the entry contains an pointer to ctor.
+*/
+struct s_font_driver_table_entry * get_font_driver_entry( char * name )
+{
+ int idx = font_drvrname_idx( name );
+ if( idx < 0 )
+ return( 0 );
+ else
+ return( (struct s_font_driver_table_entry *)&font_driver_table[idx] );
+}
+
+
+/*
+ Create an new text plotter object
+*/
+FONT_PLOTTER new_font_plotter( int vdihandle, char * name, unsigned long flags, int * error)
+{
+ int i=0;
+ int res = 0-ERR_PLOTTER_NOT_AVAILABLE;
+ FONT_PLOTTER fplotter = (FONT_PLOTTER)malloc( sizeof(struct s_font_plotter) );
+ if( fplotter == NULL ) {
+ *error = 0-ERR_NO_MEM;
+ return( NULL );
+ }
+ fplotter->vdi_handle = vdihandle;
+ fplotter->name = name;
+ fplotter->flags |= flags;
+ for( i = 0; ; i++) {
+ if( font_driver_table[i].name == NULL ) {
+ res = 0-ERR_PLOTTER_NOT_AVAILABLE;
+ break;
+ } else {
+ if( strcmp(name, font_driver_table[i].name) == 0 ) {
+ if( font_driver_table[i].ctor ) {
+ res = font_driver_table[i].ctor( fplotter );
+ *error = 0;
+ } else {
+ res = 0-ERR_PLOTTER_NOT_AVAILABLE;
+ *error = res;
+ return (NULL);
+ }
+ break;
+ }
+ }
+ }
+ if( res < 0 ) {
+ free( fplotter );
+ *error = res;
+ return( NULL );
+ }
+ fplotter->plotter = NULL;
+ return( fplotter );
+}
+
+static bool init=false;
+static int inst=0;
+
+/*
+ Create an new plotter object
+*/
+GEM_PLOTTER new_plotter(int vdihandle, char * name, GRECT * loc_size,
+ int virt_bpp, unsigned long flags, FONT_PLOTTER fplotter, int * error )
+{
+ int res = 0-ERR_PLOTTER_NOT_AVAILABLE;
+ int i;
+ assert( fplotter != NULL );
+
+ GEM_PLOTTER gemplotter = (GEM_PLOTTER)malloc( sizeof(struct s_gem_plotter) );
+ if( !gemplotter ) {
+ *error = 0-ERR_NO_MEM;
+ return( NULL );
+ }
+ memset( gemplotter, 0, sizeof(struct s_gem_plotter));
+
+ gemplotter->name = name;
+ gemplotter->vdi_handle = vdihandle;
+ gemplotter->flags |= flags;
+ gemplotter->font_plotter = fplotter;
+ gemplotter->bpp_virt = virt_bpp;
+ gemplotter->cfbi = 0;
+ memset(&gemplotter->fbuf, 0, sizeof(struct s_frame_buf) * MAX_FRAMEBUFS );
+ gemplotter->fbuf[0].x = loc_size->g_x;
+ gemplotter->fbuf[0].y = loc_size->g_y;
+ gemplotter->fbuf[0].w = loc_size->g_w;
+ gemplotter->fbuf[0].h = loc_size->g_h;
+
+ /* request vdi info once, so every plotter is able to access the info */
+ if( !init ) {
+ /* vdi_sysinfo */
+ read_vdi_sysinfo( vdihandle, &vdi_sysinfo );
+ init = true;
+ }
+ for( i = 0; ; i++) {
+ if( screen_driver_table[i].name == NULL ) {
+ res = 0-ERR_PLOTTER_NOT_AVAILABLE;
+ break;
+ }
+ else {
+ if( strcmp(name, screen_driver_table[i].name) == 0 ) {
+ if( screen_driver_table[i].ctor ) {
+ gemplotter->flags |= screen_driver_table[i].flags;
+ res = screen_driver_table[i].ctor( gemplotter );
+ *error = 0;
+ } else {
+ res = 0-ERR_PLOTTER_NOT_AVAILABLE;
+ *error = res;
+ return (NULL);
+ }
+ break;
+ }
+ }
+ }
+ if( res < 0 ) {
+ free( gemplotter );
+ *error = res;
+ return( NULL );
+ }
+ inst++;
+ gemplotter->font_plotter->plotter = gemplotter;
+ return( gemplotter );
+}
+
+/*
+ Free an plotter
+*/
+int delete_plotter( GEM_PLOTTER p )
+{
+ if( p ) {
+ p->dtor( p );
+ free( p );
+ p = NULL;
+ inst--;
+ if( inst == 0 ){
+
+ }
+ }
+ else
+ return( -1 );
+ return( 0 );
+}
+
+/*
+ Free an font plotter
+*/
+int delete_font_plotter( FONT_PLOTTER p )
+{
+ if( p ) {
+ p->dtor(p);
+ free( p );
+ p = NULL;
+ }
+ else
+ return( -1 );
+ return( 0 );
+}
+
+/*
+ x - x coord
+ y - y coord
+ stride - stride in bytes
+ bpp - bits per pixel
+*/
+int calc_chunked_buffer_size(int x, int y, int stride, int bpp)
+{
+ return( (x * (bpp >> 3)) * y );
+}
+
+/*
+ x - x coord
+ y - y coord
+ stride - stride in bytes
+ bpp - bits per pixel
+*/
+int get_pixel_offset( int x, int y, int stride, int bpp )
+{
+ LOG(("byte_pp: %d, pure: %d, result: %d\n",(bpp >> 3),(y * stride + x), (y * stride + x) * (bpp >> 3)));
+ return( ( (y * stride) + x) * (bpp >> 3) );
+}
+
+/*
+ 1. calculate visible area of framebuffer in coords relative to framebuffer position
+
+ result:
+ this function should calc offsets into x,y coords of the framebuffer which
+ can be drawn. If the framebuffer coords do not fall within the screen region,
+ all values of visible region are set to zero.
+*/
+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 = CURFB(p).x;
+ common.g_y = frame.g_y = CURFB(p).y;
+ common.g_w = frame.g_w = CURFB(p).w;
+ common.g_h = frame.g_h = CURFB(p).h;
+
+ if( rc_intersect( &screen, &common ) ) {
+ CURFB(p).vis_w = common.g_w;
+ CURFB(p).vis_h = common.g_h;
+ if( CURFB(p).x < screen.g_x )
+ CURFB(p).vis_x = frame.g_w - common.g_w;
+ else
+ CURFB(p).vis_x = 0;
+ if( CURFB(p).y <screen.g_y )
+ CURFB(p).vis_y = frame.g_h - common.g_h;
+ else
+ CURFB(p).vis_y = 0;
+ } else {
+ CURFB(p).vis_w = CURFB(p).vis_h = 0;
+ CURFB(p).vis_x = CURFB(p).vis_y = 0;
+ }
+}
+
+/*
+ Returns the visible parts of the box (relative coords within framebuffer),
+ relative to screen coords (normally starting at 0,0 )
+*/
+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 = CURFB(self).x;
+ vis.g_y = CURFB(self).y;
+ vis.g_w = CURFB(self).w;
+ vis.g_h = CURFB(self).h;
+
+ if ( !rc_intersect( &screen, &vis ) ) {
+ return( false );
+ }
+ vis.g_x = CURFB(self).w - vis.g_w;
+ vis.g_y = CURFB(self).h - vis.g_h;
+
+ /* clip box to visible region: */
+ if( !rc_intersect(&vis, &box) ) {
+ return( false );
+ }
+ out.g_x = box.g_x + CURFB(self).x;
+ out.g_y = box.g_y + CURFB(self).y;
+ out.g_w = box.g_w;
+ out.g_h = box.g_h;
+ *ret = out;
+ return ( true );
+}
+
+const char* plotter_err_str(int i) { return(plot_error_codes[abs(i)]); }
+
+void dump_vdi_info( short vdih )
+{
+ struct s_vdi_sysinfo temp;
+ read_vdi_sysinfo( vdih, &temp );
+ printf("struct s_vdi_sysinfo {\n");
+ printf(" short vdi_handle: %d\n", temp.vdi_handle);
+ printf(" short scr_w: %d \n", temp.scr_w);
+ printf(" short scr_h: %d\n", temp.scr_h);
+ printf(" short scr_bpp: %d\n", temp.scr_bpp);
+ printf(" int colors: %d\n", temp.colors);
+ printf(" ulong hicolors: %d\n", temp.hicolors);
+ printf(" short pixelsize: %d\n", temp.pixelsize);
+ printf(" unsigned short pitch: %d\n", temp.pitch);
+ printf(" unsigned short vdiformat: %d\n", temp.vdiformat);
+ printf(" unsigned short clut: %d\n", temp.clut);
+ printf(" void * screen: 0x0%p\n", temp.screen);
+ printf(" unsigned long screensize: %d\n", temp.screensize);
+ printf(" unsigned long mask_r: 0x0%08x\n", temp.mask_r);
+ printf(" unsigned long mask_g: 0x0%08x\n", temp.mask_g);
+ printf(" unsigned long mask_b: 0x0%08x\n", temp.mask_b);
+ printf(" unsigned long mask_a: 0x0%08x\n", temp.mask_a);
+ printf(" short maxintin: %d\n", temp.maxintin);
+ printf(" short maxpolycoords: %d\n", temp.maxpolycoords);
+ printf(" unsigned long EdDiVersion: 0x0%03x\n", temp.EdDiVersion);
+ printf(" unsigned short rasterscale: 0x%2x\n", temp.rasterscale);
+ printf("};\n");
+}
+
+void dump_plot_drivers(void)
+{
+ int i = 0;
+ while( screen_driver_table[i].name != NULL ) {
+ printf("%s -> max_bpp: %d, flags: %d\n",
+ screen_driver_table[i].name,
+ screen_driver_table[i].max_bpp,
+ screen_driver_table[i].flags
+ );
+ i++;
+ }
+}
+
+void dump_font_drivers(void)
+{
+ int i = 0;
+ while( font_driver_table[i].name != NULL ) {
+ printf("%s -> flags: %d\n",
+ font_driver_table[i].name,
+ font_driver_table[i].flags
+ );
+ i++;
+ }
+}
+
+/*
+ Convert an RGB color to an VDI Color
+*/
+void rgb_to_vdi1000( unsigned char * in, unsigned short * out )
+{
+
+ double r = ((double)in[0]/255); /* prozentsatz red */
+ double g = ((double)in[1]/255); /* prozentsatz green */
+ double b = ((double)in[2]/255); /* prozentsatz blue */
+ out[0] = 1000 * r + 0.5;
+ out[1] = 1000 * g + 0.5;
+ out[2] = 1000 * b + 0.5;
+ return;
+}
+
+
+
+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
+*/
+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];
+ /* convert each 8bit color to 6bit web color: */
+ for( i=0; i<3; i++) {
+ if(0 == rgb[i] % web_std_colors[1] ) {
+ tval[i] = rgb[i] / web_std_colors[1];
+ }
+ else {
+ int pos = ((short)rgb[i] / web_std_colors[1]);
+ if( abs(rgb[i] - web_std_colors[pos]) > abs(rgb[i] - web_std_colors[pos+1]) )
+ tval[i] = pos+1;
+ else
+ tval[i] = pos;
+ }
+ }
+ return( tval[2]*36+tval[1]*6+tval[0] );
+}
+
+/* Shared (static in object oriented slang) plotter functions: */
+int plotter_get_clip( GEM_PLOTTER self, struct s_clipping * out )
+{
+ out->x0 = self->clipping.x0;
+ out->y0 = self->clipping.y0;
+ out->x1 = self->clipping.x1;
+ out->y1 = self->clipping.y1;
+ return( 1 );
+}
+
+int plotter_std_clip(GEM_PLOTTER self,int x0, int y0, int x1, int y1)
+{
+ self->clipping.x0 = x0;
+ self->clipping.y0 = y0;
+ self->clipping.x1 = x1;
+ self->clipping.y1 = y1;
+ return ( 1 );
+}
+
+/* this converts framebuffer clipping to vdi clipping and sets it */
+void plotter_vdi_clip( GEM_PLOTTER self, bool set)
+{
+ return;
+ if( set == true ) {
+ struct s_clipping * c = &self->clipping;
+ short vdiflags[58];
+ short newclip[4];
+ 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] = CURFB(self).x + MAX(c->x0, 0);
+ newclip[1] = CURFB(self).y + MAX(c->y0, 0);
+ newclip[2] = CURFB(self).x + MIN(CURFB(self).vis_w, c->x1 - c->x0)-1;
+ newclip[3] = CURFB(self).y + MIN(CURFB(self).vis_h, c->y1 - c->y0)-1;
+ vs_clip( self->vdi_handle, 1, (short*)&newclip );
+ } else {
+ short set = 1;
+ vs_clip( self->vdi_handle, set, (short *)&prev_vdi_clip );
+ }
+}
+