1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program 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 /*
20  * $Source: r:/prj/lib/src/2d/RCS/canvas.c $
21  * $Revision: 1.21 $
22  * $Author: kevin $
23  * $Date: 1994/11/28 21:17:01 $
24  *
25  * Canvas handling routines.
26  *
27  */
28 
29 #include "grs.h"
30 #include "bitmap.h"
31 #include "chain.h"
32 #include "cnvdat.h"
33 #include "cnvtab.h"
34 #include "context.h"
35 #include "ctxmac.h"
36 #include "fcntab.h"
37 #include "lintab.h"
38 #include "tabdat.h"
39 #include "valloc.h"
40 
41 #include <stdio.h> // printf()
42 
43 #define CANVAS_STACKSIZE 16
44 grs_canvas *grd_canvas_stack[CANVAS_STACKSIZE];
45 int grd_canvas_stackp = 0;
46 
47 /* set current canvas to c. select driver_func from type of bitmap
48    attached to canvas. */
gr_set_canvas(grs_canvas * c)49 void gr_set_canvas (grs_canvas *c)
50 {
51    int i;
52 
53    if (c == NULL)
54       return;
55 
56    grd_canvas = c;
57    if (gr_generic)
58       i = BMT_GEN;
59    else
60       i = c->bm.type;
61 
62    grd_pixel_index = c->bm.type;
63    grd_canvas_index = i;
64    grd_pixel_table = grd_canvas_table_list[grd_pixel_index];
65    grd_canvas_table = grd_canvas_table_list[i];
66 
67    grd_uline_fill_table = grd_uline_fill_table_list[c->bm.type];
68    grd_uline_fill_vector = (*grd_uline_fill_table)[c->gc.fill_type];
69    grd_function_fill_table = grd_function_table_list[i];
70    grd_function_table = (*grd_function_fill_table)[c->gc.fill_type];
71 }
72 
73 /* push current canvas onto canvas stack and make passed in canvas active.
74    returns 0 if stack is ok, -1 if there is an overflow. */
gr_push_canvas(grs_canvas * c)75 int gr_push_canvas (grs_canvas *c)
76 {
77    if (grd_canvas_stackp >= CANVAS_STACKSIZE)
78       return -1;
79    grd_canvas_stack[grd_canvas_stackp++] = grd_canvas;
80    gr_set_canvas (c);
81    return 0;
82 }
83 
84 /* pop last canvas off of stack and make it active.  return it, or NULL if
85    there is an underflow. */
gr_pop_canvas(void)86 grs_canvas *gr_pop_canvas (void)
87 {
88    grs_canvas *c;
89    if (grd_canvas_stackp <= 0)
90       return NULL;
91    c = grd_canvas_stack[--grd_canvas_stackp];
92    gr_set_canvas (c);
93    return c;
94 }
95 
96 #pragma scheduling off
97 #pragma global_optimizer off
98 
gr_init_canvas(grs_canvas * c,uchar * p,int type,short w,short h)99 void gr_init_canvas (grs_canvas *c, uchar *p, int type, short w, short h)
100 {
101 #ifdef GR_DOUBLE_CANVAS
102    if (type==BMT_FLAT8_DOUBLE) {
103       gr_init_bm (&c->bm, p, BMT_FLAT8, 0, w, h);
104       gr_init_gc (c);
105       gr_cset_fix_cliprect (c, 0, 0, fix_make ((w>>1),0), fix_make (h,0));
106       c->bm.type=BMT_FLAT8_DOUBLE;
107    } else
108 #endif
109    {
110       gr_init_bm (&c->bm, p, type, 0, w, h);
111       gr_init_gc (c);
112       gr_cset_fix_cliprect (c, 0, 0, fix_make (w,0), fix_make (h,0));
113    }
114    c->ytab = NULL;
115 }
116 
117 #pragma scheduling reset
118 #pragma global_optimizer reset
119 
gr_init_sub_canvas(grs_canvas * sc,grs_canvas * dc,short x,short y,short w,short h)120 void gr_init_sub_canvas (grs_canvas *sc, grs_canvas *dc, short x, short y,
121                          short w, short h)
122 {
123    gr_init_sub_bm (&sc->bm, &dc->bm, x, y, w, h);
124    gr_init_gc (dc);
125    gr_cset_fix_cliprect (dc, 0, 0, fix_make (w,0), fix_make (h,0));
126    dc->ytab = NULL;
127 }
128 
gr_make_canvas(grs_bitmap * bm,grs_canvas * c)129 void gr_make_canvas (grs_bitmap *bm, grs_canvas *c)
130 {
131    gr_init_canvas (c, bm->bits, bm->type, bm->w, bm->h);
132 }
133 
gr_alloc_canvas(int type,short w,short h)134 grs_canvas *gr_alloc_canvas (int type, short w, short h)
135 {
136    grs_canvas *c;
137    uchar *p;
138 
139    if ((c=(grs_canvas *)malloc (sizeof (*c))) == NULL)	// was Malloc
140       return NULL;
141    if (type == BMT_DEVICE)
142       p = our_valloc (w,h);
143    else
144       p = (uchar *)malloc (w*h);// was Malloc
145    gr_init_canvas (c, p, type, w, h);
146 
147    return c;
148 }
149 
gr_free_canvas(grs_canvas * c)150 void gr_free_canvas (grs_canvas *c)
151 {
152    printf("Free canvas");
153    if (c->bm.type == BMT_DEVICE)
154       vfree (c->bm.bits);
155    else
156       free( c->bm.bits);	// was gr_free
157    free( c);	// was gr_free
158 }
159 
gr_alloc_sub_canvas(grs_canvas * c,short x,short y,short w,short h)160 grs_canvas *gr_alloc_sub_canvas (grs_canvas *c, short x, short y,
161    short w, short h)
162 {
163    grs_canvas *c_new;
164 
165    c_new = (grs_canvas *)malloc (sizeof (*c_new));// was Malloc
166    if (c_new != NULL)
167       gr_init_sub_canvas (c, c_new, x, y, w, h);
168    return c_new;
169 }
170 
gr_free_sub_canvas(grs_canvas * c)171 void gr_free_sub_canvas (grs_canvas *c)
172 {
173    free( c);	// was gr_free
174 }
175