Fri, 28 Dec 2001 04:44:15 +0000
added bitblt stuff, parser, and scanner.
1 #include <stdlib.h>
3 #include "bitblt.h"
5 static inline u8 pixel_mask (x)
6 {
7 #ifdef LSB_LEFT
8 return (1 << x);
9 #else
10 return (1 << (7 - x));
11 #endif
12 }
14 static inline u32 rect_width (Rect r)
15 {
16 return (r.lower_right.x - r.upper_left.x);
17 }
19 static inline u32 rect_height (Rect r)
20 {
21 return (r.lower_right.y - r.upper_left.y);
22 }
24 Bitmap *create_bitmap (u32 width, u32 height)
25 {
26 Bitmap *bitmap;
28 bitmap = calloc (1, sizeof (Bitmap));
29 if (! bitmap)
30 return (NULL);
31 bitmap->width = width;
32 bitmap->height = height;
33 bitmap->rowbytes = (width - 1) / 8 + 1;
34 bitmap->bits = calloc (height * bitmap->rowbytes, 1);
35 if (! bitmap->bits)
36 {
37 free (bitmap);
38 return (NULL);
39 }
40 return (bitmap);
41 }
43 void free_bitmap (Bitmap *bitmap)
44 {
45 free (bitmap->bits);
46 free (bitmap);
47 }
49 boolean get_pixel (Bitmap *bitmap, Point coord)
50 {
51 u8 *p;
52 if ((coord.x >= bitmap->width) || (coord.y >= bitmap->height))
53 return (0);
54 p = bitmap->bits + coord.y * bitmap->rowbytes + coord.x / 8;
55 return ((*p & pixel_mask (coord.x & 7)) != 0);
56 }
58 void set_pixel (Bitmap *bitmap, Point coord, boolean value)
59 {
60 u8 *p;
61 if ((coord.x >= bitmap->width) || (coord.y >= bitmap->height))
62 return;
63 p = bitmap->bits + coord.y * bitmap->rowbytes + coord.x / 8;
64 if (value)
65 *p |= pixel_mask (coord.x & 7);
66 else
67 *p &= (0xff ^ pixel_mask (coord.x & 7));
68 }
71 Bitmap *bitblt (Bitmap *src_bitmap,
72 Rect src_rect,
73 Bitmap *dest_bitmap,
74 Point dest_upper_left,
75 int scan,
76 int tfn)
77 {
78 Point src_point, dest_point;
79 boolean src_pixel, dest_pixel;
81 if (! dest_bitmap)
82 {
83 if (scan & TRANSPOSE)
84 dest_bitmap = create_bitmap (dest_upper_left.x + rect_height (src_rect),
85 dest_upper_left.y + rect_width (src_rect));
86 else
87 dest_bitmap = create_bitmap (dest_upper_left.x + rect_width (src_rect),
88 dest_upper_left.y + rect_height (src_rect));
89 if (! dest_bitmap)
90 return (NULL);
91 }
93 for (src_point.y = src_rect.upper_left.y;
94 src_point.y < src_rect.lower_right.y;
95 src_point.y++)
96 {
97 for (src_point.x = src_rect.upper_left.x;
98 src_point.x < src_rect.lower_right.x;
99 src_point.x++)
100 {
101 boolean a, b, c;
103 if (scan & TRANSPOSE)
104 {
105 dest_point.x = src_point.y - src_rect.upper_left.y;
106 dest_point.y = src_point.x - src_rect.upper_left.x;
108 if (scan & FLIP_H)
109 dest_point.x = (rect_height (src_rect) - 1) - dest_point.x;
111 if (scan & FLIP_V)
112 dest_point.y = (rect_width (src_rect) - 1) - dest_point.y;
113 }
114 else
115 {
116 dest_point.x = src_point.x - src_rect.upper_left.x;
117 dest_point.y = src_point.y - src_rect.upper_left.y;
119 if (scan & FLIP_H)
120 dest_point.x = (rect_width (src_rect) - 1) - dest_point.x;
122 if (scan & FLIP_V)
123 dest_point.y = (rect_height (src_rect) - 1) - dest_point.y;
124 }
126 dest_point.x += dest_upper_left.x;
127 dest_point.y += dest_upper_left.y;
129 a = get_pixel (src_bitmap, src_point);
130 b = get_pixel (dest_bitmap, dest_point);
131 c = (tfn & (1 << (a * 2 + b))) != 0;
133 set_pixel (dest_bitmap, dest_point, c);
134 }
135 }
136 return (dest_bitmap);
137 }