Commits

Anonymous committed 879ca7f

subrect work

Comments (0)

Files changed (8)

 # BREAK = change breaks existing code
 # BUG	= fixed a bug that was (or could have been) crashing
 
+October 16, 2002
+	fix crash with subsubsurface blits [BUG]
+	added Surface.get_offset() and get_abs_offset()
+	added Surface.get_parent() and get_abs_parent()
+
 October 6, 2002
     	added event.clear() to efficiently clear the queue
 
 <a href=ref/Surface.html#convert>Surface.convert</a> - new copy of surface with different format<br>
 <a href=ref/Surface.html#convert_alpha>Surface.convert_alpha</a> - new copy of surface with different format and per pixel alpha<br>
 <a href=ref/Surface.html#fill>Surface.fill</a> - fill areas of a Surface<br>
+<a href=ref/Surface.html#get_abs_offset>Surface.get_abs_offset</a> - get absolute offset of subsurface<br>
+<a href=ref/Surface.html#get_abs_parent>Surface.get_abs_parent</a> - get the toplevel surface for a subsurface<br>
 <a href=ref/Surface.html#get_alpha>Surface.get_alpha</a> - query alpha information<br>
 <a href=ref/Surface.html#get_at>Surface.get_at</a> - get a pixel color<br>
 <a href=ref/Surface.html#get_bitsize>Surface.get_bitsize</a> - query size of pixel<br>
 <a href=ref/Surface.html#get_locked>Surface.get_locked</a> - check if the surface needs locking<br>
 <a href=ref/Surface.html#get_losses>Surface.get_losses</a> - get mapping losses for each colorplane<br>
 <a href=ref/Surface.html#get_masks>Surface.get_masks</a> - get mapping bitmasks for each colorplane<br>
+<a href=ref/Surface.html#get_offset>Surface.get_offset</a> - get offset of subsurface<br>
 <a href=ref/Surface.html#get_palette>Surface.get_palette</a> - get the palette<br>
 <a href=ref/Surface.html#get_palette_at>Surface.get_palette_at</a> - get a palette entry<br>
+<a href=ref/Surface.html#get_parent>Surface.get_parent</a> - get a subsurface parent<br>
 <a href=ref/Surface.html#get_pitch>Surface.get_pitch</a> - query the surface pitch<br>
 <a href=ref/Surface.html#get_rect>Surface.get_rect</a> - get a rectangle covering the entire surface<br>
 <a href=ref/Surface.html#get_shifts>Surface.get_shifts</a> - alphashift<br>

docs/ref/Surface.html

 fill areas of a Surface</td></tr>
 
 
+<tr><td><a href=#get_abs_offset>get_abs_offset</a></td><td> -
+get absolute offset of subsurface</td></tr>
+
+
+<tr><td><a href=#get_abs_parent>get_abs_parent</a></td><td> -
+get the toplevel surface for a subsurface</td></tr>
+
+
 <tr><td><a href=#get_alpha>get_alpha</a></td><td> -
 query alpha information</td></tr>
 
 get mapping bitmasks for each colorplane</td></tr>
 
 
+<tr><td><a href=#get_offset>get_offset</a></td><td> -
+get offset of subsurface</td></tr>
+
+
 <tr><td><a href=#get_palette>get_palette</a></td><td> -
 get the palette</td></tr>
 
 get a palette entry</td></tr>
 
 
+<tr><td><a href=#get_parent>get_parent</a></td><td> -
+get a subsurface parent</td></tr>
+
+
 <tr><td><a href=#get_pitch>get_pitch</a></td><td> -
 query the surface pitch</td></tr>
 
 rectangle. The return value contains the actual area filled.
 </ul><br>&nbsp;<br>
 
