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