SFML/python/src/Image.cpp
tankbo 839c80556d Adjusted PySFML to work with the current SFML2 branch.
Note that it's just compatible. A lot of the new functionality is still in the pipeline.

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1308 4e206d99-4929-0410-ac5d-dfc041789085
2009-12-07 11:53:38 +00:00

404 lines
12 KiB
C++

////////////////////////////////////////////////////////////
//
// PySFML - Python binding for SFML (Simple and Fast Multimedia Library)
// Copyright (C) 2007, 2008 Rémi Koenig (remi.k2620@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#include "Image.hpp"
#include "RenderWindow.hpp"
#include "Color.hpp"
#include "Rect.hpp"
#include "compat.hpp"
extern PyTypeObject PySfColorType;
extern PyTypeObject PySfIntRectType;
extern PyTypeObject PySfRenderWindowType;
static void
PySfImage_dealloc(PySfImage* self)
{
delete self->obj;
free_object(self);
}
static PyObject *
PySfImage_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static PyObject *
PySfImage_Create(PySfImage* self, PyObject *args, PyObject *kwds)
{
PySfColor *ColorTmp=NULL;
sf::Color *Color;
unsigned int Width=0, Height=0;
const char *kwlist[] = {"Width", "Height", "Color", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|IIO!:Image.Create", (char **)kwlist, &Width, &Height, &PySfColorType, &ColorTmp))
return NULL;
if (ColorTmp)
{
Color = ColorTmp->obj;
PySfColorUpdate(ColorTmp);
self->obj->Create(Width, Height, *Color);
}
else
self->obj->Create(Width, Height);
Py_RETURN_NONE;
}
static PyObject *
PySfImage_CopyScreen(PySfImage* self, PyObject *args)
{
PySfRenderWindow *RenderWindow;
PySfIntRect *SourceRect=NULL;
bool Result;
if (!PyArg_ParseTuple(args, "O!|O!:Image.CopyScreen", &PySfRenderWindowType, &RenderWindow, &PySfIntRectType, &SourceRect))
return NULL;
if (SourceRect)
Result = self->obj->CopyScreen(*(RenderWindow->obj), *(SourceRect->obj));
else
Result = self->obj->CopyScreen(*(RenderWindow->obj));
if (Result)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
static PyObject *
PySfImage_SetPixel(PySfImage* self, PyObject *args, PyObject *kwds)
{
PySfColor *ColorTmp=NULL;
sf::Color *Color;
unsigned int x=0, y=0;
const char *kwlist[] = {"x", "y", "Color", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "II|O!:Image.SetPixel", (char **)kwlist, &x, &y, &PySfColorType, &ColorTmp))
return NULL;
if (ColorTmp)
{
Color = ColorTmp->obj;
PySfColorUpdate(ColorTmp);
self->obj->SetPixel(x, y, *Color);
}
Py_RETURN_NONE;
}
static PyObject *
PySfImage_GetPixel(PySfImage* self, PyObject *args)
{
PySfColor *Color;
unsigned int x=0, y=0;
if (!PyArg_ParseTuple(args, "II:Image.GetPixel", &x, &y))
return NULL;
Color = GetNewPySfColor();
Color->obj = new sf::Color(self->obj->GetPixel(x, y));
Color->r = Color->obj->r;
Color->g = Color->obj->g;
Color->b = Color->obj->b;
Color->a = Color->obj->a;
return (PyObject *)Color;
}
static PyObject *
PySfImage_CreateMaskFromColor(PySfImage* self, PyObject *args)
{
PySfColor *ColorTmp= (PySfColor *)args;
sf::Color *Color;
if (!PyObject_TypeCheck(ColorTmp, &PySfColorType))
{
PyErr_SetString(PyExc_TypeError, "Image.CreateMaskFromColor() Argument must be a sf.Color");
return NULL;
}
Color = ColorTmp->obj;
PySfColorUpdate(ColorTmp);
self->obj->CreateMaskFromColor(*Color);
Py_RETURN_NONE;
}
static PyObject *
PySfImage_LoadFromMemory(PySfImage* self, PyObject *args)
{
unsigned int SizeInBytes;
char *Data;
if (!PyArg_ParseTuple(args, "s#:Image.LoadFromMemory", &Data, &SizeInBytes))
return NULL;
return PyBool_FromLong(self->obj->LoadFromMemory(Data, (std::size_t) SizeInBytes));
}
static PyObject *
PySfImage_LoadFromPixels(PySfImage* self, PyObject *args)
{
unsigned int Width, Height, Size;
char *Data;
if (! PyArg_ParseTuple(args, "IIs#:Image.LoadFromPixels", &Width, &Height, &Data, &Size))
return NULL;
self->obj->LoadFromPixels(Width, Height, (sf::Uint8*) Data);
Py_RETURN_NONE;
}
static PyObject *
PySfImage_GetPixels(PySfImage *self)
{
#ifdef IS_PY3K
return PyBytes_FromStringAndSize((const char *)(self->obj->GetPixelsPtr()), self->obj->GetWidth()*self->obj->GetHeight()*4);
#else
return PyString_FromStringAndSize((const char *)(self->obj->GetPixelsPtr()), self->obj->GetWidth()*self->obj->GetHeight()*4);
#endif
}
static PyObject *
PySfImage_LoadFromFile (PySfImage *self, PyObject *args)
{
load_from_file(self, args);
}
static PyObject *
PySfImage_SaveToFile (PySfImage *self, PyObject *args)
{
save_to_file(self, args);
}
static PyObject *
PySfImage_Bind(PySfImage *self)
{
self->obj->Bind();
Py_RETURN_NONE;
}
static PyObject *
PySfImage_SetSmooth (PySfImage *self, PyObject *args)
{
self->obj->SetSmooth(PyBool_AsBool(args));
Py_RETURN_NONE;
}
static PyObject *
PySfImage_GetWidth(PySfImage *self)
{
return PyLong_FromUnsignedLong(self->obj->GetWidth());
}
static PyObject *
PySfImage_GetHeight(PySfImage *self)
{
return PyLong_FromUnsignedLong(self->obj->GetHeight());
}
static PyObject *
PySfImage_GetValidSize(PySfImage* self, PyObject *args)
{
unsigned long S = PyLong_AsUnsignedLong(args);
return PyLong_FromUnsignedLong(sf::Image::GetValidSize(S));
}
static PyObject *
PySfImage_GetTexCoords(PySfImage* self, PyObject *args)
{
PySfIntRect *RectArg = NULL;
if (!PyArg_ParseTuple(args, "O!:Image.GetTextCoords", &PySfIntRectType, &RectArg))
return NULL;
PySfFloatRect *Rect;
Rect = GetNewPySfFloatRect();
Rect->Owner = true;
Rect->obj = new sf::FloatRect(self->obj->GetTexCoords(*(RectArg->obj)));
PySfFloatRectUpdateSelf(Rect);
return (PyObject *)Rect;
}
static int
PySfImage_init(PySfImage *self, PyObject *args, PyObject *kwds)
{
int size = PyTuple_Size(args);
if (size > 0)
{
if (PySfImage_Create(self, args, kwds) == NULL)
{
if (size != 3)
return -1;
else if (PySfImage_LoadFromPixels(self, args) == NULL)
return -1;
else PyErr_Clear();
}
}
return 0;
}
static PyObject *
PySfImage_Copy(PySfImage* self, PyObject *args, PyObject *kwds);
static PyMethodDef PySfImage_methods[] = {
{"Copy", (PyCFunction)PySfImage_Copy, METH_VARARGS, "Copy(Source, DestX, DestY, SourceRect = sf.IntRect(0,0,0,0))\n\
Copy pixels from another image onto this one. This function does a slow pixel copy and should only be used at initialization time.\n\
Source : Source image to copy\n\
DestX : X coordinate of the destination position\n\
DestY : Y coordinate of the destination position\n\
SourceRect : Sub-rectangle of the source image to copy (empty by default - entire image)\n\
ApplyAlpha : Should the copy take in account the source transparency? (false by default)"},
{"Create", (PyCFunction)PySfImage_Create, METH_VARARGS, "Create(Width=0, Height=0, Color=sf.Color.Black)\n\
Create an empty image.\n\
Width : Image width\n\
Height : Image height\n\
Col : Image color (black by default)"},
{"CopyScreen", (PyCFunction)PySfImage_CopyScreen, METH_VARARGS, "CopyScreen(Window, SourceRect)\n\
Create the image from the current contents of the given window. Return True if copy was successful.\n\
Window : Window to capture\n\
SourceRect : Sub-rectangle of the screen to copy (empty by default - entire image)"},
{"SetPixel", (PyCFunction)PySfImage_SetPixel, METH_VARARGS | METH_KEYWORDS, "SetPixel(X, Y, Col)\nChange the color of a pixel.\n\
X : X coordinate of pixel in the image\n Y : Y coordinate of pixel in the image\n Col : New color for pixel (X, Y)"},
{"GetPixel", (PyCFunction)PySfImage_GetPixel, METH_VARARGS, "GetPixel(X, Y)\nGet a pixel from the image."},
{"LoadFromFile", (PyCFunction)PySfImage_LoadFromFile, METH_O, "LoadFromFile(Path)\nLoad the surface from a file."},
{"SaveToFile", (PyCFunction)PySfImage_SaveToFile, METH_O, "SaveToFile(Path)\nSave the content of the image to a file."},
{"LoadFromMemory", (PyCFunction)PySfImage_LoadFromMemory, METH_VARARGS, "LoadFromMemory(Data)\nLoad the image from a file in memory."},
{"LoadFromPixels", (PyCFunction)PySfImage_LoadFromPixels, METH_VARARGS, "LoadFromPixels(Width, Height, Data)\nLoad the image directly from a string of pixels."},
{"GetPixels", (PyCFunction)PySfImage_GetPixels, METH_NOARGS, "GetPixels()\nGet a string representing the array of pixels (8 bits integers RGBA). String length is GetWidth() x GetHeight() x 4. This string becomes invalid if you reload or resize the image."},
{"CreateMaskFromColor", (PyCFunction)PySfImage_CreateMaskFromColor, METH_O, "CreateMaskFromColor(Color)\nCreate transparency mask from a specified colorkey."},
{"Bind", (PyCFunction)PySfImage_Bind, METH_NOARGS, "Bind()\nBind the image for rendering."},
{"SetSmooth", (PyCFunction)PySfImage_SetSmooth, METH_VARARGS, "SetSmooth(Smooth)\nEnable or disable image smooth filter."},
{"GetWidth", (PyCFunction)PySfImage_GetWidth, METH_NOARGS, "GetWidth()\nReturn the width of the image."},
{"GetHeight", (PyCFunction)PySfImage_GetHeight, METH_NOARGS, "GetHeight()\nReturn the height of the image."},
{"GetTexCoords", (PyCFunction)PySfImage_GetTexCoords, METH_VARARGS, "GetTexCoords(Rect)\nConvert a subrect expressed in pixels, into float texture coordinates. Returns texture coordinates corresponding to the sub-rectangle (sf.FloatRect instance)\n\
Rect : Sub-rectangle of image to convert"},
{"GetValidSize", (PyCFunction)PySfImage_GetValidSize, METH_STATIC | METH_O, "GetValidSize(Size)\nGet a valid texture size according to hardware support. Returns valid nearest size (greater than or equal to specified size).\n\
Size : Size to convert"},
{NULL} /* Sentinel */
};
PyTypeObject PySfImageType = {
head_init
"Image", /*tp_name*/
sizeof(PySfImage), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)PySfImage_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"sf.Image is the low-level class for loading and manipulating images.\n\
Default constructor : sf.Image()\n\
Other constructors : sf.Image(Width=0, Height=0, Color=sf.Color.Black) or sf.Image(Width, Height, Data).\n\
Copy constructor : sf.Image(Copy) where Copy is a sf.Image instance.", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
PySfImage_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)PySfImage_init, /* tp_init */
0, /* tp_alloc */
PySfImage_new, /* tp_new */
};
static PyObject *
PySfImage_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PySfImage *self;
self = (PySfImage *)type->tp_alloc(type, 0);
if (self != NULL)
{
if (PyTuple_Size(args) == 1)
{
PySfImage *Image;
if (PyArg_ParseTuple(args, "O!", &PySfImageType, &Image))
{
self->obj = new sf::Image(*(Image->obj));
}
else PyErr_Clear();
}
else self->obj = new sf::Image();
}
return (PyObject *)self;
}
static PyObject *
PySfImage_Copy(PySfImage* self, PyObject *args, PyObject *kwds)
{
const char *kwlist[] = {"Source", "DestX", "DestY", "SourceRect", "ApplyAlpha", NULL};
PySfIntRect *SourceRect = NULL;
PySfImage *Source = NULL;
unsigned int DestX, DestY;
PyObject *PyApplyAlpha = NULL;
bool ApplyAlpha = false;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!II|O!O:Image.Copy", (char **)kwlist, &PySfImageType, &Source, &DestX, &DestY, &PySfIntRectType, &SourceRect, &PyApplyAlpha))
return NULL;
if (PyApplyAlpha)
if (PyObject_IsTrue(PyApplyAlpha))
ApplyAlpha = true;
if (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);
Py_RETURN_NONE;
}
PySfImage *
GetNewPySfImage()
{
return PyObject_New(PySfImage, &PySfImageType);
}