+<a name=get_abs_offset><font size=+2><b>get_abs_offset
+</b></font><br><font size=+1><tt>
+Surface.get_abs_offset() -> x, y
+</tt></font><ul>
+Returns the absolute X and Y position a subsurface is positioned
+inside its top level parent. Will return 0,0 for surfaces that are
+not a subsurface.
+</ul><br>&nbsp;<br>
+
+<a name=get_abs_parent><font size=+2><b>get_abs_parent
+</b></font><br><font size=+1><tt>
+Surface.get_abs_parent() -> Surface
+</tt></font><ul>
+Returns the top level Surface for this subsurface. If this is not
+a subsurface it will return a reference to itself. You will always
+get a valid surface from this method.
+</ul><br>&nbsp;<br>
+
 <a name=get_alpha><font size=+2><b>get_alpha
 </b></font><br><font size=+1><tt>
 Surface.get_alpha() -> alpha
 of zero means that colorplane is not used (like alpha)
 </ul><br>&nbsp;<br>
 
+<a name=get_offset><font size=+2><b>get_offset
+</b></font><br><font size=+1><tt>
+Surface.get_offset() -> x, y
+</tt></font><ul>
+Returns the X and Y position a subsurface is positioned
+inside its parent. Will return 0,0 for surfaces that are
+not a subsurface.
+</ul><br>&nbsp;<br>
+
 <a name=get_palette><font size=+2><b>get_palette
 </b></font><br><font size=+1><tt>
 Surface.get_palette() -> [[r, g, b], ...]
 palette.
 </ul><br>&nbsp;<br>
 
+<a name=get_parent><font size=+2><b>get_parent
+</b></font><br><font size=+1><tt>
+Surface.get_parent() -> Surface
+</tt></font><ul>
+Returns the Surface that is a parent of this subsurface.
+Will return None if this is not a subsurface.
+</ul><br>&nbsp;<br>
+
 <a name=get_pitch><font size=+2><b>get_pitch
 </b></font><br><font size=+1><tt>
 Surface.get_pitch() -> pitch

docs/ref/pygame_event.html

 remove all matching event types from the queue. If no
 types are passed, this will remove all the events from the queue.
 You may also optionally pass a sequence of event types. For
-example, to remove all the mouse events from the queue, you
-would call,
-'<u>pygame.event.clear([MOUSEBUTTONUP,MOUSEBUTTONDOWN,MOUSEMOTION])</u>'.
+example, to remove all the mouse motion events from the queue, you
+would call, '<u>pygame.event.clear(MOUSEMOTION)</u>'.
 </ul><br>&nbsp;<br>
 
 <a name=event_name><font size=+2><b>event_name
     /*DOC*/    "remove all matching event types from the queue. If no\n"
     /*DOC*/    "types are passed, this will remove all the events from the queue.\n"
     /*DOC*/    "You may also optionally pass a sequence of event types. For\n"
-    /*DOC*/    "example, to remove all the mouse events from the queue, you\n"
-    /*DOC*/    "would call,\n"
-    /*DOC*/    "'pygame.event.clear([MOUSEBUTTONUP,MOUSEBUTTONDOWN,MOUSEMOTION])'.\n"
+    /*DOC*/    "example, to remove all the mouse motion events from the queue, you\n"
+    /*DOC*/    "would call, 'pygame.event.clear(MOUSEMOTION)'.\n"
     /*DOC*/ ;
 
 static PyObject* event_clear(PyObject* self, PyObject* args)
 	SDL_RWops *rw;
 	if(!PyArg_ParseTuple(arg, "O|s", &file, &name))
 		return NULL;
