Author: mog
Date: Mon Apr 28 18:39:05 2008
New Revision: 26212

URL: http://svn.gna.org/viewcvs/wesnoth?rev=26212&view=rev
Log:
Add support for arbitrary source rects to blit_surface and cut_surface

Modified:
    trunk/src/sdl_utils.cpp

Modified: trunk/src/sdl_utils.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/sdl_utils.cpp?rev=26212&r1=26211&r2=26212&view=diff
==============================================================================
--- trunk/src/sdl_utils.cpp (original)
+++ trunk/src/sdl_utils.cpp Mon Apr 28 18:39:05 2008
@@ -1093,21 +1093,42 @@
        size_t rbpp = res->format->BytesPerPixel;
        size_t rpitch = res->pitch;
 
+       // compute the areas to copy
+       SDL_Rect src_rect = r;
+       SDL_Rect dst_rect = { 0, 0, r.w, r.h };
+
+       if (src_rect.x < 0) {
+               if (src_rect.x + src_rect.w <= 0)
+                       return res;
+               dst_rect.x -= src_rect.x;
+               dst_rect.w += src_rect.x;
+               src_rect.w += src_rect.x;
+               src_rect.x = 0;
+       }
+       if (src_rect.y < 0) {
+               if (src_rect.y + src_rect.h <= 0)
+                       return res;
+               dst_rect.y -= src_rect.y;
+               dst_rect.h += src_rect.y;
+               src_rect.h += src_rect.y;
+               src_rect.y = 0;
+       }
+
+       if(src_rect.x >= surf->w || src_rect.y >= surf->h)
+               return res;
+
        surface_lock slock(surf);
        surface_lock rlock(res);
 
        Uint8* src = reinterpret_cast<Uint8 *>(slock.pixels());
        Uint8* dest = reinterpret_cast<Uint8 *>(rlock.pixels());
 
-       if(r.x >= surf->w)
-               return res;
-
-       for(int y = 0; y < r.h && (r.y + y) < surf->h; ++y) {
-               Uint8* line_src = src + (r.y + y) * spitch + r.x * sbpp;
-               Uint8* line_dest = dest + y * rpitch;
-               size_t size = r.w + r.x <= surf->w ? r.w : surf->w - r.x;
-
-               assert(rpitch >= r.w * rbpp);
+       for(int y = 0; y < src_rect.h && (src_rect.y + y) < surf->h; ++y) {
+               Uint8* line_src  = src  + (src_rect.y + y) * spitch + 
src_rect.x * sbpp;
+               Uint8* line_dest = dest + (dst_rect.y + y) * rpitch + 
dst_rect.x * rbpp;
+               size_t size = src_rect.w + src_rect.x <= surf->w ? src_rect.w : 
surf->w - src_rect.x;
+
+               assert(rpitch >= src_rect.w * rbpp);
                memcpy(line_dest, line_src, size * rbpp);
        }
 
@@ -1241,8 +1262,7 @@
 //! The rectangles are const and will not be modified.
 //!
 //! @param src          The surface to blit.
-//! @param srcrect      The size of the surface to blit, only width and height
-//!                     are used.
+//! @param srcrect      The region of the surface to blit
 //! @param dst          The surface to blit on.
 //! @param dstrect      The offset to blit the surface on, only x and y are 
used.
 void blit_surface(const surface& src, 
@@ -1262,22 +1282,57 @@
                dst_rect.y = dstrect->y;
                dst_rect.h -= dstrect->y;
 
-               assert(dst_rect.x >= 0);
-               assert(dst_rect.y >= 0);
        }
 
        SDL_Rect src_rect = { 0, 0, src->w, src->h };
        if(srcrect && srcrect->w && srcrect->h) { 
+               src_rect.x = srcrect->x;
+               src_rect.y = srcrect->y;
+
                src_rect.w = srcrect->w;
                src_rect.h = srcrect->h;
 
-               assert(src_rect.w <= src->w);
-               assert(src_rect.h <= src->h);
-       }
+               if (src_rect.x < 0) {
+            if (src_rect.x + src_rect.w <= 0 || src_rect.x + dst_rect.w <= 0 )
+                return;
+                       dst_rect.x -= src_rect.x;
+                       dst_rect.w += src_rect.x;
+                       src_rect.w += src_rect.x;
+                       src_rect.x = 0;
+               }
+               if (src_rect.y < 0) {
+            if (src_rect.y + src_rect.h <= 0 || src_rect.y + dst_rect.h <= 0 )
+                return;
+                       dst_rect.y -= src_rect.y;
+                       dst_rect.h += src_rect.y;
+                       src_rect.h += src_rect.y;
+                       src_rect.y = 0;
+               }
+               if (src_rect.x + src_rect.w > src->w) {
+            if (src_rect.x >= src->w)
+                return;
+                       src_rect.w = src->w - src_rect.x;
+               }
+               if (src_rect.y + src_rect.h > src->h) {
+            if (src_rect.y >= src->h)
+                return;
+                       src_rect.h = src->h - src_rect.y;
+               }
+       }
+
+       assert(dst_rect.x >= 0);
+       assert(dst_rect.y >= 0);
 
        // Get the blit size limits.
        const unsigned width = minimum(src_rect.w, dst_rect.w);
        const unsigned height = minimum(src_rect.h, dst_rect.h);
+//     std::cout << width << " -- " << height << "\n";
+//     std::cout << src->w << " -- " << src->h << "\n";
+//     std::cout << srcrect->x << "," << srcrect->y << " - " << srcrect->w << 
"x" << srcrect->h << " - " "\n";
+//     if (dstrect)
+//             std::cout << dstrect->x << "," << dstrect->y << " - " << 
dstrect->w << "x" << dstrect->h << " - " "\n";
+//     std::cout << src_rect.x << "," << src_rect.y << " - " << src_rect.w << 
"x" << src_rect.h << " - " "\n";
+//     std::cout << dst_rect.x << "," << dst_rect.y << " - " << dst_rect.w << 
"x" << dst_rect.h << " - " "\n";
 
        {
                // Extra scoping used for the surface_lock.


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to