NetSurf
plot.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Ole Loots <ole@monochrom.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <assert.h>
20#include <sys/types.h>
21#include <stdint.h>
22#include <string.h>
23#include <limits.h>
24#include <math.h>
25#include <stdbool.h>
26#include <mt_gem.h>
27#include <mint/osbind.h>
28
29#include "utils/log.h"
30#include "utils/utf8.h"
31#include "utils/utils.h"
32#include "netsurf/bitmap.h"
33#include "netsurf/plotters.h"
34#include "netsurf/mouse.h"
35
36#include "atari/gui.h"
37#include "atari/osspec.h"
38#include "atari/misc.h"
39#include "atari/bitmap.h"
40#include "utils/nsoption.h"
41#include "atari/plot/eddi.h"
42#include "atari/plot/fontplot.h"
43#include "atari/plot/plot.h"
44
45void vq_scrninfo(VdiHdl handle, short *work_out);
46
47struct s_view {
48 short x; /**< drawing (screen) offset x */
49 short y; /**< drawing (screen) offset y */
50 short w; /**< width of buffer, not in sync with vis_w */
51 short h; /**< height of buffer, not in sync with vis_w */
52 short vis_x; /**< visible rectangle of the screen buffer */
53 short vis_y; /**< coords are relative to plot location */
54 short vis_w; /**< clipped to screen dimensions */
55 short vis_h; /**< visible width */
56 struct rect abs_clipping; /**< The toplevel clipping rectangle */
57 struct rect clipping; /**< actual clipping rectangle */
58 float scale;
59};
60
61/**
62 * Garbage collection of the snapshot routine
63 *
64 * this should be called after you are done with the data returned by
65 * snapshot_create don't access the screenshot after you called this
66 * function
67 */
68static void snapshot_suspend(void);
69
70/**
71 * destroy memory used by screenshot
72 */
73static void snapshot_destroy(void);
74
75#ifdef WITH_8BPP_SUPPORT
76static unsigned short sys_pal[256][3]; /*RGB*/
77static unsigned short pal[256][3]; /*RGB*/
78static char rgb_lookup[256][4];
79short web_std_colors[6] = {0, 51, 102, 153, 204, 255};
80
81unsigned short vdi_web_pal[216][3] = {
82 {0x000,0x000,0x000}, {0x0c8,0x000,0x000}, {0x190,0x000,0x000},
83 {0x258,0x000,0x000}, {0x320,0x000,0x000}, {0x3e8,0x000,0x000},
84 {0x000,0x0c8,0x000}, {0x0c8,0x0c8,0x000}, {0x190,0x0c8,0x000},
85 {0x258,0x0c8,0x000}, {0x320,0x0c8,0x000}, {0x3e8,0x0c8,0x000},
86 {0x000,0x190,0x000}, {0x0c8,0x190,0x000}, {0x190,0x190,0x000},
87 {0x258,0x190,0x000}, {0x320,0x190,0x000}, {0x3e8,0x190,0x000},
88 {0x000,0x258,0x000}, {0x0c8,0x258,0x000}, {0x190,0x258,0x000},
89 {0x258,0x258,0x000}, {0x320,0x258,0x000}, {0x3e8,0x258,0x000},
90 {0x000,0x320,0x000}, {0x0c8,0x320,0x000}, {0x190,0x320,0x000},
91 {0x258,0x320,0x000}, {0x320,0x320,0x000}, {0x3e8,0x320,0x000},
92 {0x000,0x3e8,0x000}, {0x0c8,0x3e8,0x000}, {0x190,0x3e8,0x000},
93 {0x258,0x3e8,0x000}, {0x320,0x3e8,0x000}, {0x3e8,0x3e8,0x000},
94 {0x000,0x000,0x0c8}, {0x0c8,0x000,0x0c8}, {0x190,0x000,0x0c8},
95 {0x258,0x000,0x0c8}, {0x320,0x000,0x0c8}, {0x3e8,0x000,0x0c8},
96 {0x000,0x0c8,0x0c8}, {0x0c8,0x0c8,0x0c8}, {0x190,0x0c8,0x0c8},
97 {0x258,0x0c8,0x0c8}, {0x320,0x0c8,0x0c8}, {0x3e8,0x0c8,0x0c8},
98 {0x000,0x190,0x0c8}, {0x0c8,0x190,0x0c8}, {0x190,0x190,0x0c8},
99 {0x258,0x190,0x0c8}, {0x320,0x190,0x0c8}, {0x3e8,0x190,0x0c8},
100 {0x000,0x258,0x0c8}, {0x0c8,0x258,0x0c8}, {0x190,0x258,0x0c8},
101 {0x258,0x258,0x0c8}, {0x320,0x258,0x0c8}, {0x3e8,0x258,0x0c8},
102 {0x000,0x320,0x0c8}, {0x0c8,0x320,0x0c8}, {0x190,0x320,0x0c8},
103 {0x258,0x320,0x0c8}, {0x320,0x320,0x0c8}, {0x3e8,0x320,0x0c8},
104 {0x000,0x3e8,0x0c8}, {0x0c8,0x3e8,0x0c8}, {0x190,0x3e8,0x0c8},
105 {0x258,0x3e8,0x0c8}, {0x320,0x3e8,0x0c8}, {0x3e8,0x3e8,0x0c8},
106 {0x000,0x000,0x190}, {0x0c8,0x000,0x190}, {0x190,0x000,0x190},
107 {0x258,0x000,0x190}, {0x320,0x000,0x190}, {0x3e8,0x000,0x190},
108 {0x000,0x0c8,0x190}, {0x0c8,0x0c8,0x190}, {0x190,0x0c8,0x190},
109 {0x258,0x0c8,0x190}, {0x320,0x0c8,0x190}, {0x3e8,0x0c8,0x190},
110 {0x000,0x190,0x190}, {0x0c8,0x190,0x190}, {0x190,0x190,0x190},
111 {0x258,0x190,0x190}, {0x320,0x190,0x190}, {0x3e8,0x190,0x190},
112 {0x000,0x258,0x190}, {0x0c8,0x258,0x190}, {0x190,0x258,0x190},
113 {0x258,0x258,0x190}, {0x320,0x258,0x190}, {0x3e8,0x258,0x190},
114 {0x000,0x320,0x190}, {0x0c8,0x320,0x190}, {0x190,0x320,0x190},
115 {0x258,0x320,0x190}, {0x320,0x320,0x190}, {0x3e8,0x320,0x190},
116 {0x000,0x3e8,0x190}, {0x0c8,0x3e8,0x190}, {0x190,0x3e8,0x190},
117 {0x258,0x3e8,0x190}, {0x320,0x3e8,0x190}, {0x3e8,0x3e8,0x190},
118 {0x000,0x000,0x258}, {0x0c8,0x000,0x258}, {0x190,0x000,0x258},
119 {0x258,0x000,0x258}, {0x320,0x000,0x258}, {0x3e8,0x000,0x258},
120 {0x000,0x0c8,0x258}, {0x0c8,0x0c8,0x258}, {0x190,0x0c8,0x258},
121 {0x258,0x0c8,0x258}, {0x320,0x0c8,0x258}, {0x3e8,0x0c8,0x258},
122 {0x000,0x190,0x258}, {0x0c8,0x190,0x258}, {0x190,0x190,0x258},
123 {0x258,0x190,0x258}, {0x320,0x190,0x258}, {0x3e8,0x190,0x258},
124 {0x000,0x258,0x258}, {0x0c8,0x258,0x258}, {0x190,0x258,0x258},
125 {0x258,0x258,0x258}, {0x320,0x258,0x258}, {0x3e8,0x258,0x258},
126 {0x000,0x320,0x258}, {0x0c8,0x320,0x258}, {0x190,0x320,0x258},
127 {0x258,0x320,0x258}, {0x320,0x320,0x258}, {0x3e8,0x320,0x258},
128 {0x000,0x3e8,0x258}, {0x0c8,0x3e8,0x258}, {0x190,0x3e8,0x258},
129 {0x258,0x3e8,0x258}, {0x320,0x3e8,0x258}, {0x3e8,0x3e8,0x258},
130 {0x000,0x000,0x320}, {0x0c8,0x000,0x320}, {0x190,0x000,0x320},
131 {0x258,0x000,0x320}, {0x320,0x000,0x320}, {0x3e8,0x000,0x320},
132 {0x000,0x0c8,0x320}, {0x0c8,0x0c8,0x320}, {0x190,0x0c8,0x320},
133 {0x258,0x0c8,0x320}, {0x320,0x0c8,0x320}, {0x3e8,0x0c8,0x320},
134 {0x000,0x190,0x320}, {0x0c8,0x190,0x320}, {0x190,0x190,0x320},
135 {0x258,0x190,0x320}, {0x320,0x190,0x320}, {0x3e8,0x190,0x320},
136 {0x000,0x258,0x320}, {0x0c8,0x258,0x320}, {0x190,0x258,0x320},
137 {0x258,0x258,0x320}, {0x320,0x258,0x320}, {0x3e8,0x258,0x320},
138 {0x000,0x320,0x320}, {0x0c8,0x320,0x320}, {0x190,0x320,0x320},
139 {0x258,0x320,0x320}, {0x320,0x320,0x320}, {0x3e8,0x320,0x320},
140 {0x000,0x3e8,0x320}, {0x0c8,0x3e8,0x320}, {0x190,0x3e8,0x320},
141 {0x258,0x3e8,0x320}, {0x320,0x3e8,0x320}, {0x3e8,0x3e8,0x320},
142 {0x000,0x000,0x3e8}, {0x0c8,0x000,0x3e8}, {0x190,0x000,0x3e8},
143 {0x258,0x000,0x3e8}, {0x320,0x000,0x3e8}, {0x3e8,0x000,0x3e8},
144 {0x000,0x0c8,0x3e8}, {0x0c8,0x0c8,0x3e8}, {0x190,0x0c8,0x3e8},
145 {0x258,0x0c8,0x3e8}, {0x320,0x0c8,0x3e8}, {0x3e8,0x0c8,0x3e8},
146 {0x000,0x190,0x3e8}, {0x0c8,0x190,0x3e8}, {0x190,0x190,0x3e8},
147 {0x258,0x190,0x3e8}, {0x320,0x190,0x3e8}, {0x3e8,0x190,0x3e8},
148 {0x000,0x258,0x3e8}, {0x0c8,0x258,0x3e8}, {0x190,0x258,0x3e8},
149 {0x258,0x258,0x3e8}, {0x320,0x258,0x3e8}, {0x3e8,0x258,0x3e8},
150 {0x000,0x320,0x3e8}, {0x0c8,0x320,0x3e8}, {0x190,0x320,0x3e8},
151 {0x258,0x320,0x3e8}, {0x320,0x320,0x3e8}, {0x3e8,0x320,0x3e8},
152 {0x000,0x3e8,0x3e8}, {0x0c8,0x3e8,0x3e8}, {0x190,0x3e8,0x3e8},
153 {0x258,0x3e8,0x3e8}, {0x320,0x3e8,0x3e8}, {0x3e8,0x3e8,0x3e8}
154};
155#endif
156
157/* Error code translations: */
158static const char * plot_error_codes[] = {
159 "None",
160 "ERR_BUFFERSIZE_EXCEEDS_SCREEN",
161 "ERR_NO_MEM",
162 "ERR_PLOTTER_NOT_AVAILABLE"
163};
164
166
167extern short vdih;
168
169/* temp buffer for bitmap conversion: */
170static void * buf_packed;
172
173/* temp buffer for bitmap conversion: */
176
177/* buffer for plot operations that require device format, */
178/* currently used for transparent mfdb blits and snapshots: */
179static MFDB buf_scr;
180static int size_buf_scr;
181
182/* buffer for std form, used during 8bpp snapshot */
185
187
188/* intermediate bitmap format */
189static HermesFormat vfmt;
190
191/* no screen format here, hermes may not suitable for it */
192
193/* netsurf source bitmap format */
194static HermesFormat nsfmt;
195
197/* bit depth of framebuffers: */
199static struct s_view view;
200
201//static HermesHandle hermes_pal_h; /* hermes palette handle */
202static HermesHandle hermes_cnv_h; /* hermes converter instance handle */
203static HermesHandle hermes_res_h;
204
205//static short prev_vdi_clip[4];
206static struct bitmap snapshot;
207
209unsigned long atari_plot_flags;
210unsigned long atari_font_flags;
211
212typedef bool (*bitmap_convert_fnc)(struct bitmap * img, int x, int y, GRECT * clip, uint32_t bg, uint32_t flags, MFDB *out );
214
215/* exported interface documented in atari/plot.h */
216const char* plot_err_str(int i)
217{
218 return (plot_error_codes[abs(i)]);
219}
220
221
222/**
223 * Set line drawing color by passing netsurf XBGR "colour" type.
224 *
225 * \param vdih The vdi handle
226 * \param cin The netsurf colour value
227 */
228inline static void vsl_rgbcolor(short vdih, colour cin)
229{
230#ifdef WITH_8BPP_SUPPORT
231 if( vdi_sysinfo.scr_bpp > 8 ) {
232#endif
233 RGB1000 c; /* a struct with three (RGB) shorts */
234 rgb_to_vdi1000( (unsigned char*)&cin, &c);
235 vs_color(vdih, OFFSET_CUSTOM_COLOR, (short *)&c);
236 vsl_color(vdih, OFFSET_CUSTOM_COLOR);
237#ifdef WITH_8BPP_SUPPORT
238 } else {
239 if( vdi_sysinfo.scr_bpp >= 4 ){
240 vsl_color(vdih, RGB_TO_VDI(cin));
241 }
242 else
243 vsl_color(vdih, BLACK);
244 }
245#endif
246}
247
248
249/**
250 * Set fill color by passing netsurf XBGR "colour" type.
251 *
252 * \param vdih The vdi handle
253 * \param cin The netsurf colour value
254 */
255inline static void vsf_rgbcolor(short vdih, colour cin)
256{
257#ifdef WITH_8BPP_SUPPORT
258 if( vdi_sysinfo.scr_bpp > 8 ) {
259#endif
260 RGB1000 c; /* a struct with three (RGB) shorts */
261 rgb_to_vdi1000( (unsigned char*)&cin, &c);
262 vs_color( vdih, OFFSET_CUSTOM_COLOR, (short *)&c);
263 vsf_color( vdih, OFFSET_CUSTOM_COLOR );
264#ifdef WITH_8BPP_SUPPORT
265 } else {
266 if( vdi_sysinfo.scr_bpp >= 4 ){
267 vsf_color( vdih, RGB_TO_VDI(cin) );
268 }
269 else
270 vsf_color( vdih, WHITE );
271 }
272#endif
273}
274
275
276/**
277 * Get current visible coords
278 */
279inline static void plot_get_visible_grect(GRECT * out)
280{
281 out->g_x = view.vis_x;
282 out->g_y = view.vis_y;
283 out->g_w = view.vis_w;
284 out->g_h = view.vis_h;
285}
286
287
288/* calculate visible area of framebuffer in coords relative to framebuffer */
289/* position */
290/* result: */
291/* this function should calculates an rectangle relative to the plot origin*/
292/* and size. */
293/* If the ploter coords do not fall within the screen region, */
294/* all values of the region are set to zero. */
295inline static void update_visible_rect(void)
296{
297 GRECT screen; // dimensions of the screen
298 GRECT frame; // dimensions of the drawing area
299 GRECT common; // dimensions of intersection of both
300
301 screen.g_x = 0;
302 screen.g_y = 0;
303 screen.g_w = vdi_sysinfo.scr_w;
304 screen.g_h = vdi_sysinfo.scr_h;
305
306 common.g_x = frame.g_x = view.x;
307 common.g_y = frame.g_y = view.y;
308 common.g_w = frame.g_w = view.w;
309 common.g_h = frame.g_h = view.h;
310
311 if (rc_intersect(&screen, &common)) {
312 view.vis_w = common.g_w;
313 view.vis_h = common.g_h;
314 if (view.x < screen.g_x)
315 view.vis_x = frame.g_w - common.g_w;
316 else
317 view.vis_x = 0;
318 if (view.y <screen.g_y)
319 view.vis_y = frame.g_h - common.g_h;
320 else
321 view.vis_y = 0;
322 } else {
323 view.vis_w = view.vis_h = 0;
324 view.vis_x = view.vis_y = 0;
325 }
326}
327
328
329/**
330 * Returns the visible parts of the box
331 *
332 * The returned values are relative coords within framebuffer,
333 * relative to screen coords (normally starting at 0,0 )
334 */
335inline static bool fbrect_to_screen(GRECT box, GRECT * ret)
336{
337 GRECT out, vis, screen;
338
339 screen.g_x = 0;
340 screen.g_y = 0;
341 screen.g_w = vdi_sysinfo.scr_w;
342 screen.g_h = vdi_sysinfo.scr_h;
343
344 /* get visible region: */
345 vis.g_x = view.x;
346 vis.g_y = view.y;
347 vis.g_w = view.w;
348 vis.g_h = view.h;
349
350 if ( !rc_intersect( &screen, &vis ) ) {
351 return( false );
352 }
353 vis.g_x = view.w - vis.g_w;
354 vis.g_y = view.h - vis.g_h;
355
356 /* clip box to visible region: */
357 if( !rc_intersect(&vis, &box) ) {
358 return( false );
359 }
360 out.g_x = box.g_x + view.x;
361 out.g_y = box.g_y + view.y;
362 out.g_w = box.g_w;
363 out.g_h = box.g_h;
364 *ret = out;
365 return ( true );
366}
367
368
369/**
370 * copy an rectangle from the plot buffer to screen
371 *
372 * because this is an on-screen plotter, this is an screen to screen copy.
373 */
374bool plot_copy_rect(GRECT src, GRECT dst)
375{
376 MFDB devmf;
377 MFDB scrmf;
378 short pxy[8];
379 GRECT vis;
380
381 /* clip to visible rect, only needed for onscreen renderer: */
383
384 if( !rc_intersect(&vis, &src) )
385 return(true);
386 if( !rc_intersect(&vis, &dst) )
387 return(true);
388
389 src.g_x = view.x + src.g_x;
390 src.g_y = view.y + src.g_y;
391 dst.g_x = view.x + dst.g_x;
392 dst.g_y = view.y + dst.g_y;
393
394 devmf.fd_addr = NULL;
395 devmf.fd_w = src.g_w;
396 devmf.fd_h = src.g_h;
397 devmf.fd_wdwidth = 0;
398 devmf.fd_stand = 0;
399 devmf.fd_nplanes = 0;
400 devmf.fd_r1 = devmf.fd_r2 = devmf.fd_r3 = 0;
401
402 scrmf.fd_addr = NULL;
403 scrmf.fd_w = dst.g_w;
404 scrmf.fd_h = dst.g_h;
405 scrmf.fd_wdwidth = 0 ;
406 scrmf.fd_stand = 0;
407 scrmf.fd_nplanes = 0;
408 scrmf.fd_r1 = scrmf.fd_r2 = scrmf.fd_r3 = 0;
409
410 pxy[0] = src.g_x;
411 pxy[1] = src.g_y;
412 pxy[2] = pxy[0] + src.g_w-1;
413 pxy[3] = pxy[1] + src.g_h-1;
414 pxy[4] = dst.g_x;
415 pxy[5] = dst.g_y;
416 pxy[6] = pxy[4] + dst.g_w-1;
417 pxy[7] = pxy[5] + dst.g_h-1;
418 plot_lock();
419 vro_cpyfm( atari_plot_vdi_handle, S_ONLY, (short*)&pxy, &devmf, &scrmf);
420 plot_unlock();
421
422 return(true);
423}
424
425
426/**
427 * Fill the screen info structure.
428 *
429 * \param vdih The handle
430 * \param[out] info The infor structure to fill.
431 */
432static void read_vdi_sysinfo(short vdih, struct s_vdi_sysinfo * info)
433{
434 /** \todo this long is being cast to a pointer */
435 unsigned long cookie_EdDI=0;
436 short out[300];
437 memset( info, 0, sizeof(struct s_vdi_sysinfo) );
438
439 info->vdi_handle = vdih;
440 if ( tos_getcookie(C_EdDI, (long *)&cookie_EdDI) == C_NOTFOUND ) {
441 info->EdDiVersion = 0;
442 } else {
443 info->EdDiVersion = EdDI_version( (void *)cookie_EdDI );
444 }
445
446 memset( &out, 0, sizeof(short)*300 );
447 vq_extnd( vdih, 0, (short*)&out );
448 info->scr_w = out[0]+1;
449 info->scr_h = out[1]+1;
450 if( out[39] == 2 ) {
451 info->scr_bpp = 1;
452 info->colors = out[39];
453 } else {
454 info->colors = out[39];
455 }
456
457 memset( &out, 0, sizeof(short)*300 );
458 vq_extnd( vdih, 1, (short*)&out );
459 info->scr_bpp = out[4];
460 info->maxpolycoords = out[14];
461 info->maxintin = out[15];
462 if( out[30] & 1 ) {
463 info->rasterscale = true;
464 } else {
465 info->rasterscale = false;
466 }
467
468 switch( info->scr_bpp ) {
469 case 8:
470 info->pixelsize=1;
471 break;
472 case 15:
473 case 16:
474 info->pixelsize=2;
475 break;
476 case 24:
477 info->pixelsize=3;
478 break;
479 case 32:
480 info->pixelsize=4;
481 break;
482 case 64:
483 info->pixelsize=8;
484 break;
485 default:
486 info->pixelsize=1;
487 break;
488
489 }
490 info->pitch = info->scr_w * info->pixelsize;
491 info->vdiformat = ( (info->scr_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
492 info->screensize = ( info->scr_w * info->pixelsize ) * info->scr_h;
493
494 if( info->EdDiVersion >= EDDI_10 ) {
495 memset( &out, 0, sizeof(short)*300 );
496 vq_scrninfo(vdih, (short*)&out);
497 info->vdiformat = out[0];
498 info->clut = out[1];
499 info->scr_bpp = out[2];
500 info->hicolors = *((unsigned long*) &out[3]);
501 if( info->EdDiVersion >= EDDI_11 ) {
502 info->pitch = out[5];
503 info->screen = (void *) *((unsigned long *) &out[6]);
504 }
505
506 switch( info->clut ) {
507
509 break;
510
512 {
513 int component; /* red, green, blue, alpha, overlay */
514 int num_bit;
515 unsigned short *tmp_p;
516
517 /* We can build masks with info here */
518 tmp_p = (unsigned short *) &out[16];
519 for (component=0; component<5; component++) {
520 for (num_bit=0; num_bit<16; num_bit++) {
521 unsigned short val;
522
523 val = *tmp_p++;
524
525 if (val == 0xffff) {
526 continue;
527 }
528
529 switch(component) {
530 case 0:
531 info->mask_r |= 1<< val;
532 break;
533 case 1:
534 info->mask_g |= 1<< val;
535 break;
536 case 2:
537 info->mask_b |= 1<< val;
538 break;
539 case 3:
540 info->mask_a |= 1<< val;
541 break;
542 }
543 }
544 }
545 }
546
547 /* Remove lower green bits for Intel endian screen */
548 if ((info->mask_g == ((7<<13)|3)) ||
549 (info->mask_g == ((7<<13)|7))) {
550 info->mask_g &= ~(7<<13);
551 }
552 break;
553
554 case VDI_CLUT_NONE:
555 break;
556 }
557 }
558}
559
560
561/**
562 * Convert an RGB color to an VDI Color
563 */
564inline void rgb_to_vdi1000(unsigned char * in, RGB1000 *out)
565{
566 double r = ((double)in[3]/255); /* prozentsatz red */
567 double g = ((double)in[2]/255); /* prozentsatz green */
568 double b = ((double)in[1]/255); /* prozentsatz blue */
569 out->red = 1000 * r + 0.5;
570 out->green = 1000 * g + 0.5;
571 out->blue = 1000 * b + 0.5;
572 return;
573}
574
575
576inline void vdi1000_to_rgb(unsigned short * in, unsigned char * out)
577{
578 double r = ((double)in[0]/1000); /* prozentsatz red */
579 double g = ((double)in[1]/1000); /* prozentsatz green */
580 double b = ((double)in[2]/1000); /* prozentsatz blue */
581 out[2] = 255 * r + 0.5;
582 out[1] = 255 * g + 0.5;
583 out[0] = 255 * b + 0.5;
584 return;
585}
586
587
588#ifdef WITH_8BPP_SUPPORT
589/**
590 * Set pixel within an 8 bit VDI standard bitmap.
591 */
592inline static void
593set_stdpx( MFDB * dst, int wdplanesz, int x, int y, unsigned char val )
594{
595 short * buf;
596 short whichbit = (1<<(15-(x%16)));
597
598 buf = dst->fd_addr;
599 buf += ((dst->fd_wdwidth*(y))+(x>>4));
600
601 *buf = (val&1) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
602
603 buf += wdplanesz;
604 *buf = (val&(1<<1)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
605
606 buf += wdplanesz;
607 *buf = (val&(1<<2)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
608
609 buf += wdplanesz;
610 *buf = (val&(1<<3)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
611
612 buf += wdplanesz;
613 *buf = (val&(1<<4)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
614
615 buf += wdplanesz;
616 *buf = (val&(1<<5)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
617
618 buf += wdplanesz;
619 *buf = (val&(1<<6)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
620
621 buf += wdplanesz;
622 *buf = (val&(1<<7)) ? ((*buf)|(whichbit)) : ((*buf)&~(whichbit));
623}
624
625
626/**
627 * Read pixel from an 8 bit VDI standard bitmap.
628 */
629inline static unsigned char get_stdpx(MFDB * dst, int wdplanesz, int x, int y)
630{
631 unsigned char ret=0;
632 short * buf;
633 short whichbit = (1<<(15-(x%16)));
634
635 buf = dst->fd_addr;
636 buf += ((dst->fd_wdwidth*(y))+(x>>4));
637
638 if( *buf & whichbit )
639 ret |= 1;
640
641 buf += wdplanesz;
642 if( *buf & whichbit )
643 ret |= 2;
644
645 buf += wdplanesz;
646 if( *buf & whichbit )
647 ret |= 4;
648
649 buf += wdplanesz;
650 if( *buf & whichbit )
651 ret |= 8;
652
653 buf += wdplanesz;
654 if( *buf & whichbit )
655 ret |= 16;
656
657 buf += wdplanesz;
658 if( *buf & whichbit )
659 ret |= 32;
660
661 buf += wdplanesz;
662 if( *buf & whichbit )
663 ret |= 64;
664
665 buf += wdplanesz;
666 if( *buf & whichbit )
667 ret |= 128;
668
669 return( ret );
670}
671
672/**
673 * Convert an RGB color into an index into the 216 colors web pallette
674 */
675inline short rgb_to_666_index(unsigned char r, unsigned char g, unsigned char b)
676{
677 short i;
678 unsigned char rgb[3] = {r,g,b};
679 unsigned char tval[3];
680
681 int diff_a, diff_b, diff_c;
682 diff_a = abs(r-g);
683 diff_b = abs(r-b);
684 diff_c = abs(r-b);
685 if( diff_a < 2 && diff_b < 2 && diff_c < 2 ) {
686 if( (r!=0XFF) && (g!=0XFF) && (b!=0XFF) ) {
687 if( ((r&0xF0)>>4) != 0 )
688 //printf("conv gray: %x -> %d\n", ((r&0xF0)>>4) , (OFFSET_CUST_PAL) + ((r&0xF0)>>4) );
689 return( (OFFSET_CUST_PAL - OFFSET_WEB_PAL) + ((r&0xF0)>>4) );
690 }
691 }
692
693 /* convert each 8bit color to 6bit web color: */
694 for( i=0; i<3; i++) {
695 if(0 == rgb[i] % web_std_colors[1] ) {
696 tval[i] = rgb[i] / web_std_colors[1];
697 } else {
698 int pos = ((short)rgb[i] / web_std_colors[1]);
699 if( abs(rgb[i] - web_std_colors[pos]) > abs(rgb[i] - web_std_colors[pos+1]) )
700 tval[i] = pos+1;
701 else
702 tval[i] = pos;
703 }
704 }
705 return(tval[2]*36+tval[1]*6+tval[0]);
706}
707#endif
708
709
710static void dump_vdi_info(short vdih)
711{
712 struct s_vdi_sysinfo temp;
713 read_vdi_sysinfo( vdih, &temp );
714 printf("struct s_vdi_sysinfo {\n");
715 printf(" short vdi_handle: %d\n", temp.vdi_handle);
716 printf(" short scr_w: %d \n", temp.scr_w);
717 printf(" short scr_h: %d\n", temp.scr_h);
718 printf(" short scr_bpp: %d\n", temp.scr_bpp);
719 printf(" int colors: %d\n", temp.colors);
720 printf(" ulong hicolors: %lu\n", temp.hicolors);
721 printf(" short pixelsize: %d\n", temp.pixelsize);
722 printf(" unsigned short pitch: %d\n", temp.pitch);
723 printf(" unsigned short vdiformat: %d\n", temp.vdiformat);
724 printf(" unsigned short clut: %d\n", temp.clut);
725 printf(" void * screen: 0x0%p\n", temp.screen);
726 printf(" unsigned long screensize: %lu\n", temp.screensize);
727 printf(" unsigned long mask_r: 0x0%08lx\n", temp.mask_r);
728 printf(" unsigned long mask_g: 0x0%08lx\n", temp.mask_g);
729 printf(" unsigned long mask_b: 0x0%08lx\n", temp.mask_b);
730 printf(" unsigned long mask_a: 0x0%08lx\n", temp.mask_a);
731 printf(" short maxintin: %d\n", temp.maxintin);
732 printf(" short maxpolycoords: %d\n", temp.maxpolycoords);
733 printf(" unsigned long EdDiVersion: 0x0%03lx\n", temp.EdDiVersion);
734 printf(" unsigned short rasterscale: 0x%2x\n", temp.rasterscale);
735 printf("};\n");
736}
737
738
739/**
740 * Create an snapshot of the screen image in device format.
741 */
742static MFDB * snapshot_create_native_mfdb(int x, int y, int w, int h)
743{
744 MFDB scr;
745 short pxy[8];
746
747 /* allocate memory for the snapshot */
748 {
749 int scr_stride = MFDB_STRIDE( w );
750 int scr_size = ( ((scr_stride >> 3) * h) * vdi_sysinfo.scr_bpp );
751 if(size_buf_scr == 0 ){
752 /* init screen mfdb */
753 buf_scr.fd_addr = malloc( scr_size );
754 size_buf_scr = scr_size;
755 } else {
756 if( scr_size >size_buf_scr ) {
757 buf_scr.fd_addr = realloc(
758 buf_scr.fd_addr, scr_size
759 );
760 size_buf_scr = scr_size;
761 }
762 }
763 if(buf_scr.fd_addr == NULL ) {
764 size_buf_scr = 0;
765 return( NULL );
766 }
767 buf_scr.fd_nplanes = vdi_sysinfo.scr_bpp;
768 buf_scr.fd_w = scr_stride;
769 buf_scr.fd_h = h;
770 buf_scr.fd_wdwidth = scr_stride >> 4;
771 assert(buf_scr.fd_addr != NULL );
772 }
773 init_mfdb( 0, w, h, 0, &scr );
774 pxy[0] = x;
775 pxy[1] = y;
776 pxy[2] = pxy[0] + w-1;
777 pxy[3] = pxy[1] + h-1;
778 pxy[4] = 0;
779 pxy[5] = 0;
780 pxy[6] = w-1;
781 pxy[7] = h-1;
782 vro_cpyfm(
783 atari_plot_vdi_handle, S_ONLY, (short*)&pxy,
784 &scr, &buf_scr
785 );
786
787 return( &buf_scr );
788}
789
790
791/**
792 * Create an snapshot of the screen in netsurf ABGR format
793 *
794 * This creates an snapshot in RGBA format (NetSurf's native format)
795 *
796 * Capture the screen at x,y location
797 *
798 * \param x absolute screen coords
799 * \param y absolute screen coords
800 * \param w width
801 * \param h height
802 */
803static struct bitmap *snapshot_create(int x, int y, int w, int h)
804{
805 int err;
806 MFDB * native;
807 // uint32_t start = clock();
808
809 // FIXME: This can be optimized a lot.
810 // 1. do not copy the snapshot to the bitmap buffer
811 // when the format of screen and bitmap equals.
812 // just point the bitmap to the native mfdb.
813 // 2. if we have eddi 1.1, we could optimize that further
814 // make snapshot_create_native_mfdb just returning a pointer
815 // to the screen.
816
817 native = snapshot_create_native_mfdb(x, y, w, h );
818
819 if(vfmt.bits == 32 )
820 goto no_copy;
821
822 /* allocate buffer for result bitmap: */
823 if(buf_scr_compat == NULL ) {
825 } else {
831 }
832
833 /* convert screen buffer to ns format: */
834 err = Hermes_ConverterRequest( hermes_cnv_h,
835 &vfmt,
836 &nsfmt
837 );
838 assert( err != 0 );
839 err = Hermes_ConverterCopy( hermes_cnv_h,
840 native->fd_addr,
841 0, /* x src coord of top left in pixel coords */
842 0, /* y src coord of top left in pixel coords */
843 w, h,
844 native->fd_w * vdi_sysinfo.pixelsize, /* stride as bytes */
846 0, /* x dst coord of top left in pixel coords */
847 0, /* y dst coord of top left in pixel coords */
848 w, h,
849 atari_bitmap_get_rowstride(buf_scr_compat) /* stride as bytes */
850 );
851 assert( err != 0 );
852 return( (struct bitmap * )buf_scr_compat );
853
854no_copy:
855
856 snapshot.width = w;
857 snapshot.height = h;
858 snapshot.pixdata = native->fd_addr;
861
862 uint32_t row, col;
863 for (row = 0; row<(uint32_t)h; row++) {
864 // fd_w matches stride!
865 uint32_t *rowptr = ((uint32_t*)native->fd_addr + ((row*native->fd_w)));
866 for (col=0; col<(uint32_t)w; col++) {
867 *(rowptr+col) = (*(rowptr+col)<<8);
868 }
869 }
870 return( &snapshot );
871}
872
873
874/**
875 * Notify the snapshot interface that the last snapshot is no longer in use.
876 */
877static void snapshot_suspend(void)
878{
880 buf_scr.fd_addr = realloc(
881 buf_scr.fd_addr, CONV_KEEP_LIMIT
882 );
883 if(buf_scr.fd_addr != NULL ) {
885 } else {
886 size_buf_scr = 0;
887 }
888 }
889
890#ifdef WITH_8BPP_SUPPORT
892 buf_std.fd_addr = realloc(
893 buf_std.fd_addr, CONV_KEEP_LIMIT
894 );
895 if(buf_std.fd_addr != NULL ) {
897 } else {
898 size_buf_std = 0;
899 }
900 }
901#endif
902
903 if(buf_scr_compat != NULL ) {
905 if( bs > CONV_KEEP_LIMIT ) {
906 int w = 0;
907 int h = 1;
909 assert( CONV_KEEP_LIMIT == w*buf_scr_compat->bpp );
913 );
914 }
915 }
916}
917
918
919/**
920 * Shut down the snapshot interface.
921 */
922static void snapshot_destroy(void)
923{
924
925 free(buf_scr.fd_addr);
926 if( buf_scr_compat != NULL) {
928 }
929
930 buf_scr.fd_addr = NULL;
931 buf_scr_compat = NULL;
932
933#ifdef WITH_8BPP_SUPPORT
934 free(buf_std.fd_addr);
935 buf_std.fd_addr = NULL;
936#endif
937}
938
939
940inline static uint32_t ablend(uint32_t pixel, uint32_t scrpixel)
941{
942 int opacity = pixel & 0xFF;
943 int transp = 0x100 - opacity;
944 uint32_t rb, g;
945 pixel >>= 8;
946 scrpixel >>= 8;
947 rb = ((pixel & 0xFF00FF) * opacity +
948 (scrpixel & 0xFF00FF) * transp) >> 8;
949 g = ((pixel & 0x00FF00) * opacity +
950 (scrpixel & 0x00FF00) * transp) >> 8;
951
952 return ((rb & 0xFF00FF) | (g & 0xFF00)) << 8;
953}
954
955
956/**
957 * Alpha blends an image, using one pixel as the background.
958 *
959 * The bitmap receives the result.
960 */
961inline static bool ablend_pixel(struct bitmap * img, uint32_t bg, GRECT * clip)
962{
963 uint32_t * imgrow;
964 int img_x, img_y, img_stride;
965
966 img_stride= atari_bitmap_get_rowstride(img);
967
968 for( img_y = 0; img_y < clip->g_h; img_y++) {
969 imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
970 for( img_x = 0; img_x < clip->g_w; img_x++ ) {
971 imgrow[img_x] = ablend( imgrow[img_x], bg );
972 }
973 }
974 return(true);
975}
976
977
978/**
979 * Aplha blends the foreground image onto thebackground images.
980 *
981 * The background receives the blended image pixels.
982 */
983inline static bool
985 struct bitmap *bg,
986 GRECT *img_clip,
987 GRECT * bg_clip )
988{
989 uint32_t * imgrow;
990 uint32_t * screenrow;
991 int img_x, img_y, bg_x, bg_y, img_stride, bg_stride;
992
993 bg_clip = bg_clip;
994 img_stride = atari_bitmap_get_rowstride(img);
995 bg_stride = atari_bitmap_get_rowstride(bg);
996
997 for( img_y = img_clip->g_y, bg_y = 0; bg_y < img_clip->g_h; bg_y++, img_y++) {
998 imgrow = (uint32_t *)(img->pixdata + (img_stride * img_y));
999 screenrow = (uint32_t *)(bg->pixdata + (bg_stride * bg_y));
1000 for( img_x = img_clip->g_x, bg_x = 0; bg_x < img_clip->g_w; bg_x++, img_x++ ) {
1001
1002 // when the pixel isn't fully transparent,...:
1003 if( (imgrow[img_x] & 0x0FF) != 0 ){
1004 screenrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
1005 }
1006
1007 // FIXME, maybe this loop would be faster??:
1008 // ---
1009 //if( (imgrow[img_x] & 0x0FF) != 0xFF ){
1010 // imgrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
1011 //}
1012
1013 // or maybe even this???
1014 // ---
1015 //if( (imgrow[img_x] & 0x0FF) == 0xFF ){
1016 // screenrow[bg_x] = imgrow[img_x];
1017 //} else if( (imgrow[img_x] & 0x0FF) != 0x00 ) {
1018 // screenrow[bg_x] = ablend( imgrow[img_x], screenrow[bg_x]);
1019 //}
1020 }
1021 }
1022 return(false);
1023}
1024
1025
1026#ifdef WITH_8BPP_SUPPORT
1027
1028/**
1029 * Create an snapshot of the screen image in VDI standard format (8 bit).
1030 */
1031static MFDB * snapshot_create_std_mfdb(int x, int y, int w, int h)
1032{
1033 /* allocate memory for the snapshot */
1034 {
1035 int scr_stride = MFDB_STRIDE( w );
1036 int scr_size = ( ((scr_stride >> 3) * h) * vdi_sysinfo.scr_bpp );
1037 if(size_buf_std == 0 ){
1038 /* init screen mfdb */
1039 buf_std.fd_addr = malloc( scr_size );
1040 size_buf_std = scr_size;
1041 } else {
1042 if( scr_size >size_buf_std ) {
1043 buf_std.fd_addr = realloc(
1044 buf_std.fd_addr, scr_size
1045 );
1046 size_buf_std = scr_size;
1047 }
1048 }
1049 if(buf_std.fd_addr == NULL ) {
1050 size_buf_std = 0;
1051 return( NULL );
1052 }
1053 buf_std.fd_nplanes = 8;
1054 buf_std.fd_w = scr_stride;
1055 buf_std.fd_h = h;
1056 buf_std.fd_stand = 1;
1057 buf_std.fd_wdwidth = scr_stride >> 4;
1058 assert(buf_std.fd_addr != NULL );
1059 }
1060 MFDB * native = snapshot_create_native_mfdb(x,y,w,h );
1061 assert( native );
1062
1064 return( &buf_std );
1065}
1066
1067
1068/**
1069 * Convert an bitmap to an 8 bit device dependant MFDB
1070 * \param img the bitmap (only tested with 32bit bitmaps)
1071 * \param x screen coord of the background
1072 * \param y screen coord of the background
1073 * \param clip the region of the image that get's converted
1074 * \param bg the background used for cheap transparency
1075 * \param flags
1076 * \param out receives the converted bitmap (still owned by the plot API)
1077 *
1078 */
1079static bool
1080bitmap_convert_8(struct bitmap *img,
1081 int x,
1082 int y,
1083 GRECT *clip,
1084 uint32_t bg,
1085 uint32_t flags,
1086 MFDB *out)
1087{
1088 MFDB native;
1089 MFDB stdform;
1090 int dststride; /* stride of dest. image */
1091 int dstsize; /* size of dest. in byte */
1092 int bw, bh;
1093 struct bitmap * scrbuf = NULL;
1094 bool cache = ( flags & BITMAPF_BUFFER_NATIVE );
1095 bool opaque = atari_bitmap_get_opaque( img );
1096
1097 if( opaque == false ){
1098 if( ( (atari_plot_flags & PLOT_FLAG_TRANS) == 0)
1099 &&
1100 ((flags & (BITMAPF_MONOGLYPH|BITMAPF_BUFFER_NATIVE))==0) ){
1101 opaque = true;
1102 }
1103 }
1104
1105 assert( clip->g_h > 0 );
1106 assert( clip->g_w > 0 );
1107
1108 bw = atari_bitmap_get_width( img );
1109 bh = atari_bitmap_get_height( img );
1110
1111 // The converted bitmap can be saved for subsequent blits, when
1112 // the bitmap is fully opaque
1113
1114 if( (opaque == true) || (flags & BITMAPF_BUFFER_NATIVE ) ){
1115 if( img->converted == true ){
1116 *out = img->native;
1117 return( 0 );
1118 }
1119 if( ( flags & BITMAPF_MONOGLYPH ) == 0 ){
1120 cache = true;
1121 }
1122 }
1123 if( ( flags & BITMAPF_MONOGLYPH ) != 0 ){
1124 assert(cache == false);
1125 }
1126
1127 /* (re)allocate buffer for out image: */
1128 /* altough the buffer is named "buf_packed" on 8bit systems */
1129 /* it's not... */
1130 if( cache == false ){
1131 // the size of the output will match the size of the clipping:
1132 dststride = MFDB_STRIDE( clip->g_w );
1133 dstsize = ( ((dststride >> 3) * clip->g_h) * atari_plot_bpp_virt);
1134 if (dstsize > size_buf_packed) {
1135 int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1;
1136 void *buf;
1137 if (buf_packed == NULL) {
1138 buf = malloc( blocks * CONV_BLOCK_SIZE);
1139 } else {
1140 buf = realloc(buf_packed, blocks * CONV_BLOCK_SIZE);
1141 }
1142 if (buf == NULL) {
1143 return( 0-ERR_NO_MEM );
1144 }
1145 buf_packed = buf;
1147 }
1148 native.fd_addr = buf_packed;
1149 }
1150 else {
1151 // the output image will be completly saved, so size of the output
1152 // image will match the input image size.
1153 dststride = MFDB_STRIDE( bw );
1154 dstsize = ( ((dststride >> 3) * bh) * atari_plot_bpp_virt);
1155 assert( out->fd_addr == NULL );
1156 native.fd_addr = malloc( dstsize );
1157 if (native.fd_addr == NULL){
1158 if (scrbuf != NULL)
1159 atari_bitmap_destroy(scrbuf);
1160 return( 0-ERR_NO_MEM );
1161 }
1162 }
1163
1164
1165 /*
1166 on 8 bit systems we must convert the TC (ABGR) image
1167 to vdi standard format. ( only tested for 256 colors )
1168 and then convert it to native format with v_trnfm()
1169 */
1170 // realloc mem for stdform
1171 if( opaque == false ){
1172 // point image to snapshot buffer, otherwise allocate mem
1173 MFDB * bg = snapshot_create_std_mfdb(x, y, clip->g_w, clip->g_h);
1174 stdform.fd_addr = bg->fd_addr;
1175 bh = clip->g_h;
1176 } else {
1177 if (dstsize > size_buf_planar) {
1178 int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1;
1179 void *buf;
1180 if (buf_planar == NULL) {
1181 buf = malloc(blocks * CONV_BLOCK_SIZE);
1182 } else {
1183 buf = realloc(buf_planar, blocks * CONV_BLOCK_SIZE);
1184 }
1185 if (buf == NULL ) {
1186 if (cache) {
1187 free(native.fd_addr);
1188 }
1189 return( 0-ERR_NO_MEM );
1190 }
1191 buf_planar = buf;
1193 }
1194 stdform.fd_addr = buf_planar;
1195 }
1196 stdform.fd_w = dststride;
1197 stdform.fd_h = bh;
1198 stdform.fd_wdwidth = dststride >> 4;
1199 stdform.fd_stand = 1;
1200 stdform.fd_nplanes = (short)atari_plot_bpp_virt;
1201 stdform.fd_r1 = stdform.fd_r2 = stdform.fd_r3 = 0;
1202
1203 int img_stride = atari_bitmap_get_rowstride(img);
1204 uint32_t prev_pixel = 0x12345678; //TODO: check for collision in first pixel
1205 unsigned long col = 0;
1206 unsigned char val = 0;
1207 uint32_t * row;
1208 uint32_t pixel;
1209 int wdplanesize = stdform.fd_wdwidth*stdform.fd_h;
1210
1211 if( opaque == false ){
1212 // apply transparency and convert to vdi std format
1213 unsigned long bgcol = 0;
1214 unsigned char prev_col = 0;
1215 for( y=0; y<clip->g_h; y++ ){
1216 row = (uint32_t *)(img->pixdata + (img_stride * (y+clip->g_y)));
1217 for( x=0; x<clip->g_w; x++ ){
1218 pixel = row[x+clip->g_x];
1219 if( (pixel&0xFF) == 0 ){
1220 continue;
1221 }
1222 if( (pixel&0xFF) < 0xF0 ){
1223 col = get_stdpx( &stdform, wdplanesize,x,y );
1224 if( (col != prev_col) || (y == 0) )
1225 bgcol = (((rgb_lookup[col][2] << 16) | (rgb_lookup[col][1] << 8) | (rgb_lookup[col][0]))<<8);
1226 if( prev_col != col || prev_pixel != pixel ){
1227 prev_col = col;
1228 pixel = ablend( pixel, bgcol );
1229 prev_pixel = pixel;
1230 pixel = pixel >> 8;
1231 /* convert pixel value to vdi color index: */
1232 col = ( ((pixel&0xFF)<<16)
1233 | (pixel&0xFF00)
1234 | ((pixel&0xFF0000)>>16) );
1235 val = RGB_TO_VDI( col );
1236 }
1237 set_stdpx( &stdform, wdplanesize, x, y, val );
1238 } else {
1239 if( pixel != prev_pixel ){
1240 /* convert pixel value to vdi color index: */
1241 pixel = pixel >> 8;
1242 col = ( ((pixel&0xFF)<<16)
1243 | (pixel&0xFF00)
1244 | ((pixel&0xFF0000)>>16) );
1245 val = RGB_TO_VDI( col );
1246 prev_pixel = pixel;
1247 }
1248 set_stdpx( &stdform, wdplanesize, x, y, val );
1249 }
1250 }
1251 }
1252 // adjust output position:
1253 clip->g_x = 0;
1254 clip->g_y = 0;
1255 } else {
1256 // convert the whole image data to vdi std format.
1257 for( y=0; y < bh; y++ ){
1258 row = (uint32_t *)(img->pixdata + (img_stride * y));
1259 for( x=0; x < bw; x++ ){
1260 pixel = row[x];
1261 if( pixel != prev_pixel ){
1262 /* convert pixel value to vdi color index: */
1263 pixel = pixel >> 8;
1264 col = ( ((pixel&0xFF)<<16)
1265 | (pixel&0xFF00)
1266 | ((pixel&0xFF0000)>>16) );
1267 val = RGB_TO_VDI( col );
1268 prev_pixel = pixel;
1269 }
1270 set_stdpx( &stdform, wdplanesize, x, y, val );
1271 }
1272 }
1273 }
1274
1275 // convert into native format:
1276 native.fd_w = stdform.fd_w;
1277 native.fd_h = stdform.fd_h;
1278 native.fd_wdwidth = stdform.fd_wdwidth;
1279 native.fd_stand = 0;
1280 native.fd_nplanes = (short)atari_plot_bpp_virt;
1281 native.fd_r1 = native.fd_r2 = native.fd_r3 = 0;
1282 vr_trnfm(atari_plot_vdi_handle, &stdform, &native );
1283 *out = native;
1284 if( cache == true ){
1285 img->native = native;
1286 img->converted = true;
1287 }
1288
1289 return(0);
1290}
1291#endif
1292
1293
1294/**
1295 * Convert bitmap to the native screen format
1296 *
1297 * \param img the bitmap
1298 * \param x coordinate where the bitmap REGION (described in clip)
1299 * shall be drawn (screen coords)
1300 * \param y coordinate where the bitmap REGION (described in clip)
1301 * shall be drawn (screen coords)
1302 * \param clip which area of the bitmap shall be drawn
1303 * \param bg background color
1304 * \param flags blit flags
1305 * \param out the result MFDB
1306 */
1307static bool
1309 int x,
1310 int y,
1311 GRECT *clip,
1312 uint32_t bg,
1313 uint32_t flags,
1314 MFDB *out)
1315{
1316 int dststride; /* stride of dest. image */
1317 int dstsize; /* size of dest. in byte */
1318 int err;
1319 int bw, bh;
1320 struct bitmap * scrbuf = NULL;
1321 struct bitmap * source = NULL;
1322 bool cache = ( flags & BITMAPF_BUFFER_NATIVE );
1323 bool opaque = atari_bitmap_get_opaque( img );
1324
1325 if (opaque == false ) {
1326 if( ( (atari_plot_flags & PLOT_FLAG_TRANS) == 0)
1327 &&
1328 ((flags & (BITMAPF_MONOGLYPH|BITMAPF_BUFFER_NATIVE))==0) ){
1329 opaque = true;
1330 }
1331 }
1332
1333 assert( clip->g_h > 0 );
1334 assert( clip->g_w > 0 );
1335
1336 bw = atari_bitmap_get_width( img );
1337 bh = atari_bitmap_get_height( img );
1338
1339 // The converted bitmap can be saved for subsequent blits, WHEN:
1340 // A.) the bitmap is fully opaque OR
1341 // B.) the bitmap is completly inside the window
1342 // the latter one is important for alpha blits,
1343 // because we must get the window background to apply transparency
1344 // If the image is not completly within the window,
1345 // we can't get the whole background for the image.
1346 // this only works if the image isn't used at several different places.
1347 // In fact in case of alpha bitmap caching it is only used for the
1348 // toolbar buttons right now.
1349
1350 if( (opaque == true) || (flags & BITMAPF_BUFFER_NATIVE ) ){
1351 if( img->converted == true ){
1352 *out = img->native;
1353 return( 0 );
1354 }
1355 if( ( flags & BITMAPF_MONOGLYPH ) == 0 ){
1356 cache = true;
1357 }
1358 }
1359
1360 /* rem. if eddi xy is installed, we could directly access the screen! */
1361 /* apply transparency to the image: */
1362 if (( opaque == false )) {
1363 /* copy the screen to an temp buffer: */
1364 if ((flags & BITMAPF_BUFFER_NATIVE) == 0) {
1365 scrbuf = snapshot_create(x, y, clip->g_w, clip->g_h);
1366 if( scrbuf != NULL ) {
1367
1368 assert( clip->g_w <= bw );
1369 assert( clip->g_h <= bh );
1370
1371 // copy blended pixels to the screen buffer:
1372 ablend_bitmap( img, scrbuf, clip, NULL );
1373 /* adjust size which gets converted: */
1374 bw = clip->g_w;
1375 bh = clip->g_h;
1376 /* adjust output position: */
1377 clip->g_x = 0;
1378 clip->g_y = 0;
1379 /* set the source of conversion: */
1380 source = scrbuf;
1381 }
1382 } else {
1383 /*
1384 The whole bitmap can be transformed to an mfdb
1385 (and get's cached)
1386 */
1387 GRECT region = { 0, 0, bw, bh };
1388 ablend_pixel( img, bg, &region );
1389 source = img;
1390 }
1391 } else {
1392 source = img;
1393 }
1394 /* (re)allocate buffer for converted image: */
1395 dststride = MFDB_STRIDE(bw);
1396 dstsize = ( ((dststride >> 3) * bh) * atari_plot_bpp_virt );
1397 if (cache == false) {
1398 /* ensure cache buffer is large enough */
1399 if (dstsize > size_buf_packed) {
1400 int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1;
1401 void *buf;
1402 if (buf_packed == NULL) {
1403 buf = malloc(blocks * CONV_BLOCK_SIZE);
1404 } else {
1405 buf = realloc(buf_packed, blocks * CONV_BLOCK_SIZE);
1406 }
1407 if (buf == NULL ) {
1408 if (scrbuf != NULL) {
1409 atari_bitmap_destroy(scrbuf);
1410 }
1411 return( 0-ERR_NO_MEM );
1412 }
1413 buf_packed = buf;
1415 }
1416 out->fd_addr = buf_packed;
1417 } else {
1418 assert( out->fd_addr == NULL );
1419 out->fd_addr = (void*)malloc( dstsize );
1420 if( out->fd_addr == NULL ){
1421 if( scrbuf != NULL )
1422 atari_bitmap_destroy( scrbuf );
1423 return( 0-ERR_NO_MEM );
1424 }
1425 }
1426
1427 out->fd_w = dststride;
1428 out->fd_h = bh;
1429 out->fd_wdwidth = dststride >> 4;
1430 out->fd_stand = 0;
1431 out->fd_nplanes = (short)atari_plot_bpp_virt;
1432 out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
1433
1434 err = Hermes_ConverterRequest(
1436 &nsfmt,
1437 &vfmt
1438 );
1439 assert( err != 0 );
1440
1441 // FIXME: here we can use the same optimization which is used for
1442 // the snapshot creation.
1443
1444 /* convert image to virtual format: */
1445 err = Hermes_ConverterCopy( hermes_cnv_h,
1446 source->pixdata,
1447 0, /* x src coord of top left in pixel coords */
1448 0, /* y src coord of top left in pixel coords */
1449 bw, bh,
1450 source->rowstride, /* stride as bytes */
1451 out->fd_addr,
1452 0, /* x dst coord of top left in pixel coords */
1453 0,/* y dst coord of top left in pixel coords */
1454 bw, bh,
1455 (dststride >> 3) * atari_plot_bpp_virt /* stride as bytes */
1456 );
1457 assert( err != 0 );
1458
1459 if( cache == true ){
1460 img->native = *out;
1461 img->converted = true;
1462 }
1463 return( 0 );
1464
1465}
1466
1467
1468inline static void convert_bitmap_done(void)
1469{
1471 void *buf;
1472 /* free the mem if it was an large allocation ... */
1473 buf = realloc(buf_packed, CONV_KEEP_LIMIT);
1474 if (buf != NULL) {
1475 buf_packed = buf;
1477 }
1478 }
1479}
1480
1481
1482bool plot_blit_bitmap(struct bitmap * bmp, int x, int y,
1483 unsigned long bg, unsigned long flags )
1484{
1485 MFDB src_mf;
1486 MFDB scrmf;
1487 short pxy[8];
1488 GRECT off, clip, vis;
1489 int screen_x, screen_y;
1490
1491 src_mf.fd_addr = NULL;
1492 scrmf.fd_addr = NULL;
1493
1494 off.g_x = x;
1495 off.g_y = y;
1496 off.g_h = bmp->height;
1497 off.g_w = bmp->width;
1498
1499 // clip plotter clip rectangle:
1500 clip.g_x = view.clipping.x0;
1501 clip.g_y = view.clipping.y0;
1504
1505 if( !rc_intersect( &clip, &off) ) {
1506 return(true);
1507 }
1508
1509 // clip the visible rectangle of the plot area
1510 // this is the area of the plotter which falls into
1511 // screen region:
1513 if( !rc_intersect( &vis, &off) ) {
1514 return(true);
1515 }
1516
1517 screen_x = view.x + off.g_x;
1518 screen_y = view.y + off.g_y;
1519
1520 // convert the clipping relative to bitmap:
1521 off.g_x = off.g_x - x;
1522 off.g_y = off.g_y - y;
1523 assert( (off.g_x >= 0) && (off.g_y >= 0) );
1524
1525 /* Convert the Bitmap to native screen format - ready for output. */
1526 /* This includes blending transparent pixels: */
1527 if (bitmap_convert(bmp, screen_x, screen_y, &off, bg, flags, &src_mf)
1528 != 0 ) {
1529 return(true);
1530 }
1531
1532 // setup the src region:
1533 pxy[0] = off.g_x;
1534 pxy[1] = off.g_y;
1535 pxy[2] = off.g_x + off.g_w-1;
1536 pxy[3] = off.g_y + off.g_h-1;
1537
1538 // setup the target region:
1539 pxy[4] = screen_x;
1540 pxy[5] = screen_y;
1541 pxy[6] = screen_x + off.g_w-1;
1542 pxy[7] = screen_y + off.g_h-1;
1543
1544 vro_cpyfm(atari_plot_vdi_handle, S_ONLY, (short*)&pxy, &src_mf, &scrmf);
1547 return(true);
1548}
1549
1550
1551bool plot_blit_mfdb(GRECT * loc, MFDB * insrc, short fgcolor,
1552 uint32_t flags)
1553{
1554 MFDB screen;
1555// MFDB tran;
1556 MFDB * src;
1557 short pxy[8];
1558 short c[2] = {fgcolor, 0};
1559 GRECT off;
1560
1561 plot_get_clip_grect(&off);
1562 if( rc_intersect(loc, &off) == 0 ){
1563 return( 1 );
1564 }
1565
1566 init_mfdb( 0, loc->g_w, loc->g_h, 0, &screen );
1567//
1568// if( insrc->fd_stand){
1569// printf("st\n");
1570// int size = init_mfdb( insrc->fd_nplanes, loc->g_w, loc->g_h,
1571// MFDB_FLAG_NOALLOC,
1572// &tran
1573// );
1574// if( size_buf_scr == 0 ){
1575// buf_scr.fd_addr = malloc( size );
1576// size_buf_scr = size;
1577// } else {
1578// if( size > size_buf_scr ) {
1579// buf_scr.fd_addr = realloc(
1580// buf_scr.fd_addr, size
1581// );
1582// size_buf_scr = size;
1583// }
1584// }
1585// tran.fd_addr = buf_scr.fd_addr;
1586// vr_trnfm(atari_plot_vdi_handle, insrc, &tran );
1587// src = &tran;
1588// } else {
1589 src = insrc;
1590// }
1591
1592 pxy[0] = off.g_x - loc->g_x;
1593 pxy[1] = off.g_y - loc->g_y;
1594 pxy[2] = pxy[0] + off.g_w - 1;
1595 pxy[3] = pxy[1] + off.g_h - 1;
1596 pxy[4] = view.x + off.g_x;
1597 pxy[5] = view.y + off.g_y;
1598 pxy[6] = pxy[4] + off.g_w-1;
1599 pxy[7] = pxy[5] + off.g_h-1;
1600
1601
1602 if( flags & PLOT_FLAG_TRANS && src->fd_nplanes == 1){
1603 vrt_cpyfm(atari_plot_vdi_handle, MD_REPLACE/*MD_TRANS*/, (short*)pxy, src, &screen, (short*)&c);
1604 } else {
1605 /* this method only plots transparent bitmaps, right now... */
1606 }
1607 return( 1 );
1608}
1609
1610
1611/* exported interface documented in atari/plot.h */
1612int plot_init(const struct redraw_context *ctx, char *fdrvrname)
1613{
1614 GRECT loc_pos = { 0, 0, 360, 400 };
1615 int err=0;
1616
1617 if( nsoption_int(atari_dither) == 1)
1619 if( nsoption_int(atari_transparency) == 1 )
1621 if( nsoption_int(atari_font_monochrom) == 1 )
1623
1624 if (atari_plot_vdi_handle == -1) {
1625
1626 short dummy;
1627 short work_in[12] = {Getrez()+2,1,1,1,1,1,1,1,1,1,2,1};
1628 short work_out[57];
1629 atari_plot_vdi_handle=graf_handle(&dummy, &dummy, &dummy, &dummy);
1630 v_opnvwk(work_in, &atari_plot_vdi_handle, work_out);
1631 NSLOG(netsurf, INFO, "Plot VDI handle: %d", atari_plot_vdi_handle);
1632 }
1634 if(verbose_log) {
1637 }
1638
1640 atari_font_flags, &err);
1641 if (err) {
1642 const char * desc = plot_err_str(err);
1643 NSLOG(netsurf, INFO, "Unable to load font plotter %s -> %s",
1644 fdrvrname, desc);
1645 die("font plotter");
1646 }
1647
1648 memset(&view, 0, sizeof(struct s_view));
1650 view.x = loc_pos.g_x;
1651 view.y = loc_pos.g_y;
1652 view.w = loc_pos.g_w;
1653 view.h = loc_pos.g_h;
1654 size_buf_packed = 0;
1655 size_buf_planar = 0;
1656 buf_packed = NULL;
1657 buf_planar = NULL;
1660 } else {
1662 }
1663
1664 plot_set_scale(1.0);
1666
1667 struct rect clip;
1668 clip.x0 = 0;
1669 clip.y0 = 0;
1670 clip.x1 = view.w;
1671 clip.y1 = view.h;
1672 ctx->plot->clip(ctx, &clip);
1673
1674 assert(Hermes_Init());
1675
1676#ifdef WITH_8BPP_SUPPORT
1677 bitmap_convert = (vdi_sysinfo.scr_bpp > 8) ? bitmap_convert_tc : bitmap_convert_8;
1678
1679 /* Setup color lookup tables and palette */
1680 unsigned char rgbcol[4];
1681 if( vdi_sysinfo.scr_bpp <= 8 ){
1682 unsigned char graytone=0;
1683 int i;
1684 for( i=0; i<=255; i++ ) {
1685
1686 // get the current color and save it for restore:
1687 vq_color(atari_plot_vdi_handle, i, 1, (unsigned short*)&sys_pal[i][0] );
1688 if( i<OFFSET_WEB_PAL ) {
1689 pal[i][0] = sys_pal[i][0];
1690 pal[i][1] = sys_pal[i][1];
1691 pal[i][2] = sys_pal[i][2];
1692 } else if( vdi_sysinfo.scr_bpp >= 8 ) {
1693 if ( i < OFFSET_CUST_PAL ){
1694 pal[i][0] = vdi_web_pal[i-OFFSET_WEB_PAL][0];
1695 pal[i][1] = vdi_web_pal[i-OFFSET_WEB_PAL][1];
1696 pal[i][2] = vdi_web_pal[i-OFFSET_WEB_PAL][2];
1697 //set the new palette color to websafe value:
1698 vs_color(atari_plot_vdi_handle, i, &pal[i][0]);
1699 }
1700 if( i >= OFFSET_CUST_PAL && i<OFFSET_CUST_PAL+16 ) {
1701 /* here we define 20 additional gray colors... */
1702 rgbcol[1] = rgbcol[2] = rgbcol[3] = ((graytone&0x0F) << 4);
1703 rgb_to_vdi1000( &rgbcol[0], &pal[i][0] );
1704 vs_color(atari_plot_vdi_handle, i, &pal[i][0]);
1705 graytone++;
1706 }
1707
1708 }
1709 vdi1000_to_rgb( &pal[i][0], &rgb_lookup[i][0] );
1710 }
1711
1712 } else {
1713 /* no need to change the palette - its application specific */
1714 }
1715#else
1717#endif
1718
1719 /* Setup Hermes conversion handles */
1720 unsigned long hermesflags = (atari_plot_flags & PLOT_FLAG_DITHER) ? HERMES_CONVERT_DITHER : 0;
1721 hermes_cnv_h = Hermes_ConverterInstance(hermesflags);
1722 assert( hermes_cnv_h );
1723 hermes_res_h = Hermes_ConverterInstance(hermesflags);
1724 assert( hermes_res_h );
1725
1726 /* set up the src & dst format: */
1727 /* netsurf uses RGBA ... */
1728 nsfmt.a = 0xFFUL;
1729 nsfmt.b = 0x0FF00UL;
1730 nsfmt.g = 0x0FF0000UL;
1731 nsfmt.r = 0x0FF000000UL;
1732 nsfmt.bits = 32;
1733 nsfmt.indexed = false;
1734 nsfmt.has_colorkey = false;
1735
1741 vfmt.indexed = (atari_plot_bpp_virt <= 8) ? 1 : 0;
1742 vfmt.has_colorkey = 0;
1743
1744 return( err );
1745}
1746
1747
1748int plot_finalise( void )
1749{
1750
1752
1753#ifdef WITH_8BPP_SUPPORT
1754 if (vfmt.indexed) {
1755 int i;
1756 for (i=OFFSET_WEB_PAL; i<OFFSET_CUST_PAL+16; i++) {
1757 vs_color(atari_plot_vdi_handle, i, &sys_pal[i][0]);
1758 }
1759 }
1760#endif
1761
1762 /* close Hermes stuff: */
1763 Hermes_ConverterReturn(hermes_cnv_h);
1764 Hermes_Done();
1765
1766 /* free up temporary buffers */
1767 free(buf_packed );
1768 free(buf_planar);
1770
1771 return 0;
1772}
1773
1774
1775bool plot_lock(void)
1776{
1778 return(true);
1779 if( !wind_update(BEG_UPDATE|0x100) )
1780 return(false);
1781 if( !wind_update(BEG_MCTRL|0x100) ){
1782 wind_update(END_UPDATE);
1783 return(false);
1784 }
1786 graf_mouse(M_OFF, NULL);
1787 return(true);
1788}
1789
1790
1791bool plot_unlock(void)
1792{
1793 if( (atari_plot_flags & PLOT_FLAG_LOCKED) == 0 )
1794 return(true);
1795 wind_update(END_MCTRL);
1796 wind_update(END_UPDATE);
1797 graf_mouse(M_ON, NULL);
1798 vs_clip_off(atari_plot_vdi_handle);
1799 atari_plot_flags &= ~PLOT_FLAG_LOCKED;
1800 return(false);
1801}
1802
1803
1804/* exported interface documented in atari/plot.h */
1805bool
1806plot_set_dimensions(const struct redraw_context *ctx, int x, int y, int w, int h)
1807{
1808 bool doupdate = false;
1809 struct rect newclip = {0, 0, w, h};
1810 GRECT absclip = {x, y, w, h};
1811
1812 if (!(w == view.w && h == view.h)) {
1813 view.w = (short)w;
1814 view.h = (short)h;
1815 doupdate = true;
1816 }
1817 if (!(x == view.x && y == view.y)) {
1818 view.x = (short)x;
1819 view.y = (short)y;
1820 doupdate = true;
1821 }
1822 if (doupdate==true)
1824
1825 //dbg_rect("plot_set_dimensions", &newclip);
1826
1827 plot_set_abs_clipping(&absclip);
1828 ctx->plot->clip(ctx, &newclip);
1829 return(true);
1830}
1831
1832
1833/**
1834 * Get current canvas size
1835 *
1836 * \param dst the GRECT * which receives the canvas size
1837 */
1838bool plot_get_dimensions(GRECT *dst)
1839{
1840 dst->g_x = view.x;
1841 dst->g_y = view.y;
1842 dst->g_w = view.w;
1843 dst->g_h = view.h;
1844 return(true);
1845}
1846
1847
1848/**
1849 * set scale of plotter.
1850 * \param scale the new scale value
1851 * \return the old scale value
1852 */
1853
1854float plot_set_scale(float scale)
1855{
1856 float ret = view.scale;
1857
1858 view.scale = scale;
1859
1860 return(ret);
1861}
1862
1863
1865{
1866 return(view.scale);
1867}
1868
1869
1870/**
1871 * Subsequent calls to plot_clip will be clipped by the absolute clip.
1872 *
1873 * \param area the maximum clipping rectangle (absolute screen coords)
1874 */
1875void plot_set_abs_clipping(const GRECT *area)
1876{
1877 GRECT canvas;
1878
1879 plot_get_dimensions(&canvas);
1880
1881 if(!rc_intersect(area, &canvas)){
1882 view.abs_clipping.x0 = 0;
1883 view.abs_clipping.x1 = 0;
1884 view.abs_clipping.y0 = 0;
1885 view.abs_clipping.y1 = 0;
1886 } else {
1887 view.abs_clipping.x0 = area->g_x;
1888 view.abs_clipping.x1 = area->g_x + area->g_w;
1889 view.abs_clipping.y0 = area->g_y;
1890 view.abs_clipping.y1 = area->g_y + area->g_h;
1891 }
1892}
1893
1894
1895/**
1896 * Get the maximum clip extent, in absolute screen coords
1897 * \param dst the structure that receives the absolute clipping
1898 */
1900{
1901 *dst = view.abs_clipping;
1902}
1903
1904
1905/**
1906 * Get the maximum clip extent, in absolute screen coords
1907 * \param dst the structure that receives the absolute clipping
1908 */
1910{
1911 dst->g_x = view.abs_clipping.x0;
1912 dst->g_w = view.abs_clipping.x1 - view.abs_clipping.x0;
1913 dst->g_y = view.abs_clipping.y0;
1914 dst->g_h = view.abs_clipping.y1 - view.abs_clipping.y0;
1915}
1916
1917
1919{
1920 return(atari_plot_vdi_handle);
1921}
1922
1923
1925{
1926 return(atari_plot_flags);
1927}
1928
1929
1930bool plot_get_clip(struct rect * out)
1931{
1932 out->x0 = view.clipping.x0;
1933 out->y0 = view.clipping.y0;
1934 out->x1 = view.clipping.x1;
1935 out->y1 = view.clipping.y1;
1936 return( true );
1937}
1938
1939
1940void plot_get_clip_grect(GRECT * out)
1941{
1942 struct rect clip={0,0,0,0};
1943
1945
1946 out->g_x = clip.x0;
1947 out->g_y = clip.y0;
1948 out->g_w = clip.x1 - clip.x0;
1949 out->g_h = clip.y1 - clip.y0;
1950}
1951
1952
1954{
1955 return(fplotter);
1956}
1957
1958
1960{
1961 fplotter = font_plotter;
1962}
1963
1964
1965/**
1966 * \brief Sets a clip rectangle for subsequent plot operations.
1967 *
1968 * \param ctx The current redraw context.
1969 * \param clip The rectangle to limit all subsequent plot
1970 * operations within.
1971 * \return NSERROR_OK on success else error code.
1972 */
1973static nserror
1974plot_clip(const struct redraw_context *ctx, const struct rect *clip)
1975{
1976 GRECT canvas, screen, gclip, maxclip;
1977 short pxy[4];
1978
1979 screen.g_x = 0;
1980 screen.g_y = 0;
1981 screen.g_w = vdi_sysinfo.scr_w;
1982 screen.g_h = vdi_sysinfo.scr_h;
1983
1984 plot_get_dimensions(&canvas);
1985
1986 view.clipping.y0 = clip->y0;
1987 view.clipping.y1 = clip->y1;
1988 view.clipping.x0 = clip->x0;
1989 view.clipping.x1 = clip->x1;
1990
1991 plot_get_clip_grect(&gclip);
1992
1993 gclip.g_x += canvas.g_x;
1994 gclip.g_y += canvas.g_y;
1995
1996 rc_intersect(&canvas, &gclip);
1997
1998 if(gclip.g_h < 0){
1999 gclip.g_h = 0;
2000 }
2001
2002 if (!rc_intersect(&screen, &gclip)) {
2003 //dbg_rect("cliprect: ", &view.clipping);
2004 //dbg_grect("screen: ", &canvas);
2005 //dbg_grect("canvas clipped: ", &gclip);
2006 //assert(1 == 0);
2007 }
2008
2009 // When setting VDI clipping, obey to maximum cliping rectangle:
2011 rc_intersect(&maxclip, &gclip);
2012
2013 //dbg_grect("canvas clipped to screen", &gclip);
2014
2015 pxy[0] = gclip.g_x;
2016 pxy[1] = gclip.g_y;
2017 pxy[2] = pxy[0] + gclip.g_w;
2018 pxy[3] = pxy[1] + gclip.g_h;
2019
2020 vs_clip(atari_plot_vdi_handle, 1, (short*)&pxy);
2021
2022 return NSERROR_OK;
2023}
2024
2025
2026/**
2027 * Plots an arc
2028 *
2029 * plot an arc segment around (x,y), anticlockwise from angle1
2030 * to angle2. Angles are measured anticlockwise from
2031 * horizontal, in degrees.
2032 *
2033 * \param ctx The current redraw context.
2034 * \param pstyle Style controlling the arc plot.
2035 * \param x The x coordinate of the arc.
2036 * \param y The y coordinate of the arc.
2037 * \param radius The radius of the arc.
2038 * \param angle1 The start angle of the arc.
2039 * \param angle2 The finish angle of the arc.
2040 * \return NSERROR_OK on success else error code.
2041 */
2042static nserror
2043plot_arc(const struct redraw_context *ctx,
2044 const plot_style_t *pstyle,
2045 int x, int y, int radius, int angle1, int angle2)
2046{
2047 vswr_mode(atari_plot_vdi_handle, MD_REPLACE);
2048 if (pstyle->fill_type == PLOT_OP_TYPE_NONE) {
2049 return NSERROR_OK;
2050 }
2051
2052 if (pstyle->fill_type != PLOT_OP_TYPE_SOLID) {
2054 vsf_perimeter(atari_plot_vdi_handle, 1);
2055 vsf_interior(atari_plot_vdi_handle, 1 );
2057 view.x + x,
2058 view.y + y,
2059 radius,
2060 angle1 * 10,
2061 angle2 * 10);
2062 } else {
2064 vsl_width(atari_plot_vdi_handle, 1);
2065 vsf_perimeter(atari_plot_vdi_handle, 1);
2067 view.x + x,
2068 view.y + y, radius,
2069 angle1 * 10,
2070 angle2 * 10);
2071 }
2072
2073 return NSERROR_OK;
2074}
2075
2076
2077/**
2078 * Plots a circle
2079 *
2080 * Plot a circle centered on (x,y), which is optionally filled.
2081 *
2082 * \param ctx The current redraw context.
2083 * \param pstyle Style controlling the circle plot.
2084 * \param x x coordinate of circle centre.
2085 * \param y y coordinate of circle centre.
2086 * \param radius circle radius.
2087 * \return NSERROR_OK on success else error code.
2088 */
2089static nserror
2090plot_disc(const struct redraw_context *ctx,
2091 const plot_style_t *pstyle,
2092 int x, int y, int radius)
2093{
2094 if (pstyle->fill_type != PLOT_OP_TYPE_SOLID) {
2096 vsf_perimeter(atari_plot_vdi_handle, 1);
2097 vsf_interior(atari_plot_vdi_handle, 0);
2098 v_circle(atari_plot_vdi_handle, view.x + x, view.y + y, radius);
2099 } else {
2101 vsf_perimeter(atari_plot_vdi_handle, 0);
2102 vsf_interior(atari_plot_vdi_handle, FIS_SOLID);
2103 v_circle(atari_plot_vdi_handle, view.x + x, view.y + y, radius);
2104 }
2105 return NSERROR_OK;
2106}
2107
2108
2109/**
2110 * Plots a line
2111 *
2112 * plot a line from (x0,y0) to (x1,y1). Coordinates are at
2113 * centre of line width/thickness.
2114 *
2115 * \param ctx The current redraw context.
2116 * \param pstyle Style controlling the line plot.
2117 * \param line A rectangle defining the line to be drawn
2118 * \return NSERROR_OK on success else error code.
2119 */
2120static nserror
2121plot_line(const struct redraw_context *ctx,
2122 const plot_style_t *pstyle,
2123 const struct rect *line)
2124{
2125 short pxy[4];
2126 uint32_t lt;
2127 int sw = plot_style_fixed_to_int(pstyle->stroke_width);
2128
2129 if (((line->x0 < 0) && (line->x1 < 0)) ||
2130 ((line->y0 < 0) && (line->y1 < 0))) {
2131 return NSERROR_OK;
2132 }
2133
2134 pxy[0] = view.x + MAX(0, line->x0);
2135 pxy[1] = view.y + MAX(0, line->y0);
2136 pxy[2] = view.x + MAX(0, line->x1);
2137 pxy[3] = view.y + MAX(0, line->y1);
2138
2139 if ((line->y0 > view.h-1) && (line->y1 > view.h-1)) {
2140 return NSERROR_OK;
2141 }
2142
2143 //printf("view: %d,%d,%d,%d\n", view.x, view.y, view.w, view.h);
2144 //printf("line: %d,%d,%d,%d\n", x0, y0, x1, y1);
2145
2146 //plot_vdi_clip(true);
2147
2148 if (sw == 0) {
2149 sw = 1;
2150 }
2151 NSLT2VDI(lt, pstyle)
2152 vsl_type(atari_plot_vdi_handle, (lt&0x0F));
2153 /* if the line style is not available within VDI system,define own style: */
2154 if ((lt&0x0F) == 7 ) {
2155 vsl_udsty(atari_plot_vdi_handle, ((lt&0xFFFF00) >> 8));
2156 }
2157 vsl_width(atari_plot_vdi_handle, (short)sw);
2159 v_pline(atari_plot_vdi_handle, 2, (short *)&pxy );
2160 //plot_vdi_clip(false);
2161
2162 return NSERROR_OK;
2163}
2164
2165
2166/**
2167 * Plots a rectangle.
2168 *
2169 * The rectangle can be filled an outline or both controlled
2170 * by the plot style The line can be solid, dotted or
2171 * dashed. Top left corner at (x0,y0) and rectangle has given
2172 * width and height.
2173 *
2174 * \param ctx The current redraw context.
2175 * \param pstyle Style controlling the rectangle plot.
2176 * \param rect A rectangle defining the line to be drawn
2177 * \return NSERROR_OK on success else error code.
2178 */
2179static nserror
2181 const plot_style_t *pstyle,
2182 const struct rect *rect)
2183{
2184 short pxy[4];
2185 GRECT r, rclip, sclip;
2186 int sw = plot_style_fixed_to_int(pstyle->stroke_width);
2187 uint32_t lt;
2188
2189 /* current canvas clip: */
2190 rclip.g_x = view.clipping.x0;
2191 rclip.g_y = view.clipping.y0;
2192 rclip.g_w = view.clipping.x1 - view.clipping.x0;
2193 rclip.g_h = view.clipping.y1 - view.clipping.y0;
2194
2195 /* physical clipping: */
2196 sclip.g_x = rclip.g_x;
2197 sclip.g_y = rclip.g_y;
2198 sclip.g_w = view.vis_w;
2199 sclip.g_h = view.vis_h;
2200
2201 rc_intersect(&sclip, &rclip);
2202 r.g_x = rect->x0;
2203 r.g_y = rect->y0;
2204 r.g_w = rect->x1 - rect->x0;
2205 r.g_h = rect->y1 - rect->y0;
2206
2207 if (!rc_intersect(&rclip, &r)) {
2208 return NSERROR_OK;
2209 }
2210
2211 if (pstyle->stroke_type != PLOT_OP_TYPE_NONE) {
2212 /*
2213 manually draw the line, because we do not need vdi clipping
2214 for vertical / horizontal line draws.
2215 */
2216 if (sw == 0)
2217 sw = 1;
2218
2219 NSLT2VDI(lt, pstyle);
2220 vsl_type(atari_plot_vdi_handle, (lt&0x0F));
2221 /*
2222 if the line style is not available within VDI system,
2223 define own style:
2224 */
2225 if ((lt&0x0F) == 7 ) {
2226 vsl_udsty(atari_plot_vdi_handle, ((lt&0xFFFF00) >> 8));
2227 }
2228 vsl_width(atari_plot_vdi_handle, (short)sw );
2230 /* top border: */
2231 if (r.g_y == rect->y0) {
2232 pxy[0] = view.x + r.g_x;
2233 pxy[1] = view.y + r.g_y ;
2234 pxy[2] = view.x + r.g_x + r.g_w;
2235 pxy[3] = view.y + r.g_y;
2236 v_pline(atari_plot_vdi_handle, 2, (short *)&pxy);
2237 }
2238
2239 /* right border: */
2240 if (r.g_x + r.g_w == rect->x1 ) {
2241 pxy[0] = view.x + r.g_x + r.g_w;
2242 pxy[1] = view.y + r.g_y;
2243 pxy[2] = view.x + r.g_x + r.g_w;
2244 pxy[3] = view.y + r.g_y + r.g_h;
2245 v_pline(atari_plot_vdi_handle, 2, (short *)&pxy);
2246 }
2247
2248 /* bottom border: */
2249 if ( r.g_y+r.g_h == rect->y1 ) {
2250 pxy[0] = view.x + r.g_x;
2251 pxy[1] = view.y + r.g_y+r.g_h;
2252 pxy[2] = view.x + r.g_x+r.g_w;
2253 pxy[3] = view.y + r.g_y+r.g_h;
2254 v_pline(atari_plot_vdi_handle, 2, (short *)&pxy);
2255 }
2256
2257 /* left border: */
2258 if ( r.g_x == rect->x0 ) {
2259 pxy[0] = view.x + r.g_x;
2260 pxy[1] = view.y + r.g_y;
2261 pxy[2] = view.x + r.g_x;
2262 pxy[3] = view.y + r.g_y + r.g_h;
2263 v_pline(atari_plot_vdi_handle, 2, (short *)&pxy);
2264 }
2265 }
2266
2267 if (pstyle->fill_type != PLOT_OP_TYPE_NONE ) {
2268 short stroke_width = (short)(pstyle->stroke_type != PLOT_OP_TYPE_NONE) ?
2270
2272 vsf_perimeter(atari_plot_vdi_handle, 0);
2273 vsf_interior(atari_plot_vdi_handle, FIS_SOLID);
2274
2275
2276 pxy[0] = view.x + r.g_x + stroke_width;
2277 pxy[1] = view.y + r.g_y + stroke_width;
2278 pxy[2] = view.x + r.g_x + r.g_w -1 - stroke_width;
2279 pxy[3] = view.y + r.g_y + r.g_h -1 - stroke_width;
2280
2281 vsf_style(atari_plot_vdi_handle, 1);
2282 v_bar(atari_plot_vdi_handle, (short*)&pxy);
2283 }
2284
2285 return NSERROR_OK;
2286}
2287
2288
2289/**
2290 * Plot a polygon
2291 *
2292 * Plots a filled polygon with straight lines between
2293 * points. The lines around the edge of the ploygon are not
2294 * plotted. The polygon is filled with the non-zero winding
2295 * rule.
2296 *
2297 * \param ctx The current redraw context.
2298 * \param pstyle Style controlling the polygon plot.
2299 * \param p verticies of polygon
2300 * \param n number of verticies.
2301 * \return NSERROR_OK on success else error code.
2302 */
2303static nserror
2305 const plot_style_t *pstyle,
2306 const int *p,
2307 unsigned int n)
2308{
2309 short pxy[n*2];
2310 unsigned int i = 0;
2311
2312 if (vdi_sysinfo.maxpolycoords > 0)
2313 assert( (signed int)n < vdi_sysinfo.maxpolycoords);
2314
2315 vsf_interior(atari_plot_vdi_handle, FIS_SOLID);
2316 vsf_style(atari_plot_vdi_handle, 1);
2317 for (i = 0; i<n*2; i=i+2) {
2318 pxy[i] = (short)view.x+p[i];
2319 pxy[i+1] = (short)view.y+p[i+1];
2320 }
2321
2322 if (pstyle->fill_type == PLOT_OP_TYPE_SOLID) {
2324 v_fillarea(atari_plot_vdi_handle, n, (short*)&pxy);
2325 } else {
2326 pxy[n*2]=pxy[0];
2327 pxy[n*2+1]=pxy[1];
2329 v_pline(atari_plot_vdi_handle, n+1, (short *)&pxy);
2330 }
2331
2332 return NSERROR_OK;
2333}
2334
2335
2336/**
2337 * Plots a path.
2338 *
2339 * Path plot consisting of cubic Bezier curves. Line and fill colour is
2340 * controlled by the plot style.
2341 *
2342 * \param ctx The current redraw context.
2343 * \param pstyle Style controlling the path plot.
2344 * \param p elements of path
2345 * \param n nunber of elements on path
2346 * \param transform A transform to apply to the path.
2347 * \return NSERROR_OK on success else error code.
2348 */
2349static nserror
2350plot_path(const struct redraw_context *ctx,
2351 const plot_style_t *pstyle,
2352 const float *p,
2353 unsigned int n,
2354 const float transform[6])
2355{
2356 /** \todo Implement atari path plot */
2357 return NSERROR_OK;
2358}
2359
2360
2361/**
2362 * Plot a bitmap
2363 *
2364 * Tiled plot of a bitmap image. (x,y) gives the top left
2365 * coordinate of an explicitly placed tile. From this tile the
2366 * image can repeat in all four directions -- up, down, left
2367 * and right -- to the extents given by the current clip
2368 * rectangle.
2369 *
2370 * The bitmap_flags say whether to tile in the x and y
2371 * directions. If not tiling in x or y directions, the single
2372 * image is plotted. The width and height give the dimensions
2373 * the image is to be scaled to.
2374 *
2375 * \param ctx The current redraw context.
2376 * \param bitmap The bitmap to plot
2377 * \param x The x coordinate to plot the bitmap
2378 * \param y The y coordiante to plot the bitmap
2379 * \param width The width of area to plot the bitmap into
2380 * \param height The height of area to plot the bitmap into
2381 * \param bg the background colour to alpha blend into
2382 * \param flags the flags controlling the type of plot operation
2383 * \return NSERROR_OK on success else error code.
2384 */
2385static nserror
2386plot_bitmap(const struct redraw_context *ctx,
2387 struct bitmap *bitmap,
2388 int x, int y,
2389 int width,
2390 int height,
2391 colour bg,
2392 bitmap_flags_t flags)
2393{
2394 struct bitmap * bm = NULL;
2395 bool repeat_x = (flags & BITMAPF_REPEAT_X);
2396 bool repeat_y = (flags & BITMAPF_REPEAT_Y);
2397 int bmpw,bmph;
2398 struct rect clip = {0,0,0,0};
2399
2402
2403 if(view.scale != 1.0){
2404 width = (int)(((float)width)*view.scale);
2405 height = (int)(((float)height)*view.scale);
2406 }
2407
2408 if ( repeat_x || repeat_y ) {
2410 if (repeat_x && width == 1 && repeat_y && height == 1 ) {
2411 width = MAX( width, clip.x1 - x );
2412 height = MAX( height, clip.y1 - y );
2413 } else if (repeat_x && width == 1 ) {
2414 width = MAX( width, clip.x1 - x);
2415 } else if (repeat_y && height == 1) {
2416 height = MAX( height, clip.y1 - y );
2417 }
2418 }
2419
2420 if (width != bmpw || height != bmph) {
2422 if (bitmap->resized) {
2423 bm = bitmap->resized;
2424 } else {
2425 bm = bitmap;
2426 }
2427 } else {
2428 bm = bitmap;
2429 }
2430
2431 /* out of memory? */
2432 if (bm == NULL) {
2433 printf("plot: out of memory! bmp: %p, bmpres: %p\n",
2434 bitmap, bitmap->resized );
2435 return NSERROR_NOMEM;
2436 }
2437
2438 if (!(repeat_x || repeat_y) ) {
2439 plot_blit_bitmap(bm, x, y, bg, flags);
2440 } else {
2441 int xf,yf;
2442 int xoff = x;
2443 int yoff = y;
2444
2445 if (yoff > clip.y0) {
2446 yoff = (clip.y0 - height) + ((yoff - clip.y0) % height);
2447 }
2448 if (xoff > clip.x0) {
2449 xoff = (clip.x0 - width) + ((xoff - clip.x0) % width);
2450 }
2451 /* for now, repeating just works in the rigth / down direction */
2452 /*
2453 if( repeat_x == true )
2454 xoff = clip.x0;
2455 if(repeat_y == true )
2456 yoff = clip.y0;
2457 */
2458
2459 for (xf = xoff; xf < clip.x1; xf += width ) {
2460 for (yf = yoff; yf < clip.y1; yf += height ) {
2461 plot_blit_bitmap(bm, xf, yf, bg, flags );
2462 if (!repeat_y) {
2463 break;
2464 }
2465 }
2466 if (!repeat_x) {
2467 break;
2468 }
2469 }
2470 }
2471
2472 return NSERROR_OK;
2473}
2474
2475
2476/**
2477 * Text plotting.
2478 *
2479 * \param ctx The current redraw context.
2480 * \param fstyle plot style for this text
2481 * \param x x coordinate
2482 * \param y y coordinate
2483 * \param text UTF-8 string to plot
2484 * \param length length of string, in bytes
2485 * \return NSERROR_OK on success else error code.
2486 */
2487static nserror
2488plot_text(const struct redraw_context *ctx,
2489 const struct plot_font_style *fstyle,
2490 int x,
2491 int y,
2492 const char *text,
2493 size_t length)
2494{
2495 if (view.scale != 1.0) {
2496 plot_font_style_t newstyle = *fstyle;
2497 newstyle.size = (int)((float)fstyle->size*view.scale);
2498 fplotter->text(fplotter, x, y, text, length, &newstyle);
2499 } else {
2500 fplotter->text(fplotter, x, y, text, length, fstyle);
2501 }
2502
2503 return NSERROR_OK;
2504}
2505
2506/** atari plottr operation table */
2509 .line = plot_line,
2510 .polygon = plot_polygon,
2511 .clip = plot_clip,
2512 .text = plot_text,
2513 .disc = plot_disc,
2514 .arc = plot_arc,
2515 .bitmap = plot_bitmap,
2516 .path = plot_path,
2517 .flush = NULL,
2518 .group_start = NULL,
2519 .group_end = NULL,
2520 .option_knockout = true
2521};
void die(const char *error)
Cause an abnormal program termination.
Definition: misc.c:69
static nserror plot_path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:2350
struct s_vdi_sysinfo vdi_sysinfo
Definition: plot.c:196
static bool ablend_bitmap(struct bitmap *img, struct bitmap *bg, GRECT *img_clip, GRECT *bg_clip)
Aplha blends the foreground image onto thebackground images.
Definition: plot.c:984
static void vsf_rgbcolor(short vdih, colour cin)
Set fill color by passing netsurf XBGR "colour" type.
Definition: plot.c:255
static nserror plot_clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:1974
static struct s_view view
Definition: plot.c:199
bool plot_blit_mfdb(GRECT *loc, MFDB *insrc, short fgcolor, uint32_t flags)
Definition: plot.c:1551
static void update_visible_rect(void)
Definition: plot.c:295
static nserror plot_text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plot.c:2488
const struct plotter_table atari_plotters
atari plottr operation table
Definition: plot.c:2507
static nserror plot_bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plot.c:2386
static nserror plot_rectangle(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *rect)
Plots a rectangle.
Definition: plot.c:2180
static int size_buf_packed
Definition: plot.c:171
static void snapshot_destroy(void)
destroy memory used by screenshot
Definition: plot.c:922
unsigned long atari_plot_flags
Definition: plot.c:209
static void * buf_packed
Definition: plot.c:170
static nserror plot_disc(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius)
Plots a circle.
Definition: plot.c:2090
static HermesHandle hermes_cnv_h
Definition: plot.c:202
void plot_get_abs_clipping(struct rect *dst)
Get the maximum clip extent, in absolute screen coords.
Definition: plot.c:1899
bool plot_blit_bitmap(struct bitmap *bmp, int x, int y, unsigned long bg, unsigned long flags)
Definition: plot.c:1482
void plot_set_text_plotter(FONT_PLOTTER font_plotter)
Definition: plot.c:1959
static const char * plot_error_codes[]
Definition: plot.c:158
static void plot_get_visible_grect(GRECT *out)
Get current visible coords.
Definition: plot.c:279
MFDB buf_std
Definition: plot.c:183
short vdih
static void read_vdi_sysinfo(short vdih, struct s_vdi_sysinfo *info)
Fill the screen info structure.
Definition: plot.c:432
static void convert_bitmap_done(void)
Definition: plot.c:1468
float plot_get_scale(void)
Definition: plot.c:1864
static void vsl_rgbcolor(short vdih, colour cin)
Set line drawing color by passing netsurf XBGR "colour" type.
Definition: plot.c:228
void rgb_to_vdi1000(unsigned char *in, RGB1000 *out)
Convert an RGB color to an VDI Color.
Definition: plot.c:564
static bool fbrect_to_screen(GRECT box, GRECT *ret)
Returns the visible parts of the box.
Definition: plot.c:335
bool plot_lock(void)
Definition: plot.c:1775
long plot_get_flags(void)
Definition: plot.c:1924
bool plot_get_clip(struct rect *out)
Definition: plot.c:1930
const char * plot_err_str(int i)
translate an error number
Definition: plot.c:216
static int atari_plot_bpp_virt
Definition: plot.c:198
static HermesFormat vfmt
Definition: plot.c:189
void vdi1000_to_rgb(unsigned short *in, unsigned char *out)
Definition: plot.c:576
float plot_set_scale(float scale)
set scale of plotter.
Definition: plot.c:1854
static int size_buf_scr
Definition: plot.c:180
VdiHdl plot_get_vdi_handle(void)
Definition: plot.c:1918
void plot_get_clip_grect(GRECT *out)
Get clipping for current framebuffer as GRECT.
Definition: plot.c:1940
static struct bitmap snapshot
Definition: plot.c:206
bool plot_copy_rect(GRECT src, GRECT dst)
copy an rectangle from the plot buffer to screen
Definition: plot.c:374
void plot_set_abs_clipping(const GRECT *area)
Subsequent calls to plot_clip will be clipped by the absolute clip.
Definition: plot.c:1875
FONT_PLOTTER plot_get_text_plotter()
Definition: plot.c:1953
static bitmap_convert_fnc bitmap_convert
Definition: plot.c:213
static bool ablend_pixel(struct bitmap *img, uint32_t bg, GRECT *clip)
Alpha blends an image, using one pixel as the background.
Definition: plot.c:961
bool plot_set_dimensions(const struct redraw_context *ctx, int x, int y, int w, int h)
Set plot origin and canvas size.
Definition: plot.c:1806
static struct bitmap * snapshot_create(int x, int y, int w, int h)
Create an snapshot of the screen in netsurf ABGR format.
Definition: plot.c:803
static nserror plot_line(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *line)
Plots a line.
Definition: plot.c:2121
VdiHdl atari_plot_vdi_handle
Definition: plot.c:208
static void snapshot_suspend(void)
Garbage collection of the snapshot routine.
Definition: plot.c:877
static nserror plot_polygon(const struct redraw_context *ctx, const plot_style_t *pstyle, const int *p, unsigned int n)
Plot a polygon.
Definition: plot.c:2304
static MFDB * snapshot_create_native_mfdb(int x, int y, int w, int h)
Create an snapshot of the screen image in device format.
Definition: plot.c:742
void * buf_planar
Definition: plot.c:174
static MFDB buf_scr
Definition: plot.c:179
unsigned long atari_font_flags
Definition: plot.c:210
int size_buf_planar
Definition: plot.c:175
static HermesHandle hermes_res_h
Definition: plot.c:203
void vq_scrninfo(VdiHdl handle, short *work_out)
static void dump_vdi_info(short vdih)
Definition: plot.c:710
static uint32_t ablend(uint32_t pixel, uint32_t scrpixel)
Definition: plot.c:940
static HermesFormat nsfmt
Definition: plot.c:194
static nserror plot_arc(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius, int angle1, int angle2)
Plots an arc.
Definition: plot.c:2043
void plot_get_abs_clipping_grect(GRECT *dst)
Get the maximum clip extent, in absolute screen coords.
Definition: plot.c:1909
static bool bitmap_convert_tc(struct bitmap *img, int x, int y, GRECT *clip, uint32_t bg, uint32_t flags, MFDB *out)
Convert bitmap to the native screen format.
Definition: plot.c:1308
bool plot_get_dimensions(GRECT *dst)
Get current canvas size.
Definition: plot.c:1838
FONT_PLOTTER fplotter
Definition: plot.c:165
int plot_finalise(void)
Definition: plot.c:1748
int plot_init(const struct redraw_context *ctx, char *fdrvrname)
Init screen and font driver objects.
Definition: plot.c:1612
int size_buf_std
Definition: plot.c:184
struct bitmap * buf_scr_compat
Definition: plot.c:186
bool(* bitmap_convert_fnc)(struct bitmap *img, int x, int y, GRECT *clip, uint32_t bg, uint32_t flags, MFDB *out)
Definition: plot.c:212
bool plot_unlock(void)
Definition: plot.c:1791
#define FONTPLOT_FLAG_MONOGLYPH
Definition: plot.h:41
#define BITMAPF_MONOGLYPH
The bitmap is an character bitmap.
Definition: plot.h:49
#define NSLT2VDI(dst, src)
Definition: plot.h:143
#define PLOT_FLAG_TRANS
set if the plotter supports transparent operations
Definition: plot.h:30
#define ERR_NO_MEM
Definition: plot.h:54
#define OFFSET_CUSTOM_COLOR
Definition: plot.h:175
short rgb_to_666_index(unsigned char r, unsigned char g, unsigned char b)
#define CONV_BLOCK_SIZE
how much memory to allocate if some is needed:
Definition: plot.h:26
#define CONV_KEEP_LIMIT
how much memory should be kept allocated for temp.
Definition: plot.h:23
#define PLOT_FLAG_LOCKED
plotter should set this flag during screen updates
Definition: plot.h:38
#define BITMAPF_BUFFER_NATIVE
Bitmap shall be kept converted
Definition: plot.h:50
#define PLOT_FLAG_DITHER
set if the plotter shall dither images
Definition: plot.h:29
unsigned long EdDI_version(void *function_pointer)
#define EDDI_11
Definition: eddi.h:31
@ VDI_FORMAT_PACK
Definition: eddi.h:39
@ VDI_FORMAT_INTER
Definition: eddi.h:37
@ VDI_CLUT_HARDWARE
Definition: eddi.h:45
@ VDI_CLUT_SOFTWARE
Definition: eddi.h:46
@ VDI_CLUT_NONE
Definition: eddi.h:44
#define EDDI_10
Definition: eddi.h:30
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
void dump_font_drivers(void)
Definition: fontplot.c:44
FONT_PLOTTER new_font_plotter(int vdihandle, char *name, unsigned long flags, int *error)
Create an new text plotter object.
Definition: fontplot.c:67
int delete_font_plotter(FONT_PLOTTER p)
Definition: fontplot.c:121
bool atari_bitmap_resize(struct bitmap *img, HermesHandle hermes_h, HermesFormat *fmt, int nw, int nh)
Definition: bitmap.c:313
size_t atari_bitmap_buffer_size(void *bitmap)
Definition: bitmap.c:208
size_t atari_bitmap_get_rowstride(void *bitmap)
Find the width of a pixel row in bytes.
Definition: bitmap.c:218
bool atari_bitmap_get_opaque(void *bitmap)
Gets whether a bitmap should be plotted opaque.
Definition: bitmap.c:273
void atari_bitmap_destroy(void *bitmap)
Free a bitmap.
Definition: bitmap.c:231
void * atari_bitmap_create(int w, int h, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.c:121
int init_mfdb(int bpp, int w, int h, uint32_t flags, MFDB *out)
setup an MFDB struct and allocate memory for it when it is needed.
Definition: bitmap.c:41
int atari_bitmap_get_height(void *bitmap)
Get bitmap height.
Definition: bitmap.c:301
int atari_bitmap_get_width(void *bitmap)
Get bitmap width.
Definition: bitmap.c:287
void * atari_bitmap_realloc(int w, int h, short bpp, int rowstride, unsigned int state, void *bmp)
Definition: bitmap.c:149
Atari bitmap handling implementation.
#define BITMAP_SHRINK
Definition: bitmap.h:37
#define BITMAP_GROW
Definition: bitmap.h:38
#define MFDB_STRIDE(w)
Calculates MFDB compatible rowstride (in number of bits)
Definition: bitmap.h:45
Generic bitmap handling interface.
Core mouse and pointer states.
Target independent plotting interface.
#define BITMAPF_REPEAT_X
Definition: plotters.h:38
#define BITMAPF_REPEAT_Y
Definition: plotters.h:39
unsigned long bitmap_flags_t
Definition: plotters.h:36
bool verbose_log
flag to enable verbose logging
Definition: log.c:31
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
int tos_getcookie(long tag, long *value)
Definition: osspec.c:76
#define plot_style_fixed_to_int(v)
Definition: plot_style.h:54
@ PLOT_OP_TYPE_NONE
No operation.
Definition: plot_style.h:66
@ PLOT_OP_TYPE_SOLID
Solid colour.
Definition: plot_style.h:67
int width
Definition: gui.c:159
int height
Definition: gui.c:160
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
int native
Definition: bitmap.c:75
int width
width of bitmap
Definition: bitmap.c:69
struct bitmap * resized
Definition: bitmap.h:66
int height
height of bitmap
Definition: bitmap.c:70
bool opaque
Whether the bitmap is opaque.
Definition: bitmap.c:74
UBYTE * pixdata
Definition: bitmap.c:71
short bpp
Definition: bitmap.h:64
size_t rowstride
Definition: bitmap.h:65
bool converted
Definition: bitmap.h:68
Node in box tree.
Definition: box.h:177
Font style for plotting.
Definition: plot_style.h:111
plot_style_fixed size
Font size, in pt.
Definition: plot_style.h:119
Plot style for stroke/fill plotters.
Definition: plot_style.h:76
colour fill_colour
Colour of fill.
Definition: plot_style.h:81
plot_style_fixed stroke_width
Width of stroke, in pixels.
Definition: plot_style.h:78
plot_operation_type_t fill_type
Fill plot type.
Definition: plot_style.h:80
colour stroke_colour
Colour of stroke.
Definition: plot_style.h:79
plot_operation_type_t stroke_type
Stroke plot type.
Definition: plot_style.h:77
Plotter operations table.
Definition: plotters.h:102
nserror(* rectangle)(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *rectangle)
Plots a rectangle.
Definition: plotters.h:188
nserror(* clip)(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plotters.h:111
Rectangle coordinates.
Definition: types.h:40
int x0
Definition: types.h:41
int y0
Top left.
Definition: types.h:41
int x1
Definition: types.h:42
int y1
Bottom right.
Definition: types.h:42
Redraw context.
Definition: plotters.h:51
const struct plotter_table * plot
Current plot operation table.
Definition: plotters.h:73
_fpmf_text text
Definition: fontplot.h:59
bool rasterscale
Definition: plot.h:80
void * screen
pointer to screen, or NULL
Definition: plot.h:71
short scr_h
resolution vert.
Definition: plot.h:63
unsigned long screensize
size of screen (in bytes)
Definition: plot.h:72
short pixelsize
bytes per pixel
Definition: plot.h:67
unsigned long hicolors
if colors = 0
Definition: plot.h:66
unsigned long mask_b
blue color mask
Definition: plot.h:75
int colors
0=hiclor, 2=mono
Definition: plot.h:65
short vdi_handle
vdi handle
Definition: plot.h:61
short scr_bpp
bits per pixel
Definition: plot.h:64
unsigned short pitch
row pitch
Definition: plot.h:68
short maxintin
Definition: plot.h:77
unsigned long mask_a
alpha color mask
Definition: plot.h:76
short maxpolycoords
Definition: plot.h:78
unsigned long EdDiVersion
Definition: plot.h:79
unsigned short clut
type of clut support
Definition: plot.h:70
unsigned short vdiformat
pixel format
Definition: plot.h:69
unsigned long mask_g
green color mask
Definition: plot.h:74
short scr_w
resolution horz.
Definition: plot.h:62
unsigned long mask_r
red color mask
Definition: plot.h:73
Definition: plot.c:47
short x
drawing (screen) offset x
Definition: plot.c:48
short vis_h
visible width
Definition: plot.c:55
struct rect abs_clipping
The toplevel clipping rectangle
Definition: plot.c:56
float scale
Definition: plot.c:58
short vis_y
coords are relative to plot location
Definition: plot.c:53
struct rect clipping
actual clipping rectangle
Definition: plot.c:57
short vis_w
clipped to screen dimensions
Definition: plot.c:54
short y
drawing (screen) offset y
Definition: plot.c:49
short vis_x
visible rectangle of the screen buffer
Definition: plot.c:52
short h
height of buffer, not in sync with vis_w
Definition: plot.c:51
short w
width of buffer, not in sync with vis_w
Definition: plot.c:50
uint32_t colour
Colour type: XBGR.
Definition: types.h:35
#define common
Definition: ucstables.c:40
Option reading and saving interface.
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:279
UTF-8 manipulation functions (interface).
Interface to a number of general purpose functionality.
static nserror bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plot.c:857
static nserror line(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *line)
Plots a line.
Definition: plot.c:579
static nserror text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plot.c:978
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357