/* pygame - Python Game Library Copyright (C) 2008 Marcus von Appen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//* This is a proposed SDL_gfx draw module for Pygame. It is backported from Pygame 2. TODO: - Add gfxdraw.doc file. - Unpdate Setup.in and config modules. - Move Python 3 compatibility macros to a header. - Determine if SDL video must be initiated for all routines to work. Add check if required, else remove ASSERT_VIDEO_INIT. - Unit tests. - Example (Maybe).*/#define PYGAME_SDLGFXPRIM_INTERNAL#include "pygame.h"#include "pygamedocs.h"#include "surface.h"#include "pgcompat.h"#include "SDL_gfx/SDL_gfxPrimitives.h"staticPyObject*_gfx_pixelcolor(PyObject*self,PyObject*args);staticPyObject*_gfx_hlinecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_vlinecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_rectanglecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_boxcolor(PyObject*self,PyObject*args);staticPyObject*_gfx_linecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_circlecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_arccolor(PyObject*self,PyObject*args);staticPyObject*_gfx_aacirclecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_filledcirclecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_ellipsecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_aaellipsecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_filledellipsecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_piecolor(PyObject*self,PyObject*args);staticPyObject*_gfx_trigoncolor(PyObject*self,PyObject*args);staticPyObject*_gfx_aatrigoncolor(PyObject*self,PyObject*args);staticPyObject*_gfx_filledtrigoncolor(PyObject*self,PyObject*args);staticPyObject*_gfx_polygoncolor(PyObject*self,PyObject*args);staticPyObject*_gfx_aapolygoncolor(PyObject*self,PyObject*args);staticPyObject*_gfx_filledpolygoncolor(PyObject*self,PyObject*args);staticPyObject*_gfx_texturedpolygon(PyObject*self,PyObject*args);staticPyObject*_gfx_beziercolor(PyObject*self,PyObject*args);staticPyMethodDef_gfxdraw_methods[]={{"pixel",_gfx_pixelcolor,METH_VARARGS,DOC_PYGAMEGFXDRAWPIXEL},{"hline",_gfx_hlinecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWHLINE},{"vline",_gfx_vlinecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWVLINE},{"rectangle",_gfx_rectanglecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWRECTANGLE},{"box",_gfx_boxcolor,METH_VARARGS,DOC_PYGAMEGFXDRAWRECTANGLE},{"line",_gfx_linecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWLINE},{"circle",_gfx_circlecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWCIRCLE},{"arc",_gfx_arccolor,METH_VARARGS,DOC_PYGAMEGFXDRAWARC},{"aacircle",_gfx_aacirclecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWAACIRCLE},{"filled_circle",_gfx_filledcirclecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWFILLEDCIRCLE},{"ellipse",_gfx_ellipsecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWELLIPSE},{"aaellipse",_gfx_aaellipsecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWAAELLIPSE},{"filled_ellipse",_gfx_filledellipsecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWFILLEDELLIPSE},{"pie",_gfx_piecolor,METH_VARARGS,DOC_PYGAMEGFXDRAWPIE},{"trigon",_gfx_trigoncolor,METH_VARARGS,DOC_PYGAMEGFXDRAWTRIGON},{"aatrigon",_gfx_aatrigoncolor,METH_VARARGS,DOC_PYGAMEGFXDRAWAATRIGON},{"filled_trigon",_gfx_filledtrigoncolor,METH_VARARGS,DOC_PYGAMEGFXDRAWFILLEDTRIGON},{"polygon",_gfx_polygoncolor,METH_VARARGS,DOC_PYGAMEGFXDRAWPOLYGON},{"aapolygon",_gfx_aapolygoncolor,METH_VARARGS,DOC_PYGAMEGFXDRAWAAPOLYGON},{"filled_polygon",_gfx_filledpolygoncolor,METH_VARARGS,DOC_PYGAMEGFXDRAWFILLEDPOLYGON},{"textured_polygon",_gfx_texturedpolygon,METH_VARARGS,DOC_PYGAMEGFXDRAWTEXTUREDPOLYGON},{"bezier",_gfx_beziercolor,METH_VARARGS,DOC_PYGAMEGFXDRAWBEZIER},{NULL,NULL,0,NULL},};#define ASSERT_VIDEO_INIT(unused) /* Is video really needed for gfxdraw? */staticintSint16FromObj(PyObject*item,Sint16*val){PyObject*intobj;longtmp;if(PyNumber_Check(item)){if(!(intobj=PyNumber_Int(item)))return0;tmp=PyInt_AsLong(intobj);Py_DECREF(intobj);if(tmp==-1&&PyErr_Occurred())return0;*val=(Sint16)tmp;return1;}return0;}staticintSint16FromSeqIndex(PyObject*obj,Py_ssize_t_index,Sint16*val){intresult=0;PyObject*item;item=PySequence_GetItem(obj,_index);if(item){result=Sint16FromObj(item,val);Py_DECREF(item);}returnresult;}staticPyObject*_gfx_pixelcolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhO:pixel",&surface,&x,&y,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(pixelRGBA(PySurface_AsSurface(surface),x,y,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_hlinecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x1,x2,y;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhO:hline",&surface,&x1,&x2,&y,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(hlineRGBA(PySurface_AsSurface(surface),x1,x2,y,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_vlinecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,_y1,y2;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhO:vline",&surface,&x,&_y1,&y2,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(vlineRGBA(PySurface_AsSurface(surface),x,_y1,y2,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_rectanglecolor(PyObject*self,PyObject*args){PyObject*surface,*color,*rect;GAME_Recttemprect,*sdlrect;Sint16x1,x2,_y1,y2;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OOO:rectangle",&surface,&rect,&color)){returnNULL;}if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}sdlrect=GameRect_FromObject(rect,&temprect);if(sdlrect==NULL){returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}x1=sdlrect->x;_y1=sdlrect->y;x2=(Sint16)(sdlrect->x+sdlrect->w-1);y2=(Sint16)(sdlrect->y+sdlrect->h-1);if(rectangleRGBA(PySurface_AsSurface(surface),x1,_y1,x2,y2,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_boxcolor(PyObject*self,PyObject*args){PyObject*surface,*color,*rect;GAME_Recttemprect,*sdlrect;Sint16x1,x2,_y1,y2;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OOO:box",&surface,&rect,&color)){returnNULL;}if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}sdlrect=GameRect_FromObject(rect,&temprect);if(sdlrect==NULL){returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}x1=sdlrect->x;_y1=sdlrect->y;x2=(Sint16)(sdlrect->x+sdlrect->w-1);y2=(Sint16)(sdlrect->y+sdlrect->h-1);if(boxRGBA(PySurface_AsSurface(surface),x1,_y1,x2,y2,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_linecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x1,x2,_y1,y2;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhO:line",&surface,&x1,&_y1,&x2,&y2,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(lineRGBA(PySurface_AsSurface(surface),x1,_y1,x2,y2,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_circlecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,r;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhO:circle",&surface,&x,&y,&r,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(circleRGBA(PySurface_AsSurface(surface),x,y,r,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_arccolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,r,start,end;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhhO:arc",&surface,&x,&y,&r,&start,&end,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(arcRGBA(PySurface_AsSurface(surface),x,y,r,start,end,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_aacirclecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,r;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhO:aacircle",&surface,&x,&y,&r,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(aacircleRGBA(PySurface_AsSurface(surface),x,y,r,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_filledcirclecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,r;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhO:filledcircle",&surface,&x,&y,&r,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(filledCircleRGBA(PySurface_AsSurface(surface),x,y,r,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_ellipsecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,rx,ry;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhO:ellipse",&surface,&x,&y,&rx,&ry,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(ellipseRGBA(PySurface_AsSurface(surface),x,y,rx,ry,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_aaellipsecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,rx,ry;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhO:aaellipse",&surface,&x,&y,&rx,&ry,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(aaellipseRGBA(PySurface_AsSurface(surface),x,y,rx,ry,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_filledellipsecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,rx,ry;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhO:filled_ellipse",&surface,&x,&y,&rx,&ry,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(filledEllipseRGBA(PySurface_AsSurface(surface),x,y,rx,ry,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_piecolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x,y,r,start,end;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhhO:pie",&surface,&x,&y,&r,&start,&end,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(pieRGBA(PySurface_AsSurface(surface),x,y,r,start,end,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_trigoncolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x1,x2,x3,_y1,y2,y3;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhhhO:trigon",&surface,&x1,&_y1,&x2,&y2,&x3,&y3,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(trigonRGBA(PySurface_AsSurface(surface),x1,_y1,x2,y2,x3,y3,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_aatrigoncolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x1,x2,x3,_y1,y2,y3;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhhhO:aatrigon",&surface,&x1,&_y1,&x2,&y2,&x3,&y3,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(aatrigonRGBA(PySurface_AsSurface(surface),x1,_y1,x2,y2,x3,y3,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_filledtrigoncolor(PyObject*self,PyObject*args){PyObject*surface,*color;Sint16x1,x2,x3,_y1,y2,y3;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OhhhhhhO:filled_trigon",&surface,&x1,&_y1,&x2,&y2,&x3,&y3,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(filledTrigonRGBA(PySurface_AsSurface(surface),x1,_y1,x2,y2,x3,y3,rgba[0],rgba[1],rgba[2],rgba[3])==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_polygoncolor(PyObject*self,PyObject*args){PyObject*surface,*color,*points,*item;Sint16*vx,*vy,x,y;Py_ssize_tcount,i;intret;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OOO:polygon",&surface,&points,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(!PySequence_Check(points)){PyErr_SetString(PyExc_TypeError,"points must be a sequence");returnNULL;}count=PySequence_Size(points);if(count<3){PyErr_SetString(PyExc_ValueError,"points must contain more than 2 points");returnNULL;}vx=PyMem_New(Sint16,(size_t)count);vy=PyMem_New(Sint16,(size_t)count);if(!vx||!vy){if(vx)PyMem_Free(vx);if(vy)PyMem_Free(vy);returnNULL;}for(i=0;i<count;i++){item=PySequence_ITEM(points,i);if(!Sint16FromSeqIndex(item,0,&x)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}if(!Sint16FromSeqIndex(item,1,&y)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}Py_DECREF(item);vx[i]=x;vy[i]=y;}Py_BEGIN_ALLOW_THREADS;ret=polygonRGBA(PySurface_AsSurface(surface),vx,vy,(int)count,rgba[0],rgba[1],rgba[2],rgba[3]);Py_END_ALLOW_THREADS;PyMem_Free(vx);PyMem_Free(vy);if(ret==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_aapolygoncolor(PyObject*self,PyObject*args){PyObject*surface,*color,*points,*item;Sint16*vx,*vy,x,y;Py_ssize_tcount,i;intret;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OOO:aapolygon",&surface,&points,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(!PySequence_Check(points)){PyErr_SetString(PyExc_TypeError,"points must be a sequence");returnNULL;}count=PySequence_Size(points);if(count<3){PyErr_SetString(PyExc_ValueError,"points must contain more than 2 points");returnNULL;}vx=PyMem_New(Sint16,(size_t)count);vy=PyMem_New(Sint16,(size_t)count);if(!vx||!vy){if(vx)PyMem_Free(vx);if(vy)PyMem_Free(vy);returnNULL;}for(i=0;i<count;i++){item=PySequence_ITEM(points,i);if(!Sint16FromSeqIndex(item,0,&x)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}if(!Sint16FromSeqIndex(item,1,&y)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}Py_DECREF(item);vx[i]=x;vy[i]=y;}Py_BEGIN_ALLOW_THREADS;ret=aapolygonRGBA(PySurface_AsSurface(surface),vx,vy,(int)count,rgba[0],rgba[1],rgba[2],rgba[3]);Py_END_ALLOW_THREADS;PyMem_Free(vx);PyMem_Free(vy);if(ret==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_filledpolygoncolor(PyObject*self,PyObject*args){PyObject*surface,*color,*points,*item;Sint16*vx,*vy,x,y;Py_ssize_tcount,i;intret;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OOO:filled_polygon",&surface,&points,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(!PySequence_Check(points)){PyErr_SetString(PyExc_TypeError,"points must be a sequence");returnNULL;}count=PySequence_Size(points);if(count<3){PyErr_SetString(PyExc_ValueError,"points must contain more than 2 points");returnNULL;}vx=PyMem_New(Sint16,(size_t)count);vy=PyMem_New(Sint16,(size_t)count);if(!vx||!vy){if(vx)PyMem_Free(vx);if(vy)PyMem_Free(vy);returnNULL;}for(i=0;i<count;i++){item=PySequence_ITEM(points,i);if(!Sint16FromSeqIndex(item,0,&x)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}if(!Sint16FromSeqIndex(item,1,&y)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}Py_DECREF(item);vx[i]=x;vy[i]=y;}Py_BEGIN_ALLOW_THREADS;ret=filledPolygonRGBA(PySurface_AsSurface(surface),vx,vy,(int)count,rgba[0],rgba[1],rgba[2],rgba[3]);Py_END_ALLOW_THREADS;PyMem_Free(vx);PyMem_Free(vy);if(ret==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_texturedpolygon(PyObject*self,PyObject*args){PyObject*surface,*texture,*points,*item;SDL_Surface*s_surface,*s_texture;Sint16*vx,*vy,x,y,tdx,tdy;Py_ssize_tcount,i;intret;ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OOOhh:textured_polygon",&surface,&points,&texture,&tdx,&tdy))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}s_surface=PySurface_AsSurface(surface);if(!PySurface_Check(texture)){PyErr_SetString(PyExc_TypeError,"texture must be a Surface");returnNULL;}s_texture=PySurface_AsSurface(texture);if(!PySequence_Check(points)){PyErr_SetString(PyExc_TypeError,"points must be a sequence");returnNULL;}if(s_surface->format->BytesPerPixel==1&&(s_texture->format->Amask||s_texture->flags&SDL_SRCALPHA)){PyErr_SetString(PyExc_ValueError,"Per-byte alpha texture unsupported ""for 8 bit surfaces");returnNULL;}count=PySequence_Size(points);if(count<3){PyErr_SetString(PyExc_ValueError,"points must contain more than 2 points");returnNULL;}vx=PyMem_New(Sint16,(size_t)count);vy=PyMem_New(Sint16,(size_t)count);if(!vx||!vy){if(vx)PyMem_Free(vx);if(vy)PyMem_Free(vy);returnNULL;}for(i=0;i<count;i++){item=PySequence_ITEM(points,i);if(!Sint16FromSeqIndex(item,0,&x)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}if(!Sint16FromSeqIndex(item,1,&y)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}Py_DECREF(item);vx[i]=x;vy[i]=y;}Py_BEGIN_ALLOW_THREADS;ret=texturedPolygon(s_surface,vx,vy,(int)count,s_texture,tdx,tdy);Py_END_ALLOW_THREADS;PyMem_Free(vx);PyMem_Free(vy);if(ret==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}staticPyObject*_gfx_beziercolor(PyObject*self,PyObject*args){PyObject*surface,*color,*points,*item;Sint16*vx,*vy,x,y;Py_ssize_tcount,i;intret,steps;Uint8rgba[4];ASSERT_VIDEO_INIT(NULL);if(!PyArg_ParseTuple(args,"OOiO:bezier",&surface,&points,&steps,&color))returnNULL;if(!PySurface_Check(surface)){PyErr_SetString(PyExc_TypeError,"surface must be a Surface");returnNULL;}if(!RGBAFromObj(color,rgba)){PyErr_SetString(PyExc_TypeError,"invalid color argument");returnNULL;}if(!PySequence_Check(points)){PyErr_SetString(PyExc_TypeError,"points must be a sequence");returnNULL;}count=PySequence_Size(points);if(count<3){PyErr_SetString(PyExc_ValueError,"points must contain more than 2 points");returnNULL;}vx=PyMem_New(Sint16,(size_t)count);vy=PyMem_New(Sint16,(size_t)count);if(!vx||!vy){PyErr_SetString(PyExc_MemoryError,"memory allocation failed");if(vx)PyMem_Free(vx);if(vy)PyMem_Free(vy);returnNULL;}for(i=0;i<count;i++){item=PySequence_ITEM(points,i);if(!Sint16FromSeqIndex(item,0,&x)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}if(!Sint16FromSeqIndex(item,1,&y)){PyMem_Free(vx);PyMem_Free(vy);Py_XDECREF(item);returnNULL;}Py_DECREF(item);vx[i]=x;vy[i]=y;}Py_BEGIN_ALLOW_THREADS;ret=bezierRGBA(PySurface_AsSurface(surface),vx,vy,(int)count,steps,rgba[0],rgba[1],rgba[2],rgba[3]);Py_END_ALLOW_THREADS;PyMem_Free(vx);PyMem_Free(vy);if(ret==-1){PyErr_SetString(PyExc_SDLError,SDL_GetError());returnNULL;}Py_RETURN_NONE;}MODINIT_DEFINE(gfxdraw){PyObject*module;#if PY3staticstructPyModuleDef_module={PyModuleDef_HEAD_INIT,MODPREFIX"gfxdraw",DOC_PYGAMEGFXDRAW,-1,_gfxdraw_methods,NULL,NULL,NULL,NULL};#endif/* importe needed apis; Do this first so if there is an error the module is not loaded. */import_pygame_base();if(PyErr_Occurred()){MODINIT_ERROR;}import_pygame_color();if(PyErr_Occurred()){MODINIT_ERROR;}import_pygame_rect();if(PyErr_Occurred()){MODINIT_ERROR;}import_pygame_surface();if(PyErr_Occurred()){MODINIT_ERROR;}#if PY3module=PyModule_Create(&_module);#elsemodule=Py_InitModule3(MODPREFIX"gfxdraw",_gfxdraw_methods,DOC_PYGAMEGFXDRAW);#endifMODINIT_RETURN(module);}