Sun, 30 Dec 2001 04:16:46 +0000
..
1 #include <stdlib.h>
3 #include "type.h"
4 #include "bitblt.h"
6 static inline u8 pixel_mask (x)
7 {
8 #ifdef LSB_LEFT
9 return (1 << x);
10 #else
11 return (1 << (7 - x));
12 #endif
13 }
15 static inline u32 rect_width (Rect r)
16 {
17 return (r.lower_right.x - r.upper_left.x);
18 }
20 static inline u32 rect_height (Rect r)
21 {
22 return (r.lower_right.y - r.upper_left.y);
23 }
25 Bitmap *create_bitmap (u32 width, u32 height)
26 {
27 Bitmap *bitmap;
29 bitmap = calloc (1, sizeof (Bitmap));
30 if (! bitmap)
31 return (NULL);
32 bitmap->width = width;
33 bitmap->height = height;
34 bitmap->rowbytes = (width - 1) / 8 + 1;
35 bitmap->bits = calloc (height * bitmap->rowbytes, 1);
36 if (! bitmap->bits)
37 {
38 free (bitmap);
39 return (NULL);
40 }
41 return (bitmap);
42 }
44 void free_bitmap (Bitmap *bitmap)
45 {
46 free (bitmap->bits);
47 free (bitmap);
48 }
50 boolean get_pixel (Bitmap *bitmap, Point coord)
51 {
52 u8 *p;
53 if ((coord.x >= bitmap->width) || (coord.y >= bitmap->height))
54 return (0);
55 p = bitmap->bits + coord.y * bitmap->rowbytes + coord.x / 8;
56 return ((*p & pixel_mask (coord.x & 7)) != 0);
57 }
59 void set_pixel (Bitmap *bitmap, Point coord, boolean value)
60 {
61 u8 *p;
62 if ((coord.x >= bitmap->width) || (coord.y >= bitmap->height))
63 return;
64 p = bitmap->bits + coord.y * bitmap->rowbytes + coord.x / 8;
65 if (value)
66 *p |= pixel_mask (coord.x & 7);
67 else
68 *p &= (0xff ^ pixel_mask (coord.x & 7));
69 }
72 Bitmap *bitblt (Bitmap *src_bitmap,
73 Rect src_rect,
74 Bitmap *dest_bitmap,
75 Point dest_upper_left,
76 int scan,
77 int tfn)
78 {
79 Point src_point, dest_point;
80 boolean src_pixel, dest_pixel;
82 if (! dest_bitmap)
83 {
84 if (scan & TRANSPOSE)
85 dest_bitmap = create_bitmap (dest_upper_left.x + rect_height (src_rect),
86 dest_upper_left.y + rect_width (src_rect));
87 else
88 dest_bitmap = create_bitmap (dest_upper_left.x + rect_width (src_rect),
89 dest_upper_left.y + rect_height (src_rect));
90 if (! dest_bitmap)
91 return (NULL);
92 }
94 for (src_point.y = src_rect.upper_left.y;
95 src_point.y < src_rect.lower_right.y;
96 src_point.y++)
97 {
98 for (src_point.x = src_rect.upper_left.x;
99 src_point.x < src_rect.lower_right.x;
100 src_point.x++)
101 {
102 boolean a, b, c;
104 if (scan & TRANSPOSE)
105 {
106 dest_point.x = src_point.y - src_rect.upper_left.y;
107 dest_point.y = src_point.x - src_rect.upper_left.x;
109 if (scan & FLIP_H)
110 dest_point.x = (rect_height (src_rect) - 1) - dest_point.x;
112 if (scan & FLIP_V)
113 dest_point.y = (rect_width (src_rect) - 1) - dest_point.y;
114 }
115 else
116 {
117 dest_point.x = src_point.x - src_rect.upper_left.x;
118 dest_point.y = src_point.y - src_rect.upper_left.y;
120 if (scan & FLIP_H)
121 dest_point.x = (rect_width (src_rect) - 1) - dest_point.x;
123 if (scan & FLIP_V)
124 dest_point.y = (rect_height (src_rect) - 1) - dest_point.y;
125 }
127 dest_point.x += dest_upper_left.x;
128 dest_point.y += dest_upper_left.y;
130 a = get_pixel (src_bitmap, src_point);
131 b = get_pixel (dest_bitmap, dest_point);
132 c = (tfn & (1 << (a * 2 + b))) != 0;
134 set_pixel (dest_bitmap, dest_point, c);
135 }
136 }
137 return (dest_bitmap);
138 }