bitblt.c

Wed, 02 Jan 2002 10:17:48 +0000

author
eric
date
Wed, 02 Jan 2002 10:17:48 +0000
changeset 35
41804cc569ab
parent 33
44d823824a46
child 42
9c85a4cd88a3
permissions
-rw-r--r--

use signed integers for coordinates.

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