Commits

Anonymous committed 818d06c

Fixed ref count leaks in base.Rect, base.FRect, mask.Mask, physics, sdl.Overlay
and sdl.Surface.
Added sdl.Surface.scroll method from trunk.

Comments (0)

Files changed (10)

 * Add palette color support to sdlext.transform (trunk rev. 2242).
 * Check trunk rev. 1918, 1921, 1922, 1933, 1953 (blit blend operations).
 * Check trunk rev. 1937, 1947 (blit blend for self).
-* Add surface.scroll (trunk rev. 1951).
 
 Things to ADD:
 ==============

doc/src/sdlvideo.xml

           access. This is especially important for Python 3.x users.
       </desc>
     </method>
+    <method name="scroll">
+      <call>scroll ([dx, dy]) -> None</call>
+      <desc>
+        Scrolls the Surface in place.
+        
+        Move the Surface contents by *dx* pixels right and *dy* pixels
+        down. dx and dy may be negative for left and up scrolls
+        respectively. Areas of the surface that are not overwritten
+        retain their original pixel values. Scrolling is contained by
+        the Surface clip area. It is safe to have *dx* and *dy* values
+        that exceed the surface size.
+      </desc>
+    </method>
     <method name="set_alpha">
       <call>set_alpha (alpha[, flags]) -> None</call>
       <desc>

src/base/floatrect.c

                 Py_DECREF (list);
                 return NULL;
             }
+            Py_DECREF (obj);
         }
     }
     return list;
                 Py_DECREF (list);
                 return NULL;
             }
+            Py_DECREF (obj);
         }
     }
     return list;
             free (components);
             return NULL;
         }
+
         maskobj->mask = components[i];
         if (PyList_Append (ret, (PyObject *) maskobj) == -1)
         {
             free (components);
             return NULL;
         }
+        Py_DECREF (maskobj);
     }
     
     free (components);

src/physics/collision.c

             retval = NULL;
             goto back;
         }
+        Py_DECREF ((PyObject*)contact);
     }
     
     *refid = collision.refno;

src/sdl/overlay.c

         Py_DECREF (wkref);
         return 0;
     }
+    Py_DECREF (wkref);
 
     return 1;
 }

src/sdl/surface.c

 static PyObject* _surface_save (PyObject *self, PyObject *args);
 static PyObject* _surface_getat (PyObject *self, PyObject *args);
 static PyObject* _surface_setat (PyObject *self, PyObject *args);
+static PyObject* _surface_scroll (PyObject *self, PyObject *args,
+    PyObject *kwds);
 
 static void _release_c_lock (void *ptr);
 
     { "fill", (PyCFunction)_surface_fill, METH_VARARGS | METH_KEYWORDS,
       DOC_VIDEO_SURFACE_FILL },
     { "save", _surface_save, METH_VARARGS, DOC_VIDEO_SURFACE_SAVE },
+    { "scroll", (PyCFunction) _surface_scroll, METH_VARARGS | METH_KEYWORDS,
+      DOC_VIDEO_SURFACE_SCROLL },
     { NULL, NULL, 0, NULL }
 };
 
     Py_RETURN_NONE;
 }
 
+static PyObject*
+_surface_scroll (PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int dx = 0, dy = 0;
+    SDL_Surface *surface;
+    
+    static char *keys[] = { "dx", "dy", NULL };
+    if (!PyArg_ParseTupleAndKeywords (args, kwds, "|ii", keys, &dx, &dy))
+        return NULL;
+
+    surface = PySDLSurface_AsSDLSurface (self);
+
+    if (!pyg_sdlsurface_scroll (surface, dx, dy))
+    {
+        PyErr_SetString (PyExc_PyGameError, SDL_GetError ());
+        return NULL;
+    }
+    Py_RETURN_NONE;
+                    
+}
+
 /* C API */
 static void
 _release_c_lock (void *ptr)
         Py_DECREF (wkref);
         return 0;
     }
+    Py_DECREF (wkref);
 
     return 1;
 }

src/sdl/surface.h

 pyg_sdlsoftware_blit (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst,
     SDL_Rect *dstrect, int blitargs);
 
+int pyg_sdlsurface_scroll (SDL_Surface *surface, int dx, int dy);
 
 #endif /* _PYGAME_SDLSURFACE_H_ */

src/sdl/surface_blit.c

     /* Blit is done! */
     return (okay ? 1 : 0);
 }
+
+int
+pyg_sdlsurface_scroll (SDL_Surface *surface, int dx, int dy)
+{
+    int bpp, pitch, w, h;
+    int locked = 0;
+    SDL_Rect *cliprect;
+    Uint8 *src, *dst;
+
+    if (!surface)
+    {
+        SDL_SetError ("passed a NULL surface");
+        return 0;
+    }
+    if (surface->locked)
+    {
+        SDL_SetError ("surface must not be locked during scroll");
+        return 0;
+    }
+
+    if ((surface->flags & SDL_OPENGL) &&
+        !(surface->flags & (SDL_OPENGLBLIT & ~SDL_OPENGL)))
+    {
+        SDL_SetError ("cannot scroll an OPENGL Surface (OPENGLBLIT is ok)");
+        return 0;
+    }
+
+    if (dx == 0 && dy == 0)
+        return 1;
+
+    cliprect = &surface->clip_rect;
+    w = cliprect->w;
+    h = cliprect->h;
+    if (dx >= w || dx <= -w || dy >= h || dy <= -h)
+        return 1;
+
+    if (SDL_MUSTLOCK (surface))
+    {
+        if (SDL_LockSurface (surface) < 0)
+            return 0;
+        else
+            locked = 1;
+    }
+
+    bpp = surface->format->BytesPerPixel;
+    pitch = surface->pitch;
+    src = dst = (Uint8 *) surface->pixels +
+                cliprect->y * pitch + cliprect->x * bpp;
+    if (dx >= 0)
+    {
+        w -= dx;
+        if (dy > 0)
+        {
+            h -= dy;
+            dst += dy * pitch + dx * bpp;
+        }
+        else
+        {
+            h += dy;
+            src -= dy * pitch;
+            dst += dx * bpp;
+        }
+    }
+    else
+    {
+        w += dx;
+        if (dy > 0)
+        {
+            h -= dy;
+            src -= dx * bpp;
+            dst += dy * pitch;
+        }
+        else
+        {
+            h += dy;
+            src -= dy * pitch + dx * bpp;
+        }
+    }
+
+    if (src < dst)
+    {
+        src += (h - 1) * pitch;
+        dst += (h - 1) * pitch;
+        pitch = -pitch;
+    }
+    while (h--)
+    {
+        memmove (dst, src, (size_t) (w * bpp));
+        src += pitch;
+        dst += pitch;
+    }
+
+    if (locked)
+        SDL_UnlockSurface (surface);
+
+    return 1;
+}