-
 	if(PyString_Check(file) || PyUnicode_Check(file))
 	{
 		if(!PyArg_ParseTuple(arg, "s|O", &name, &file))
 {
 	PyObject* owner;
 	int pixeloffset;
+	int offsetx, offsety;
 };
 #ifndef PYGAMEAPI_SURFLOCK_INTERNAL
 #define PySurface_Prep(x) if(((PySurfaceObject*)x)->subsurface)(*(*(void(*)(PyObject*))PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 0]))(x)
 	/*passthrough blits to the real surface*/
 	if(((PySurfaceObject*)self)->subsurface)
 	{
-		int offset;
 		PyObject *owner;
-
-		owner = ((PySurfaceObject*)self)->subsurface->owner;
-	        subsurface = PySurface_AsSurface(owner);	    
-
-	        offset = ((PySurfaceObject*)self)->subsurface->pixeloffset;
-	        suboffsetx = (offset % subsurface->pitch) / subsurface->format->BytesPerPixel;
-	        suboffsety = offset / subsurface->pitch;
-		if(((PySurfaceObject*)owner)->subsurface) /*multiple subsurface, let's recurse*/
+		struct SubSurface_Data *subdata;
+		
+		subdata = ((PySurfaceObject*)self)->subsurface;
+		owner = subdata->owner;
+            	subsurface = PySurface_AsSurface(owner);
+		suboffsetx = subdata->offsetx;
+		suboffsety = subdata->offsety;
+		
+		while(((PySurfaceObject*)owner)->subsurface)
 		{
-			PyObject *arg, *ret;
-			arg = Py_BuildValue("(O(ii)O)", owner,
-						dest_rect.x + suboffsetx, dest_rect.y + suboffsety, argrect);
-			ret = surf_blit(owner, arg);
-			Py_DECREF(arg);
-			((PyRectObject*)ret)->r.x -= suboffsetx;
-			((PyRectObject*)ret)->r.y -= suboffsety;
-			return ret;
+		    subdata = ((PySurfaceObject*)owner)->subsurface;
+    		    owner = subdata->owner;
+	            subsurface = PySurface_AsSurface(owner);
+	    	    suboffsetx += subdata->offsetx;
+    	    	    suboffsety += subdata->offsety;
 		}
-
+		
 	        SDL_GetClipRect(subsurface, &orig_clip);
 	        SDL_GetClipRect(dest, &sub_clip);
 	        sub_clip.x += suboffsetx;
 
 
 
+
     /*DOC*/ static char doc_surf_get_size[] =
     /*DOC*/    "Surface.get_size() -> x, y\n"
     /*DOC*/    "query the surface size\n"
 		PyMem_Del(data);
 		return NULL;
 	}
-
 	Py_INCREF(self);
 	data->owner = self;
 	data->pixeloffset = pixeloffset;
+	data->offsetx = rect->x;
+	data->offsety = rect->y;
 	((PySurfaceObject*)subobj)->subsurface = data;
 
-
-
 	return subobj;
 }
 
 
 
