Re: [AD] offscreen sub bitmaps revisited

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Fri, Jun 25, 2010 at 8:13 PM, Matthew Leverton <meffer@xxxxxxxxxx> wrote:
> So would _al_draw_bitmap_region_memory need to be updated to clip sub-bitmaps?
>
Attached is a half-implemented patch for memory bitmaps. Maybe there
is an easier way to implement this at a lower level...

The patch adds support for copying from an out-of-bounds sub-bitmap
into an in-bounds sub-bitmap. Test with ex_subbitmap.

Scaling works, but transformations do not. After taking a look at the
transformation code, I didn't even bother to try.

It also doesn't work with bitmap flipping, but that's already screwed
up (IMO) with sub-bitmaps as is.

--
Matthew Leverton
Index: src/bitmap.c
===================================================================
--- src/bitmap.c	(revision 13401)
+++ src/bitmap.c	(working copy)
@@ -616,24 +616,6 @@
 {
    ALLEGRO_BITMAP *bitmap;
 
-   /* Clip */
-   if (x < 0) {
-      w += x;
-      if (w < 0) w = 0;
-      x = 0;
-   }
-   if (y < 0) {
-      h += y;
-      if (h < 0) h = 0;
-      y = 0;
-   }
-   if (x+w > parent->w) {
-      w = parent->w - x;
-   }
-   if (y+h > parent->h) {
-      h = parent->h - y;
-   }
-
    if (parent->parent) {
       x += parent->xofs;
       y += parent->yofs;
Index: src/memblit.c
===================================================================
--- src/memblit.c	(revision 13401)
+++ src/memblit.c	(working copy)
@@ -166,8 +166,73 @@
 #define SRC_NOT_MODIFIED \
    src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && \
    tint.r == 1.0f && tint.g == 1.0f && tint.b == 1.0f && tint.a == 1.0f
+   
+#define HANDLE_SUB_BITMAPS(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, wr, hr) \
+   /* TODO: handle dest bitmaps that are out of bounds */                \
+   if (dest->parent) {                                                   \
+      dx += dest->xofs;                                                  \
+      dy += dest->yofs;                                                  \
+      dest = dest->parent;                                               \
+   }                                                                     \
+                                                                         \
+   if (bitmap->parent) {                                                 \
+      if (bitmap->xofs < 0) {                                            \
+         /* sub-bitmap origin is left of parent:                         \
+          *   shrink source width                                        \
+          *   move source to left edge, and dest x to the right          \
+          */                                                             \
+         sw += bitmap->xofs;                                             \
+         sx = 0;                                                         \
+         dx -= bitmap->xofs / wr;                                        \
+         dw += bitmap->xofs / wr;                                        \
+      }                                                                  \
+      else {                                                             \
+         sx += bitmap->xofs;                                             \
+         if (sx >= bitmap->parent->w) {                                  \
+         	  /* sub-bitmap origin begins to the right of parent:          \
+         	   *   nothing to do.                                          \
+         	   */                                                          \
+            return;                                                      \
+         }                                                               \
+      }                                                                  \
+                                                                         \
+      if (bitmap->yofs < 0) {                                            \
+         /* sub-bitmap origin is above parent:                           \
+          *   shrink source height                                       \
+          *   move source to top edge, and dest y down                   \
+          */                                                             \
+      	 sh += bitmap->yofs;                                             \
+         sy = 0;                                                         \
+         dy -= bitmap->yofs / hr;                                        \
+         dh += bitmap->yofs / hr;                                        \
+      }                                                                  \
+   		else {                                                             \
+   		   sy += bitmap->yofs;                                             \
+         if (sy >= bitmap->parent->h) {                                  \
+            /* sub-bitmap origin begins to the right of parent:          \
+             *   nothing to do.                                          \
+             */                                                          \
+   		       return;                                                     \
+   		   }                                                               \
+   		}                                                                  \
+                                                                         \
+   		bitmap = bitmap->parent;                                           \
+                                                                         \
+   		if (sx + sw > bitmap->w) {                                         \
+   			 dw -= (sx + sw - bitmap->w) / wr;                               \
+         sw = bitmap->w - sx;                                            \
+   		}                                                                  \
+                                                                         \
+   		if (sy + sh > bitmap->h) {                                         \
+   			 dh -= (sy + sh - bitmap->h) / hr;                               \
+         sh = bitmap->h - sy;                                            \
+   		}   		   		                                                     \
+                                                                         \
+   		if (sw <= 0 || sh <= 0) {                                          \
+   			return;                                                          \
+      }                                                                  \
+   }                                                                     \
 
-
 void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *bitmap,
    ALLEGRO_COLOR tint,
    int sx, int sy, int sw, int sh,
@@ -182,6 +247,7 @@
    int xinc, yinc;
    int yd;
    int sxd;
+   int dw, dh;
    
    if(!is_identity(al_get_current_transform()))
    {
@@ -228,19 +294,12 @@
       return;
    }
 
-   /* Handle sub bitmaps */
-   if (dest->parent) {
-      dx += dest->xofs;
-      dy += dest->yofs;
-      dest = dest->parent;
-   }
+	 dw = sw;
+	 dh = dh;
+	 
+	 HANDLE_SUB_BITMAPS(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1.0f, 1.0f)
+   
 
-   if (bitmap->parent) {
-      sx += bitmap->xofs;
-      sy += bitmap->yofs;
-      bitmap = bitmap->parent;
-   }
-
 #ifdef ALLEGRO_GP2XWIZ
    if (src_mode == ALLEGRO_ALPHA &&
 	 dst_mode == ALLEGRO_INVERSE_ALPHA &&
@@ -431,19 +490,8 @@
    if (dw == 0 || dh == 0)
       return;
 
-   /* Handle sub bitmaps */
-   if (dest->parent) {
-      dx += dest->xofs;
-      dy += dest->yofs;
-      dest = dest->parent;
-   }
+   HANDLE_SUB_BITMAPS(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, sxinc, syinc) 
 
-   if (src->parent) {
-      sx += src->xofs;
-      sy += src->yofs;
-      src = src->parent;
-   }
-
    if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY))) {
       return;
    }
