1 /**
2 * painter utils
3 *
4 * Copyright 2015-2016 Jay Sorg <jay.sorg@gmail.com>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #if defined(HAVE_CONFIG_H)
20 #include <config_ac.h>
21 #endif
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "painter.h"
28 #include "painter_utils.h"
29
30 /*****************************************************************************/
31 /* do a raster op */
32 int
do_rop(int rop,int src,int dst)33 do_rop(int rop, int src, int dst)
34 {
35 switch (rop)
36 {
37 case PT_ROP_0: return 0;
38 case PT_ROP_DSon: return ~(src | dst);
39 case PT_ROP_DSna: return (~src) & dst;
40 case PT_ROP_Sn: return ~src;
41 case PT_ROP_SDna: return src & (~dst);
42 case PT_ROP_Dn: return ~(dst);
43 case PT_ROP_DSx: return src ^ dst;
44 case PT_ROP_DSan: return ~(src & dst);
45 case PT_ROP_DSa: return src & dst;
46 case PT_ROP_DSxn: return ~(src) ^ dst;
47 case PT_ROP_D: return dst;
48 case PT_ROP_DSno: return (~src) | dst;
49 case PT_ROP_S: return src;
50 case PT_ROP_SDno: return src | (~dst);
51 case PT_ROP_DSo: return src | dst;
52 case PT_ROP_1: return ~0;
53 }
54 return dst;
55 }
56
57 /*****************************************************************************/
58 char *
bitmap_get_ptr(struct painter_bitmap * bitmap,int x,int y)59 bitmap_get_ptr(struct painter_bitmap *bitmap, int x, int y)
60 {
61 char *p;
62 int bpp;
63 int Bpp;
64
65 if ((x >= 0) && (x < bitmap->width) &&
66 (y >= 0) && (y < bitmap->height))
67 {
68 bpp = bitmap->format >> 24;
69 if (bpp < 8)
70 {
71 p = bitmap->data + (y * bitmap->stride_bytes) + (x / 8);
72 return p;
73 }
74 else
75 {
76 Bpp = (bpp + 7) / 8;
77 p = bitmap->data + (y * bitmap->stride_bytes) + (x * Bpp);
78 return p;
79 }
80 }
81 else
82 {
83 return NULL;
84 }
85 }
86
87 /*****************************************************************************/
88 int
bitmap_get_pixel(struct painter_bitmap * bitmap,int x,int y)89 bitmap_get_pixel(struct painter_bitmap *bitmap, int x, int y)
90 {
91 char *ptr;
92 int rv;
93
94 ptr = bitmap_get_ptr(bitmap, x, y);
95 if (ptr == NULL)
96 {
97 return 0;
98 }
99 switch (bitmap->format)
100 {
101 case PT_FORMAT_c1:
102 rv = *((unsigned char *) ptr);
103 rv = (rv & (0x80 >> (x % 8))) != 0;
104 return rv;
105 case PT_FORMAT_c8:
106 return *((unsigned char *) ptr);
107 case PT_FORMAT_r3g3b2:
108 return *((unsigned char *) ptr);
109 case PT_FORMAT_a1r5g5b5:
110 return *((unsigned short *) ptr);
111 case PT_FORMAT_r5g6b5:
112 return *((unsigned short *) ptr);
113 case PT_FORMAT_a8r8g8b8:
114 return *((unsigned int *) ptr);
115 case PT_FORMAT_a8b8g8r8:
116 return *((unsigned int *) ptr);
117 }
118 return 0;
119 }
120
121 /*****************************************************************************/
122 int
bitmap_set_pixel(struct painter_bitmap * bitmap,int x,int y,int pixel)123 bitmap_set_pixel(struct painter_bitmap *bitmap, int x, int y, int pixel)
124 {
125 char *ptr;
126
127 ptr = bitmap_get_ptr(bitmap, x, y);
128 if (ptr == NULL)
129 {
130 return 0;
131 }
132 switch (bitmap->format)
133 {
134 case PT_FORMAT_r3g3b2:
135 *((unsigned char *) ptr) = pixel;
136 break;
137 case PT_FORMAT_a1r5g5b5:
138 *((unsigned short *) ptr) = pixel;
139 break;
140 case PT_FORMAT_r5g6b5:
141 *((unsigned short *) ptr) = pixel;
142 break;
143 case PT_FORMAT_a8r8g8b8:
144 *((unsigned int *) ptr) = pixel;
145 break;
146 case PT_FORMAT_a8b8g8r8:
147 *((unsigned int *) ptr) = pixel;
148 break;
149 }
150 return 0;
151 }
152
153 /*****************************************************************************/
154 int
pixel_convert(int pixel,int src_format,int dst_format,int * palette)155 pixel_convert(int pixel, int src_format, int dst_format, int *palette)
156 {
157 int a;
158 int r;
159 int g;
160 int b;
161 int rv;
162
163 if (src_format == dst_format)
164 {
165 return pixel;
166 }
167 a = 0;
168 r = 0;
169 g = 0;
170 b = 0;
171 switch (src_format)
172 {
173 case PT_FORMAT_r3g3b2:
174 SPLIT_r3g3b2(pixel, a, r, g, b);
175 break;
176 case PT_FORMAT_a1r5g5b5:
177 SPLIT_a1r5g5b5(pixel, a, r, g, b);
178 break;
179 case PT_FORMAT_r5g6b5:
180 SPLIT_r5g6b5(pixel, a, r, g, b);
181 break;
182 case PT_FORMAT_a8r8g8b8:
183 SPLIT_a8r8g8b8(pixel, a, r, g, b);
184 break;
185 case PT_FORMAT_a8b8g8r8:
186 SPLIT_a8b8g8r8(pixel, a, r, g, b);
187 break;
188 }
189 rv = 0;
190 switch (dst_format)
191 {
192 case PT_FORMAT_a1r5g5b5:
193 MAKE_a1r5g5b5(rv, a, r, g, b);
194 break;
195 case PT_FORMAT_r5g6b5:
196 MAKE_r5g6b5(rv, a, r, g, b);
197 break;
198 case PT_FORMAT_a8r8g8b8:
199 MAKE_a8r8g8b8(rv, a, r, g, b);
200 break;
201 case PT_FORMAT_a8b8g8r8:
202 MAKE_a8b8g8r8(rv, a, r, g, b);
203 break;
204 }
205 return rv;
206 }
207
208 /*****************************************************************************/
209 int
painter_get_pixel(struct painter * painter,struct painter_bitmap * bitmap,int x,int y)210 painter_get_pixel(struct painter *painter, struct painter_bitmap *bitmap,
211 int x, int y)
212 {
213 int rv;
214
215 rv = 0;
216 if ((x >= 0) && (x < bitmap->width) && (y >= 0) && (y < bitmap->height))
217 {
218 switch (bitmap->format)
219 {
220 case PT_FORMAT_c1:
221 rv = bitmap_get_pixel(bitmap, x, y);
222 rv = rv ? painter->fgcolor : painter->bgcolor;
223 break;
224 case PT_FORMAT_c8:
225 rv = bitmap_get_pixel(bitmap, x, y);
226 rv = painter->palette[rv & 0xff];
227 break;
228 default:
229 rv = bitmap_get_pixel(bitmap, x, y);
230 break;
231 }
232 }
233 return rv;
234 }
235
236 /*****************************************************************************/
237 int
painter_set_pixel(struct painter * painter,struct painter_bitmap * bitmap,int x,int y,int pixel,int pixel_format)238 painter_set_pixel(struct painter *painter, struct painter_bitmap *bitmap,
239 int x, int y, int pixel, int pixel_format)
240 {
241 if ((painter->clip_valid == 0) ||
242 ((x >= painter->clip.x1) && (x < painter->clip.x2) &&
243 (y >= painter->clip.y1) && (y < painter->clip.y2)))
244 {
245 if ((x >= 0) && (x < bitmap->width) &&
246 (y >= 0) && (y < bitmap->height))
247 {
248 pixel = pixel_convert(pixel, pixel_format, bitmap->format,
249 painter->palette);
250 if (painter->rop != PT_ROP_S)
251 {
252 pixel = do_rop(painter->rop, pixel,
253 bitmap_get_pixel(bitmap, x, y));
254 }
255 bitmap_set_pixel(bitmap, x, y, pixel);
256 }
257 }
258 return 0;
259 }
260
261 /*****************************************************************************/
262 /* return true if there is something to draw */
263 int
painter_warp_coords(struct painter * painter,int * x,int * y,int * cx,int * cy,int * srcx,int * srcy)264 painter_warp_coords(struct painter *painter,
265 int *x, int *y, int *cx, int *cy,
266 int *srcx, int *srcy)
267 {
268 int dx;
269 int dy;
270 int lx;
271 int ly;
272 int lcx;
273 int lcy;
274
275 lx = *x;
276 ly = *y;
277 lcx = *cx;
278 lcy = *cy;
279 dx = 0;
280 dy = 0;
281 if (painter->clip_valid)
282 {
283 if (painter->clip.x1 > lx)
284 {
285 dx = painter->clip.x1 - lx;
286 }
287 if (painter->clip.y1 > ly)
288 {
289 dy = painter->clip.y1 - ly;
290 }
291 if (lx + lcx > painter->clip.x2)
292 {
293 lcx = (lcx - ((lx + lcx) - painter->clip.x2));
294 }
295 if (*y + lcy > painter->clip.y2)
296 {
297 lcy = (lcy - ((ly + lcy) - painter->clip.y2));
298 }
299 }
300 lcx = lcx - dx;
301 lcy = lcy - dy;
302 if (lcx <= 0)
303 {
304 return 0;
305 }
306 if (lcy <= 0)
307 {
308 return 0;
309 }
310 lx = lx + dx;
311 ly = ly + dy;
312 if (srcx != 0)
313 {
314 *srcx = *srcx + dx;
315 }
316 if (srcy != 0)
317 {
318 *srcy = *srcy + dy;
319 }
320 *x = lx;
321 *y = ly;
322 *cx = lcx;
323 *cy = lcy;
324 return 1;
325 }
326
327