+    /*DOC*/ static char doc_surf_get_offset[] =
+    /*DOC*/    "Surface.get_offset() -> x, y\n"
+    /*DOC*/    "get offset of subsurface\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "Returns the X and Y position a subsurface is positioned\n"
+    /*DOC*/    "inside its parent. Will return 0,0 for surfaces that are\n"
+    /*DOC*/    "not a subsurface.\n"
+    /*DOC*/ ;
+
+static PyObject* surf_get_offset(PyObject* self, PyObject* args)
+{
+    	struct SubSurface_Data *subdata;	
+    	subdata = ((PySurfaceObject*)self)->subsurface;
+	if(!subdata)
+    	    	return Py_BuildValue("(ii)", 0, 0);
+    	return Py_BuildValue("(ii)", subdata->offsetx, subdata->offsety);
+}
+
+
+    /*DOC*/ static char doc_surf_get_abs_offset[] =
+    /*DOC*/    "Surface.get_abs_offset() -> x, y\n"
+    /*DOC*/    "get absolute offset of subsurface\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "Returns the absolute X and Y position a subsurface is positioned\n"
+    /*DOC*/    "inside its top level parent. Will return 0,0 for surfaces that are\n"
+    /*DOC*/    "not a subsurface.\n"
+    /*DOC*/ ;
+
+static PyObject* surf_get_abs_offset(PyObject* self, PyObject* args)
+{
+    	struct SubSurface_Data *subdata;	
+	PyObject *owner;
+	int offsetx, offsety;
+
+    	subdata = ((PySurfaceObject*)self)->subsurface;
+	if(!subdata)
+    	    	return Py_BuildValue("(ii)", 0, 0);
+
+	subdata = ((PySurfaceObject*)self)->subsurface;
+	owner = subdata->owner;
+	offsetx = subdata->offsetx;
+	offsety = subdata->offsety;
+
+	while(((PySurfaceObject*)owner)->subsurface)
+	{
+	    subdata = ((PySurfaceObject*)owner)->subsurface;
+    	    owner = subdata->owner;
+	    offsetx += subdata->offsetx;
+    	    offsety += subdata->offsety;
+	}
+
+
+	return Py_BuildValue("(ii)", offsetx, offsety);
+}
+
+    /*DOC*/ static char doc_surf_get_parent[] =
+    /*DOC*/    "Surface.get_parent() -> Surface\n"
+    /*DOC*/    "get a subsurface parent\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "Returns the Surface that is a parent of this subsurface.\n"
+    /*DOC*/    "Will return None if this is not a subsurface.\n"
+    /*DOC*/ ;
+
+static PyObject* surf_get_parent(PyObject* self, PyObject* args)
+{
+    	struct SubSurface_Data *subdata;	
+    	subdata = ((PySurfaceObject*)self)->subsurface;
+	if(!subdata)
+    	    	RETURN_NONE
+		    
+    	Py_INCREF(subdata->owner);
+	return subdata->owner;
+}
+
+    /*DOC*/ static char doc_surf_get_abs_parent[] =
+    /*DOC*/    "Surface.get_abs_parent() -> Surface\n"
+    /*DOC*/    "get the toplevel surface for a subsurface\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "Returns the top level Surface for this subsurface. If this is not\n"
+    /*DOC*/    "a subsurface it will return a reference to itself. You will always\n"
+    /*DOC*/    "get a valid surface from this method.\n"
+    /*DOC*/ ;
+static PyObject* surf_get_abs_parent(PyObject* self, PyObject* args)
+{
+    	struct SubSurface_Data *subdata;	
+	PyObject *owner;
+
+    	subdata = ((PySurfaceObject*)self)->subsurface;
+	if(!subdata)
+	{
+	    Py_INCREF(self);
+	    return self;
+	}
+
+	subdata = ((PySurfaceObject*)self)->subsurface;
+	owner = subdata->owner;
+
+	while(((PySurfaceObject*)owner)->subsurface)
+	{
+	    subdata = ((PySurfaceObject*)owner)->subsurface;
+    	    owner = subdata->owner;
+	}
+
+	Py_INCREF(owner);
+	return owner;
+}
+
+
+
+
 static struct PyMethodDef surface_methods[] =
 {
 	{"get_at",			surf_get_at,		1, doc_surf_get_at },
 	{"get_losses",		surf_get_losses,	1, doc_surf_get_losses },
 
 	{"subsurface",		surf_subsurface,	1, doc_surf_subsurface },
+	{"get_offset",		surf_get_offset,	1, doc_surf_get_offset },
+	{"get_abs_offset",	surf_get_abs_offset,	1, doc_surf_get_abs_offset },
+	{"get_parent",		surf_get_parent,	1, doc_surf_get_parent },
+	{"get_abs_parent",	surf_get_abs_parent,	1, doc_surf_get_abs_parent },
 
 	{NULL,		NULL}
 };
 static PyObject* PySurface_New(SDL_Surface* s)
 {
 	PySurfaceObject* surf;
-
 	if(!s) return RAISE(PyExc_SDLError, SDL_GetError());
 
 	surf = PyObject_NEW(PySurfaceObject, &PySurface_Type);
 
 	PyType_Init(PySurface_Type);
 
-
     /* create the module */
 	module = Py_InitModule3("surface", surface_builtins, doc_pygame_surface_MODULE);
 	dict = PyModule_GetDict(module);
 	apiobj = PyCObject_FromVoidPtr(c_api, NULL);
 	PyDict_SetItemString(dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);
 	Py_DECREF(apiobj);
-
 	/*imported needed apis*/
 	import_pygame_base();
 	import_pygame_rect();