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.

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