1 /* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
2 /* cbitmap.c    Compiled bitmaps */
3 
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <vga.h>
8 #include "inlstring.h"		/* include inline string operations */
9 
10 #include "vgagl.h"
11 #include "def.h"
12 
13 
14 
gl_compileboxmask(int w,int h,void * _dp1,void * _dp2)15 void gl_compileboxmask(int w, int h, void *_dp1, void *_dp2)
16 {
17 /* Compiled format: <bytes_to_skip (0-254)><number_of_pixels (0-255)> */
18 /*                  <pixel_data>[<end_of_line(255)>]... */
19     uchar *dp1 = _dp1;
20     uchar *dp2 = _dp2;
21     int i;
22     for (i = 0; i < h; i++) {
23 	int x = 0;
24 	while (x < w) {
25 	    int count;
26 	    /* count zeroes */
27 	    count = 0;
28 	    while (x < w && *(dp1 + count) == 0 && count < 254) {
29 		count++;
30 		x++;
31 	    }
32 	    dp1 += count;
33 	    if (x < w) {
34 		*dp2++ = count;
35 		/* count nonzeroes */
36 		count = 0;
37 		while (x < w && *(dp1 + count) != 0 && count < 255) {
38 		    *(dp2 + count + 1) = *(dp1 + count);
39 		    count++;
40 		    x++;
41 		}
42 		*dp2 = count;
43 		dp2 += count + 1;
44 		dp1 += count;
45 	    }
46 	}
47 	*dp2++ = 0xff;
48     }
49 }
50 
gl_compiledboxmasksize(int w,int h,void * _dp1)51 int gl_compiledboxmasksize(int w, int h, void *_dp1)
52 {
53 /* Compiled format: <bytes_to_skip (0-254)><number_of_pixels (0-255)> */
54 /*                  <pixel_data>[<end_of_line(255)>]... */
55     uchar *dp1 = _dp1;
56     int size = 0;
57     int i;
58     for (i = 0; i < h; i++) {
59 	int x = 0;
60 	while (x < w) {
61 	    int count;
62 	    /* count zeroes */
63 	    count = 0;
64 	    while (x < w && *(dp1 + count) == 0 && count < 254) {
65 		count++;
66 		x++;
67 	    }
68 	    size++;
69 	    dp1 += count;
70 	    /* count nonzeroes */
71 	    if (x < w) {
72 		count = 0;
73 		while (x < w && *(dp1 + count) != 0 && count < 255) {
74 		    count++;
75 		    x++;
76 		}
77 		size += count + 1;
78 		dp1 += count;
79 	    }
80 	}
81 	size++;
82     }
83     return size;
84 }
85 
gl_putboxmaskcompiledclip(int nx,int ny,int nw,int nh,int _x,int _y,int w,int h,void * _dp)86 static void gl_putboxmaskcompiledclip(int nx, int ny, int nw, int nh, int _x,
87 				      int _y, int w, int h, void *_dp)
88 {
89 /* Special case costly clipping */
90     uchar *dp = _dp;
91     uchar *vp, *vpline;
92     int y;
93     vpline = VBUF + _y * BYTEWIDTH + _x;
94     for (y = _y; y < ny + nh; y++) {
95 	int x = _x;
96 	vp = vpline;
97 	for (;;) {
98 	    int count = *dp++;
99 	    if (count == 0xff)
100 		break;		/* end of line */
101 	    vp += count;
102 	    x += count;
103 	    count = *dp++;
104 	    /* __memcpy gives severe bug here */
105 	    if (y >= ny) {
106 		if (x >= nx)
107 		    if (x + count > __clipx2 + 1) {
108 			if (x <= __clipx2)
109 			    __memcpyb(vp, dp, __clipx2 - x + 1);
110 		    } else
111 			__memcpyb(vp, dp, count);
112 		else if (x + count > __clipx1) {
113 		    if (x + count > __clipx2 + 1)
114 			__memcpyb(vp + __clipx1 - x,
115 				  dp + __clipx1 - x,
116 				  __clipx2 - __clipx1 + 1);
117 		    else
118 			__memcpy(vp + __clipx1 - x,
119 				 dp + __clipx1 - x,
120 				 count - __clipx1 + x);
121                 };
122             };
123 	    x += count;
124 	    vp += count;
125 	    dp += count;
126 	}
127 	vpline += BYTEWIDTH;
128     }
129 }
130 
131 #define ADJUSTBITMAPBOX() \
132 	nw = w; nh = h; nx = x; ny = y;				\
133 	if (nx + nw < __clipx1 || nx > __clipx2)		\
134 		return;						\
135 	if (ny + nh < __clipy1 || ny > __clipy2)		\
136 		return;						\
137 	if (nx < __clipx1) {		/* left adjust */	\
138 		nw += nx - __clipx1;				\
139 		nx = __clipx1;					\
140 	}							\
141 	if (ny < __clipy1) {		/* top adjust */	\
142 		nh += ny - __clipy1;				\
143 		ny = __clipy1;					\
144 	}							\
145 	if (nx + nw > __clipx2)		/* right adjust */	\
146 		nw = __clipx2 - nx + 1;				\
147 	if (ny + nh > __clipy2)		/* bottom adjust */	\
148 		nh = __clipy2 - ny + 1;				\
149 
150 
gl_putboxmaskcompiled(int x,int y,int w,int h,void * _dp)151 void gl_putboxmaskcompiled(int x, int y, int w, int h, void *_dp)
152 {
153 /* no clipping */
154     uchar *dp = _dp;
155     uchar *vp, *vpline;
156     int i;
157     if (MODETYPE != CONTEXT_LINEAR && MODETYPE != CONTEXT_VIRTUAL) {
158 	printf("vgagl: putboxmaskcompiled only supported in linear framebuffer\n");
159 	return;
160     }
161     if (__clip) {
162 	int nx, ny, nw, nh;
163 	ADJUSTBITMAPBOX();
164 	if (nw != w || nh != h) {
165 	    gl_putboxmaskcompiledclip(nx, ny, nw, nh, x, y, w, h,
166 				      dp);
167 	    return;
168 	}
169     }
170     vpline = VBUF + y * BYTEWIDTH + x;
171     for (i = 0; i < h; i++) {
172 	vp = vpline;
173 	for (;;) {
174 	    int count = *dp++;
175 	    if (count == 0xff)
176 		break;		/* end of line */
177 	    vp += count;
178 	    count = *dp++;
179 	    /* __memcpy gives severe bug here */
180 	    __memcpyb(vp, dp, count);
181 	    vp += count;
182 	    dp += count;
183 	}
184 	vpline += BYTEWIDTH;
185     }
186 }
187