From 60e14e75b72bdb5082a6ff8b320e31193cc9c992 Mon Sep 17 00:00:00 2001
From: remi-k <remi-k@4e206d99-4929-0410-ac5d-dfc041789085>
Date: Thu, 21 May 2009 13:52:28 +0000
Subject: [PATCH] Improved the way rectangle are handled; Some bug fixes.

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1093 4e206d99-4929-0410-ac5d-dfc041789085
---
 python/src/Drawable.cpp     |  4 ++--
 python/src/Font.cpp         | 18 +++++++++------
 python/src/Glyph.cpp        | 44 +++++++++++++++++-------------------
 python/src/Glyph.hpp        |  1 +
 python/src/Image.cpp        | 17 ++++----------
 python/src/Rect.cpp         | 45 ++++++++++++++++++++++++-------------
 python/src/Rect.hpp         |  2 ++
 python/src/RenderWindow.cpp | 40 +++++++++++++++++++++++----------
 python/src/RenderWindow.hpp |  3 +++
 python/src/Sprite.cpp       | 40 ++++++++++++++++++++-------------
 python/src/Sprite.hpp       |  2 ++
 python/src/String.cpp       |  6 ++---
 python/src/View.cpp         | 36 +++++++++++------------------
 python/src/View.hpp         |  2 ++
 14 files changed, 145 insertions(+), 115 deletions(-)

diff --git a/python/src/Drawable.cpp b/python/src/Drawable.cpp
index 75ab0407..6375a35d 100644
--- a/python/src/Drawable.cpp
+++ b/python/src/Drawable.cpp
@@ -230,7 +230,7 @@ PySfDrawable_TransformToGlobal(PySfDrawable* self, PyObject *args)
 	return Py_BuildValue("ff", result.x, result.y);
 }
 