@@ -1256,6 +1304,7 @@
    ALLEGRO_BITMAP *dest = al_get_target_bitmap();
    int x;
    int y;
+   int dw, dh;
 
    ASSERT(_al_pixel_format_is_real(bitmap->format));
    ASSERT(_al_pixel_format_is_real(dest->format));
@@ -1283,19 +1332,11 @@
       sh -= inc;
    }
 
-   /* Handle sub bitmaps */
-   if (dest->parent) {
-      dx += dest->xofs;
-      dy += dest->yofs;
-      dest = dest->parent;
-   }
+   dw = sw;
+   dh = sh;
+   
+   HANDLE_SUB_BITMAPS(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1.0f, 1.0f)
 
-   if (bitmap->parent) {
-      sx += bitmap->xofs;
-      sy += bitmap->yofs;
-      bitmap = bitmap->parent;
-   }
-
    /* Fast paths for no flipping */
    if (!(flags & ALLEGRO_FLIP_HORIZONTAL) &&
          !(flags & ALLEGRO_FLIP_VERTICAL)) {
@@ -1419,19 +1460,8 @@
    if (dw == 0 || dh == 0)
       return;
 
-   /* Handle sub bitmaps */
-   if (dest->parent) {
-      dx += dest->xofs;
-      dy += dest->yofs;
-      dest = dest->parent;
-   }
+   HANDLE_SUB_BITMAPS(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, sxinc, syinc)
 
-   if (src->parent) {
-      sx += src->xofs;
-      sy += src->yofs;
-      src = src->parent;
-   }
-
    if (src->format == dest->format) {
       if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY,
             ALLEGRO_LOCK_READONLY))) {


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/