-int PySfDrawable_SetAttr(PyObject* self, PyObject *attr_name, PyObject *v)
+int PySfDrawable_setattro(PyObject* self, PyObject *attr_name, PyObject *v)
 {
 #ifdef IS_PY3K
 	PyObject *string = PyUnicode_AsUTF8String(attr_name);
@@ -299,7 +299,7 @@ PyTypeObject PySfDrawableType = {
 	0,						/*tp_call*/
 	0,						/*tp_str*/
 	0,						/*tp_getattro*/
-	PySfDrawable_SetAttr,	/*tp_setattro*/
+	PySfDrawable_setattro,	/*tp_setattro*/
 	0,						/*tp_as_buffer*/
 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
 	"Abstract base class for every object that can be drawn into a render window.", /* tp_doc */
diff --git a/python/src/Font.cpp b/python/src/Font.cpp
index cd6f7bd9..b7beeafd 100644
--- a/python/src/Font.cpp
+++ b/python/src/Font.cpp
@@ -167,13 +167,17 @@ PySfFont_GetCharacterSize(PySfFont* self)
 static PyObject *
 PySfFont_GetGlyph(PySfFont* self, PyObject *args)
 {
-	PySfGlyph *PyGlyph = GetNewPySfGlyph();
-	sf::Glyph *Glyph = new sf::Glyph(self->obj->GetGlyph(PyLong_AsUnsignedLong(args)));
-	PyGlyph->obj = Glyph;
-	PyGlyph->Rectangle->obj = &(PyGlyph->obj->Rectangle);
-	PyGlyph->TexCoords->obj = &(PyGlyph->obj->TexCoords);
-	PySfGlyphUpdateSelf(PyGlyph);
-	return (PyObject *)PyGlyph;
+	PySfGlyph *Glyph = GetNewPySfGlyph();
+	Glyph->Owner = false;
+	Glyph->Rectangle = GetNewPySfIntRect();
+	Glyph->Rectangle->Owner = false;
+	Glyph->TexCoords = GetNewPySfFloatRect();
+	Glyph->TexCoords->Owner = false;
+	Glyph->obj = (sf::Glyph *) &(self->obj->GetGlyph(PyLong_AsUnsignedLong(args)));
+	Glyph->Rectangle->obj = &(Glyph->obj->Rectangle);
+	Glyph->TexCoords->obj = &(Glyph->obj->TexCoords);
+	PySfGlyphUpdateSelf(Glyph);
+	return (PyObject *)Glyph;
 }
 
 static PyMethodDef PySfFont_methods[] = {
diff --git a/python/src/Glyph.cpp b/python/src/Glyph.cpp
index d7fe9fc3..d805c478 100644
--- a/python/src/Glyph.cpp
+++ b/python/src/Glyph.cpp
@@ -41,10 +41,8 @@ static PyMemberDef PySfGlyph_members[] = {
 static void
 PySfGlyph_dealloc(PySfGlyph *self)
 {
-	self->Rectangle->obj = new sf::IntRect(self->obj->Rectangle);
-	Py_DECREF(self->Rectangle);
-	self->TexCoords->obj = new sf::FloatRect(self->obj->TexCoords);
-	Py_DECREF(self->TexCoords);
+	Py_CLEAR(self->Rectangle);
+	Py_CLEAR(self->TexCoords);
 	delete self->obj;
 	free_object(self);
 }
@@ -53,30 +51,14 @@ void
 PySfGlyphUpdateObj(PySfGlyph *self)
 {
 	self->obj->Advance = self->Advance;
-	PySfIntRectUpdateObj(self->Rectangle);
-	PySfFloatRectUpdateObj(self->TexCoords);
-	self->obj->Rectangle.Left = self->Rectangle->Left;
-	self->obj->Rectangle.Top = self->Rectangle->Top;
-	self->obj->Rectangle.Right = self->Rectangle->Right;
-	self->obj->Rectangle.Bottom = self->Rectangle->Bottom;
-	self->obj->TexCoords.Left = self->TexCoords->Left;
-	self->obj->TexCoords.Top = self->TexCoords->Top;
-	self->obj->TexCoords.Right = self->TexCoords->Right;
-	self->obj->TexCoords.Bottom = self->TexCoords->Bottom;
+	PySfIntRectUpdateSelf(self->Rectangle);
+	PySfFloatRectUpdateSelf(self->TexCoords);
 }
 
 void
 PySfGlyphUpdateSelf(PySfGlyph *self)
 {
 	self->Advance = self->obj->Advance;
-	self->Rectangle->Left = self->obj->Rectangle.Left;
-	self->Rectangle->Top = self->obj->Rectangle.Top;
-	self->Rectangle->Right = self->obj->Rectangle.Right;
-	self->Rectangle->Bottom = self->obj->Rectangle.Bottom;
-	self->TexCoords->Left = self->obj->TexCoords.Left;
-	self->TexCoords->Top = self->obj->TexCoords.Top;
-	self->TexCoords->Right = self->obj->TexCoords.Right;
-	self->TexCoords->Bottom = self->obj->TexCoords.Bottom;
 	PySfIntRectUpdateObj(self->Rectangle);
 	PySfFloatRectUpdateObj(self->TexCoords);
 }
@@ -88,16 +70,32 @@ PySfGlyph_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 	self = (PySfGlyph *)type->tp_alloc(type, 0);
 	if (self != NULL)
 	{
-		self->Advance = 0;
 		self->Rectangle = GetNewPySfIntRect();
+		self->Rectangle->Owner = false;
 		self->TexCoords = GetNewPySfFloatRect();
+		self->TexCoords->Owner = false;
 		self->obj = new sf::Glyph();
+		self->Owner = true;
+		self->Advance = self->obj->Advance;
 		self->Rectangle->obj = &(self->obj->Rectangle);
 		self->TexCoords->obj = &(self->obj->TexCoords);
+		PySfIntRectUpdateSelf(self->Rectangle);
+		PySfFloatRectUpdateSelf(self->TexCoords);
 	}
 	return (PyObject *)self;
 }
 
+int
+PySfGlyph_setattro(PyObject* self, PyObject *attr_name, PyObject *v)
+{
+	int result = PyObject_GenericSetAttr(self, attr_name, v);
+	PySfGlyph *Glyph = (PySfGlyph *)self;
+	Glyph->obj->Rectangle = *(Glyph->Rectangle->obj);
+	Glyph->obj->TexCoords = *(Glyph->TexCoords->obj);
+	Glyph->obj->Advance = Glyph->Advance;
+	return result;
+}
+
 PyTypeObject PySfGlyphType = {
 	head_init
 	"Glyph",				/*tp_name*/
diff --git a/python/src/Glyph.hpp b/python/src/Glyph.hpp
index 5b83575d..d461b5d1 100644
--- a/python/src/Glyph.hpp
+++ b/python/src/Glyph.hpp
@@ -34,6 +34,7 @@
 
 typedef struct {
 	PyObject_HEAD
+	bool Owner;
 	int Advance;
 	PySfIntRect *Rectangle;
 	PySfFloatRect *TexCoords;
diff --git a/python/src/Image.cpp b/python/src/Image.cpp
index d98e4ea2..b9e33b98 100644
--- a/python/src/Image.cpp
+++ b/python/src/Image.cpp
@@ -78,10 +78,7 @@ PySfImage_CopyScreen(PySfImage* self, PyObject *args)
 
 
 	if (SourceRect)
-	{
-		PySfIntRectUpdateObj(SourceRect);
 		Result = self->obj->CopyScreen(*(RenderWindow->obj), *(SourceRect->obj));
-	}
 	else
 		Result = self->obj->CopyScreen(*(RenderWindow->obj));
 	if (Result)
@@ -242,18 +239,15 @@ PySfImage_GetTexCoords(PySfImage* self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "O!|O:Image.GetTextCoords", &PySfIntRectType, &RectArg, &AdjustObj))
 		return NULL;
 
-	if (AdjustObj)
-		if (PyObject_IsTrue(AdjustObj))
-			Adjust = true;
+	if (AdjustObj != NULL)
+		Adjust = PyBool_AsBool(AdjustObj);
 
 	PySfFloatRect *Rect;
 
 	Rect = GetNewPySfFloatRect();
+	Rect->Owner = true;
 	Rect->obj = new sf::FloatRect(self->obj->GetTexCoords(*(RectArg->obj), Adjust));
-	Rect->Left = Rect->obj->Left;
-	Rect->Top = Rect->obj->Top;
-	Rect->Right = Rect->obj->Right;
-	Rect->Bottom = Rect->obj->Bottom;
+	PySfFloatRectUpdateSelf(Rect);
 
 	return (PyObject *)Rect;
 }
@@ -400,10 +394,7 @@ PySfImage_Copy(PySfImage* self, PyObject *args, PyObject *kwds)
 			ApplyAlpha = true;
 
 	if (SourceRect)
-	{
-		PySfIntRectUpdateObj(SourceRect);
 		self->obj->Copy(*(Source->obj), DestX, DestY, *(SourceRect->obj), ApplyAlpha);
-	}
 	else
 		self->obj->Copy(*(Source->obj), DestX, DestY, sf::IntRect(0, 0, 0, 0), ApplyAlpha);
 
diff --git a/python/src/Rect.cpp b/python/src/Rect.cpp
index 26a61b5a..8d5c5769 100644
--- a/python/src/Rect.cpp
+++ b/python/src/Rect.cpp
@@ -49,14 +49,16 @@ static PyMemberDef PySfFloatRect_members[] = {
 static void
 PySfIntRect_dealloc(PySfIntRect* self)
 {
-	delete self->obj;
+	if (self->Owner)
+		delete self->obj;
 	free_object(self);
 }
 
 static void
 PySfFloatRect_dealloc(PySfFloatRect* self)
 {
-	delete self->obj;
+	if (self->Owner)
+		delete self->obj;
 	free_object(self);
 }
 
@@ -68,7 +70,8 @@ PySfIntRect_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 	self = (PySfIntRect *)type->tp_alloc(type, 0);
 	if (self != NULL)
 	{
-		if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiii:IntRect.__init__", (char **)kwlist, &(self->Left), &(self->Top), &(self->Right), &(self->Bottom)))
+		self->Owner = true;
+		if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiii:IntRect.__new__", (char **)kwlist, &(self->Left), &(self->Top), &(self->Right), &(self->Bottom)))
 			return NULL;
 		self->obj = new sf::IntRect(self->Left, self->Top, self->Right, self->Bottom);
 	}
@@ -83,7 +86,8 @@ PySfFloatRect_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 	self = (PySfFloatRect *)type->tp_alloc(type, 0);
 	if (self != NULL)
 	{
-		if (!PyArg_ParseTupleAndKeywords(args, kwds, "ffff:FloatRect.__init__", (char **)kwlist, &(self->Left), &(self->Top), &(self->Right), &(self->Bottom)))
+		self->Owner = true;
+		if (!PyArg_ParseTupleAndKeywords(args, kwds, "ffff:FloatRect.__new__", (char **)kwlist, &(self->Left), &(self->Top), &(self->Right), &(self->Bottom)))
 			return NULL;
 		self->obj = new sf::FloatRect(self->Left, self->Top, self->Right, self->Bottom);
 	}
@@ -93,14 +97,12 @@ PySfFloatRect_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 static PyObject *
 PySfIntRect_GetWidth(PySfIntRect *self)
 {
-	PySfIntRectUpdateObj(self);
 	return PyLong_FromLong(self->obj->GetWidth());
 }
 
 static PyObject *
 PySfIntRect_GetHeight(PySfIntRect *self)
 {
-	PySfIntRectUpdateObj(self);
 	return PyLong_FromLong(self->obj->GetHeight());
 }
 
@@ -113,14 +115,12 @@ PySfIntRect_Intersects(PySfIntRect* self, PyObject *args);
 static PyObject *
 PySfFloatRect_GetWidth(PySfFloatRect *self)
 {
-	PySfFloatRectUpdateObj(self);
 	return PyFloat_FromDouble(self->obj->GetWidth());
 }
 
 static PyObject *
 PySfFloatRect_GetHeight(PySfFloatRect *self)
 {
-	PySfFloatRectUpdateObj(self);
 	return PyFloat_FromDouble(self->obj->GetHeight());
 }
 
@@ -138,7 +138,6 @@ PySfIntRect_Offset(PySfIntRect* self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "ii:IntRect.Offset", &OffsetX, &OffsetY))
 		return NULL; 
 
-	PySfIntRectUpdateObj(self);
 	self->obj->Offset(OffsetX, OffsetY);
 	PySfIntRectUpdateSelf(self);
 	Py_RETURN_NONE;
@@ -152,7 +151,6 @@ PySfFloatRect_Offset(PySfFloatRect* self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "ff:FloatRect.Offset", &OffsetX, &OffsetY))
 		return NULL; 
 
-	PySfFloatRectUpdateObj(self);
 	self->obj->Offset(OffsetX, OffsetY);
 	PySfFloatRectUpdateSelf(self);
 	Py_RETURN_NONE;
@@ -202,6 +200,24 @@ Check intersection between two rectangles.\n\
 	{NULL}  /* Sentinel */
 };
 
+int
+PySfIntRect_setattro(PyObject* self, PyObject *attr_name, PyObject *v)
+{
+	int result = PyObject_GenericSetAttr(self, attr_name, v);
+	PySfIntRect *Rect = (PySfIntRect *)self;
+	PySfIntRectUpdateObj(Rect);
+	return result;
+}
+
+int
+PySfFloatRect_setattro(PyObject* self, PyObject *attr_name, PyObject *v)
+{
+	int result = PyObject_GenericSetAttr(self, attr_name, v);
+	PySfFloatRect *Rect = (PySfFloatRect *)self;
+	PySfFloatRectUpdateObj(Rect);
+	return result;
+}
+
 PyTypeObject PySfIntRectType = {
 	head_init
 	"IntRect",				/*tp_name*/
@@ -220,7 +236,7 @@ PyTypeObject PySfIntRectType = {
 	0,						/*tp_call*/
 	0,						/*tp_str*/
 	0,						/*tp_getattro*/
-	0,						/*tp_setattro*/
+	PySfIntRect_setattro,	/*tp_setattro*/
 	0,						/*tp_as_buffer*/
 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
 	"sf.IntRect is an utility class for manipulating rectangles.", /* tp_doc */
@@ -262,7 +278,7 @@ PyTypeObject PySfFloatRectType = {
 	0,						/*tp_call*/
 	0,						/*tp_str*/
 	0,						/*tp_getattro*/
-	0,						/*tp_setattro*/
+	PySfFloatRect_setattro,	/*tp_setattro*/
 	0,						/*tp_as_buffer*/
 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
 	"sf.FloatRect is an utility class for manipulating rectangles.", /* tp_doc */
@@ -294,7 +310,6 @@ PySfFloatRect_Contains(PySfFloatRect* self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "ff:FloatRect.Contains", &x, &y))
 		return NULL; 
 
-	PySfFloatRectUpdateObj(self);
 	return PyBool_FromLong(self->obj->Contains(x,y));
 }
 
@@ -307,7 +322,6 @@ PySfFloatRect_Intersects(PySfFloatRect* self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "O!|O!:FloatRect.Intersects", &PySfFloatRectType, &Rect, &PySfFloatRectType, &OverlappingRect))
 		return NULL; 
 
-	PySfFloatRectUpdateObj(self);
 	if (OverlappingRect)
 		result = self->obj->Intersects(*(Rect->obj), (OverlappingRect->obj));
 	else
@@ -322,7 +336,6 @@ PySfIntRect_Contains(PySfIntRect* self, PyObject *args)
 {
 	unsigned int x=0, y=0;
 
-	PySfIntRectUpdateObj(self);
 	if (!PyArg_ParseTuple(args, "II:IntRect.Contains",  &x, &y))
 		return NULL;
 
@@ -335,7 +348,6 @@ PySfIntRect_Intersects(PySfIntRect* self, PyObject *args)
 	PySfIntRect *Rect=NULL, *OverlappingRect=NULL;
 	bool result;
 
-	PySfIntRectUpdateObj(self);
 	if (!PyArg_ParseTuple(args, "O!|O!:IntRect.Intersects", &PySfIntRectType, &Rect, &PySfIntRectType, &OverlappingRect))
 		return NULL; 
 
@@ -364,6 +376,7 @@ PySfFloatRectUpdateObj(PySfFloatRect *self)
 	self->obj->Top = self->Top;
 	self->obj->Bottom = self->Bottom;
 }
+
 void
 PySfIntRectUpdateSelf(PySfIntRect *self)
 {
diff --git a/python/src/Rect.hpp b/python/src/Rect.hpp
index 4b4ae63f..69385f45 100644
--- a/python/src/Rect.hpp
+++ b/python/src/Rect.hpp
@@ -31,6 +31,7 @@
 
 typedef struct {
 	PyObject_HEAD
+	bool Owner;
 	int Left;
 	int Right;
 	int Top;
@@ -40,6 +41,7 @@ typedef struct {
 
 typedef struct {
 	PyObject_HEAD
+	bool Owner;
 	float Left;
 	float Right;
 	float Top;
diff --git a/python/src/RenderWindow.cpp b/python/src/RenderWindow.cpp
index ad35f934..b5ed06d7 100644
--- a/python/src/RenderWindow.cpp
+++ b/python/src/RenderWindow.cpp
@@ -23,7 +23,6 @@
 ////////////////////////////////////////////////////////////
 
 #include "RenderWindow.hpp"
-#include "View.hpp"
 #include "Image.hpp"
 #include "Window.hpp"
 #include "Color.hpp"
@@ -43,7 +42,8 @@ extern PyTypeObject PySfDrawableType;
 
 static void
 PySfRenderWindow_dealloc(PySfRenderWindow* self)
-{
+{
+	Py_CLEAR(self->View);
 	delete self->obj;
 	free_object(self);
 }
@@ -53,8 +53,11 @@ PySfRenderWindow_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
 	PySfRenderWindow *self;
 	self = (PySfRenderWindow *)type->tp_alloc(type, 0);
-	if (self != NULL)
-		self->obj = new sf::RenderWindow();
+	if (self != NULL)
+	{
+		self->obj = new sf::RenderWindow();
+		self->View = NULL;
+	}
 	return (PyObject *)self;
 }
 
@@ -152,13 +155,23 @@ PySfRenderWindow_Clear(PySfRenderWindow *self, PyObject *args)
 
 static PyObject *
 PySfRenderWindow_GetView(PySfRenderWindow *self)
-{
-	PySfView *View;
+{
+	if (self->View != NULL)
+	{
+		Py_INCREF(self->View);
+		return (PyObject *)(self->View);
+	}
+	else
+	{
+		PySfView *View;
 
-	View = GetNewPySfView();
-	View->obj = new sf::View(self->obj->GetView());
-
-	return (PyObject *)View;
+		View = GetNewPySfView();
+		View->Owner = false;
+		View->obj = (sf::View *)&(self->obj->GetView());
+		Py_INCREF(View);
+		self->View = View;
+		return (PyObject *)View;
+	}
 }
 
 static PyObject *
@@ -176,8 +189,11 @@ PySfRenderWindow_SetView(PySfRenderWindow* self, PyObject *args)
 	{
 		PyErr_SetString(PyExc_TypeError, "RenderWindow.SetView() Argument is not a sf.View");
 		return NULL;
-	}
-	self->obj->SetView( *(View->obj));
+	}
+	Py_CLEAR(self->View);
+	Py_INCREF(View);
+	self->View = View;
+	self->obj->SetView(*(View->obj));
 	Py_RETURN_NONE;
 }
 
diff --git a/python/src/RenderWindow.hpp b/python/src/RenderWindow.hpp
index 37e62afb..0a488977 100644
--- a/python/src/RenderWindow.hpp
+++ b/python/src/RenderWindow.hpp
@@ -29,9 +29,12 @@
 
 #include <SFML/Graphics.hpp>
 
+#include "View.hpp"
+
 typedef struct {
 	PyObject_HEAD
 	sf::RenderWindow *obj;
+	PySfView *View;
 } PySfRenderWindow;
 
 
diff --git a/python/src/Sprite.cpp b/python/src/Sprite.cpp
index 7aa0d81c..4c47a4cd 100644
--- a/python/src/Sprite.cpp
+++ b/python/src/Sprite.cpp
@@ -24,7 +24,6 @@
 
 #include "Sprite.hpp"
 #include "Drawable.hpp"
-#include "Rect.hpp"
 #include "Color.hpp"
 
 #include "compat.hpp"
@@ -39,7 +38,8 @@ extern PyTypeObject PySfDrawableType;
 static void
 PySfSprite_dealloc(PySfSprite *self)
 {
-	Py_XDECREF(self->Image);
+	Py_CLEAR(self->Image);
+	Py_CLEAR(self->SubRect);
 	delete self->obj;
 	free_object(self);
 }
@@ -54,6 +54,7 @@ PySfSprite_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 	if (self != NULL)
 	{
 		self->Image = NULL;
+		self->SubRect = NULL;
 		self->IsCustom = false;
 	}
 
@@ -140,28 +141,37 @@ PySfSprite_Resize(PySfSprite* self, PyObject *args)
 
 static PyObject *
 PySfSprite_GetSubRect(PySfSprite* self)
-{
-	PySfIntRect *Rect;
-
-	Rect = GetNewPySfIntRect();
-	Rect->obj = new sf::IntRect(self->obj->GetSubRect());
-	Rect->Left = Rect->obj->Left;
-	Rect->Top = Rect->obj->Top;
-	Rect->Right = Rect->obj->Right;
-	Rect->Bottom = Rect->obj->Bottom;
-
-	return (PyObject *)Rect;
+{
+	if (self->SubRect != NULL)
+	{
+		Py_INCREF(self->SubRect);
+		return (PyObject *)(self->SubRect);
+	}
+	else
+	{
+		PySfIntRect *Rect;
+		Rect = GetNewPySfIntRect();
+		Rect->Owner = false;
+		Rect->obj = (sf::IntRect *) &(self->obj->GetSubRect());
+		PySfIntRectUpdateSelf(Rect);
+		Py_INCREF(Rect);
+		self->SubRect = Rect;
+		return (PyObject *)Rect;
+	}
 }
 
 static PyObject *
 PySfSprite_SetSubRect(PySfSprite* self, PyObject *args)
 {
 	PySfIntRect *Rect = (PySfIntRect *)args;
-	if (! PyObject_TypeCheck(Rect, &PySfIntRectType))
+	if (!PyObject_TypeCheck(Rect, &PySfIntRectType))
 	{
 		PyErr_SetString(PyExc_TypeError, "Sprite.SetSubRect() Argument is not a sf.IntRect instance");
 		return NULL;
-	}
+	}
+	Py_CLEAR(self->SubRect);
+	Py_INCREF(Rect);
+	self->SubRect = Rect;
 	self->obj->SetSubRect(*(Rect->obj));
 	Py_RETURN_NONE;
 }
diff --git a/python/src/Sprite.hpp b/python/src/Sprite.hpp
index ae83bbf3..78ae631e 100644
--- a/python/src/Sprite.hpp
+++ b/python/src/Sprite.hpp
@@ -30,12 +30,14 @@
 #include <SFML/Graphics/Sprite.hpp>
 
 #include "Image.hpp"
+#include "Rect.hpp"
 
 typedef struct {
 	PyObject_HEAD
 	bool IsCustom;
 	sf::Sprite *obj;
 	PySfImage *Image;
+	PySfIntRect *SubRect;
 } PySfSprite;
 
 #endif
diff --git a/python/src/String.cpp b/python/src/String.cpp
index ecb16850..52bf9f5c 100644
--- a/python/src/String.cpp
+++ b/python/src/String.cpp
@@ -175,11 +175,9 @@ PySfString_GetRect(PySfString* self)
 	PySfFloatRect *Rect;
 
 	Rect = GetNewPySfFloatRect();
+	Rect->Owner = true;
 	Rect->obj = new sf::FloatRect (self->obj->GetRect());
-	Rect->Left = Rect->obj->Left;
-	Rect->Top = Rect->obj->Top;
-	Rect->Right = Rect->obj->Right;
-	Rect->Bottom = Rect->obj->Bottom;
+	PySfFloatRectUpdateSelf(Rect);
 
 	return (PyObject *)Rect;
 }
diff --git a/python/src/View.cpp b/python/src/View.cpp
index 45ffd079..468f2ad8 100644
--- a/python/src/View.cpp
+++ b/python/src/View.cpp
@@ -23,7 +23,6 @@
 ////////////////////////////////////////////////////////////
 
 #include "View.hpp"
-#include "Rect.hpp"
 
 #include "offsetof.hpp"
 #include "compat.hpp"
@@ -49,26 +48,19 @@ PySfView_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 	if (self != NULL)
 	{
 		self->Owner = true;
+		PySfFloatRect *Rect = NULL;
+		if (!PyArg_ParseTuple(args, "|O!:View.__new__", &PySfFloatRectType, &Rect))
+			return NULL;
+
+		if (Rect != NULL)
+			self->obj = new sf::View( (const sf::FloatRect) *(Rect->obj));
+		else
+			self->obj = new sf::View();
 	}
 
 	return (PyObject *)self;
 }
 
-static int
-PySfView_init(PySfView *self, PyObject *args, PyObject *kwds)
-{
-	PySfFloatRect *Rect=NULL;
-	if (!PyArg_ParseTuple(args, "|O!:View.__init__", &PySfFloatRectType, &Rect))
-		return -1;
-
-	if (Rect != NULL)
-		self->obj = new sf::View( (const sf::FloatRect) *(Rect->obj));
-	else
-		self->obj = new sf::View();
-
-	return 0;
-}
-
 static PyObject *
 PySfView_GetCenter(PySfView* self)
 {
@@ -87,11 +79,9 @@ static PyObject *
 PySfView_GetRect(PySfView* self)
 {
 	PySfFloatRect *Rect = GetNewPySfFloatRect();
-	Rect->obj = new sf::FloatRect(self->obj->GetRect());
-	Rect->Left = Rect->obj->Left;
-	Rect->Right = Rect->obj->Right;
-	Rect->Top = Rect->obj->Top;
-	Rect->Bottom = Rect->obj->Bottom;
+	Rect->Owner = false;
+	Rect->obj = (sf::FloatRect *) &(self->obj->GetRect());
+	PySfFloatRectUpdateSelf(Rect);
 	return (PyObject *)Rect;
 }
 
@@ -181,7 +171,7 @@ PyTypeObject PySfViewType = {
 	0,					/* tp_descr_get */
 	0,					/* tp_descr_set */
 	0,					/* tp_dictoffset */
-	(initproc)PySfView_init, /* tp_init */
+	0,					/* tp_init */
 	0,					/* tp_alloc */
 	PySfView_new,		/* tp_new */
 };
@@ -189,6 +179,6 @@ PyTypeObject PySfViewType = {
 PySfView *
 GetNewPySfView()
 {
-	return (PySfView *)PySfView_new(&PySfViewType, NULL, NULL);
+	return PyObject_New(PySfView, &PySfViewType);
 }
 
diff --git a/python/src/View.hpp b/python/src/View.hpp
index 2e8955c3..98f12527 100644
--- a/python/src/View.hpp
+++ b/python/src/View.hpp
@@ -29,6 +29,8 @@
 
 #include <SFML/Graphics/View.hpp>
 
+#include "Rect.hpp"
+
 typedef struct {
 	PyObject_HEAD
 	bool Owner;