~ubuntu-branches/ubuntu/gutsy/pygame/gutsy

« back to all changes in this revision

Viewing changes to src/surface.c

  • Committer: Bazaar Package Importer
  • Author(s): Ed Boraas
  • Date: 2002-02-20 06:39:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020220063924-amlzj7tqkeods4eq
Tags: upstream-1.4
ImportĀ upstreamĀ versionĀ 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    pygame - Python Game Library
 
3
    Copyright (C) 2000-2001  Pete Shinners
 
4
 
 
5
    This library is free software; you can redistribute it and/or
 
6
    modify it under the terms of the GNU Library General Public
 
7
    License as published by the Free Software Foundation; either
 
8
    version 2 of the License, or (at your option) any later version.
 
9
 
 
10
    This library is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
    Library General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU Library General Public
 
16
    License along with this library; if not, write to the Free
 
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
    Pete Shinners
 
20
    pete@shinners.org
 
21
*/
 
22
 
 
23
/*
 
24
 *  pygame Surface module
 
25
 */
 
26
#define PYGAMEAPI_SURFACE_INTERNAL
 
27
#include "pygame.h"
 
28
 
 
29
 
 
30
staticforward PyTypeObject PySurface_Type;
 
31
static PyObject* PySurface_New(SDL_Surface* info);
 
32
#define PySurface_Check(x) ((x)->ob_type == &PySurface_Type)
 
33
 
 
34
 
 
35
 
 
36
/* surface object methods */
 
37
 
 
38
 
 
39
    /*DOC*/ static char doc_surf_get_at[] =
 
40
    /*DOC*/    "Surface.get_at(position) -> RGBA\n"
 
41
    /*DOC*/    "get a pixel color\n"
 
42
    /*DOC*/    "\n"
 
43
    /*DOC*/    "Returns the RGB color values at a given pixel. If the\n"
 
44
    /*DOC*/    "Surface has no per-pixel alpha, the alpha will be 255 (opaque).\n"
 
45
    /*DOC*/    "\n"
 
46
    /*DOC*/    "This function will need to temporarily lock the surface.\n"
 
47
    /*DOC*/ ;
 
48
 
 
49
static PyObject* surf_get_at(PyObject* self, PyObject* arg)
 
50
{
 
51
        SDL_Surface* surf = PySurface_AsSurface(self);
 
52
        SDL_PixelFormat* format = surf->format;
 
53
        Uint8* pixels = (Uint8*)surf->pixels;
 
54
        int x, y;
 
55
        Uint32 color;
 
56
        Uint8* pix;
 
57
        Uint8 r, g, b, a;
 
58
 
 
59
        if(!PyArg_ParseTuple(arg, "(ii)", &x, &y))
 
60
                return NULL;
 
61
 
 
62
        if(surf->flags & SDL_OPENGL)
 
63
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
64
 
 
65
        if(x < 0 || x >= surf->w || y < 0 || y >= surf->h)
 
66
                return RAISE(PyExc_IndexError, "pixel index out of range");
 
67
 
 
68
        if(format->BytesPerPixel < 1 || format->BytesPerPixel > 4)
 
69
                return RAISE(PyExc_RuntimeError, "invalid color depth for surface");
 
70
 
 
71
        if(!PySurface_Lock(self)) return NULL;
 
72
        pixels = (Uint8*)surf->pixels;
 
73
 
 
74
        switch(format->BytesPerPixel)
 
75
        {
 
76
                case 1:
 
77
                        color = (Uint32)*((Uint8*)pixels + y * surf->pitch + x);
 
78
                        break;
 
79
                case 2:
 
80
                        color = (Uint32)*((Uint16*)(pixels + y * surf->pitch) + x);
 
81
                        break;
 
82
                case 3:
 
83
                        pix = ((Uint8*)(pixels + y * surf->pitch) + x * 3);
 
84
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
 
85
                        color = (pix[0]) + (pix[1]<<8) + (pix[2]<<16);
 
86
#else
 
87
                        color = (pix[2]) + (pix[1]<<8) + (pix[0]<<16);
 
88
#endif
 
89
                        break;
 
90
                default: /*case 4:*/
 
91
                        color = *((Uint32*)(pixels + y * surf->pitch) + x);
 
92
                        break;
 
93
        }
 
94
        if(!PySurface_Unlock(self)) return NULL;
 
95
 
 
96
        SDL_GetRGBA(color, format, &r, &g, &b, &a);
 
97
        return Py_BuildValue("(bbbb)", r, g, b, a);
 
98
}
 
99
 
 
100
 
 
101
 
 
102
    /*DOC*/ static char doc_surf_set_at[] =
 
103
    /*DOC*/    "Surface.set_at(position, RGBA) -> None\n"
 
104
    /*DOC*/    "set pixel at given position\n"
 
105
    /*DOC*/    "\n"
 
106
    /*DOC*/    "Assigns color to the image at the give position. Color can be a\n"
 
107
    /*DOC*/    "RGBA sequence or a mapped color integer.\n"
 
108
    /*DOC*/    "\n"
 
109
    /*DOC*/    "In some situations just using the fill() function with a one-pixel\n"
 
110
    /*DOC*/    "sized rectangle will be quicker. Also the fill function does not\n"
 
111
    /*DOC*/    "require the surface to be locked.\n"
 
112
    /*DOC*/    "\n"
 
113
    /*DOC*/    "This function will need to temporarily lock the surface.\n"
 
114
    /*DOC*/ ;
 
115
 
 
116
static PyObject* surf_set_at(PyObject* self, PyObject* args)
 
117
{
 
118
        SDL_Surface* surf = PySurface_AsSurface(self);
 
119
        SDL_PixelFormat* format = surf->format;
 
120
        Uint8* pixels;
 
121
        int x, y;
 
122
        Uint32 color;
 
123
        Uint8 rgba[4];
 
124
        PyObject* rgba_obj;
 
125
        Uint8* byte_buf;
 
126
 
 
127
        if(!PyArg_ParseTuple(args, "(ii)O", &x, &y, &rgba_obj))
 
128
                return NULL;
 
129
 
 
130
        if(surf->flags & SDL_OPENGL)
 
131
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
132
 
 
133
        if(x < 0 || x >= surf->w || y < 0 || y >= surf->h)
 
134
        {
 
135
                PyErr_SetString(PyExc_IndexError, "pixel coordinate out of range");
 
136
                return NULL;
 
137
        }
 
138
 
 
139
        if(format->BytesPerPixel < 1 || format->BytesPerPixel > 4)
 
140
                return RAISE(PyExc_RuntimeError, "invalid color depth for surface");
 
141
 
 
142
        if(PyInt_Check(rgba_obj))
 
143
                color = (Uint32)PyInt_AsLong(rgba_obj);
 
144
        else if(RGBAFromObj(rgba_obj, rgba))
 
145
                color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]);
 
146
        else
 
147
                return RAISE(PyExc_TypeError, "invalid color argument");
 
148
 
 
149
        if(!PySurface_Lock(self)) return NULL;
 
150
        pixels = (Uint8*)surf->pixels;
 
151
 
 
152
        switch(format->BytesPerPixel)
 
153
        {
 
154
                case 1:
 
155
                        *((Uint8*)pixels + y * surf->pitch + x) = (Uint8)color;
 
156
                        break;
 
157
                case 2:
 
158
                        *((Uint16*)(pixels + y * surf->pitch) + x) = (Uint16)color;
 
159
                        break;
 
160
                case 3:
 
161
                        byte_buf = (Uint8*)(pixels + y * surf->pitch) + x * 3;
 
162
                        *(byte_buf + (format->Rshift >> 3)) = rgba[0];
 
163
                        *(byte_buf + (format->Gshift >> 3)) = rgba[1];
 
164
                        *(byte_buf + (format->Bshift >> 3)) = rgba[2];  
 
165
                        break;
 
166
                default: /*case 4:*/
 
167
                        *((Uint32*)(pixels + y * surf->pitch) + x) = color;
 
168
                        break;
 
169
        }
 
170
 
 
171
        if(!PySurface_Unlock(self)) return NULL;
 
172
        RETURN_NONE
 
173
}
 
174
 
 
175
 
 
176
 
 
177
    /*DOC*/ static char doc_surf_map_rgb[] =
 
178
    /*DOC*/    "Surface.map_rgb(RGBA) -> int\n"
 
179
    /*DOC*/    "convert RGB into a mapped color\n"
 
180
    /*DOC*/    "\n"
 
181
    /*DOC*/    "Uses the Surface format to convert RGBA into a mapped color value.\n"
 
182
    /*DOC*/    "\n"
 
183
    /*DOC*/    "This function is not as needed as normal C code using SDL. The pygame\n"
 
184
    /*DOC*/    "functions do not used mapped colors, so there is no need to map them.\n"
 
185
   /*DOC*/ ;
 
186
 
 
187
static PyObject* surf_map_rgb(PyObject* self,PyObject* args)
 
188
{
 
189
        SDL_Surface* surf = PySurface_AsSurface(self);
 
190
        Uint8 rgba[4];
 
191
        int color;
 
192
 
 
193
        if(!RGBAFromObj(args, rgba))
 
194
                return RAISE(PyExc_TypeError, "Invalid RGBA argument");
 
195
 
 
196
        color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]);
 
197
        return PyInt_FromLong(color);
 
198
}
 
199
 
 
200
 
 
201
 
 
202
    /*DOC*/ static char doc_surf_unmap_rgb[] =
 
203
    /*DOC*/    "Surface.unmap_rgb(color) -> RGBA\n"
 
204
    /*DOC*/    "convert mapped color into RGB\n"
 
205
    /*DOC*/    "\n"
 
206
    /*DOC*/    "This function returns the RGBA components for a mapped color\n"
 
207
    /*DOC*/    "value. If Surface has no per-pixel alpha, alpha will be 255 (opaque).\n"
 
208
    /*DOC*/    "\n"
 
209
    /*DOC*/    "This function is not as needed as normal C code using SDL. The pygame\n"
 
210
    /*DOC*/    "functions do not used mapped colors, so there is no need to unmap them.\n"
 
211
    /*DOC*/ ;
 
212
 
 
213
static PyObject* surf_unmap_rgb(PyObject* self,PyObject* args)
 
214
{
 
215
        SDL_Surface* surf = PySurface_AsSurface(self);
 
216
        Uint32 col;
 
217
        Uint8 r, g, b, a;
 
218
        
 
219
        if(!PyArg_ParseTuple(args, "i", &col))
 
220
                return NULL;
 
221
 
 
222
        SDL_GetRGBA(col,surf->format, &r, &g, &b, &a);
 
223
 
 
224
        return Py_BuildValue("(bbbb)", r, g, b, a);
 
225
}
 
226
 
 
227
 
 
228
 
 
229
    /*DOC*/ static char doc_surf_lock[] =
 
230
    /*DOC*/    "Surface.lock() -> None\n"
 
231
    /*DOC*/    "locks Surface for pixel access\n"
 
232
    /*DOC*/    "\n"
 
233
    /*DOC*/    "On accelerated surfaces, it is usually required to lock the\n"
 
234
    /*DOC*/    "surface before you can access the pixel values. To be safe, it is\n"
 
235
    /*DOC*/    "always a good idea to lock the surface before entering a block of\n"
 
236
    /*DOC*/    "code that changes or accesses the pixel values. The surface must\n"
 
237
    /*DOC*/    "not be locked when performing other pygame functions on it like\n"
 
238
    /*DOC*/    "fill and blit.\n"
 
239
    /*DOC*/    "\n"
 
240
    /*DOC*/    "You can doublecheck to really make sure a lock is needed by\n"
 
241
    /*DOC*/    "calling the mustlock() member. This should not be needed, since\n"
 
242
    /*DOC*/    "it is usually recommended to lock anyways and work with all\n"
 
243
    /*DOC*/    "surface types. If the surface does not need to be locked, the\n"
 
244
    /*DOC*/    "operation will return quickly with minute overhead.\n"
 
245
    /*DOC*/    "\n"
 
246
    /*DOC*/    "On some platforms a necessary lock can shut off some parts of the\n"
 
247
    /*DOC*/    "system. This is not a problem unless you leave surfaces locked\n"
 
248
    /*DOC*/    "for long periouds of time. Only keep the surface locked when you\n"
 
249
    /*DOC*/    "need the pixel access. At the same time, it is not a good too\n"
 
250
    /*DOC*/    "repeatedly lock and unlock the surface inside tight loops. It is\n"
 
251
    /*DOC*/    "fine to leave the surface locked while needed, just don't be\n"
 
252
    /*DOC*/    "lazy.\n"
 
253
    /*DOC*/ ;
 
254
 
 
255
static PyObject* surf_lock(PyObject* self, PyObject* args)
 
256
{
 
257
        if(!PyArg_ParseTuple(args, ""))
 
258
                return NULL;
 
259
 
 
260
        if(!PySurface_Lock(self))
 
261
                return NULL;
 
262
 
 
263
        RETURN_NONE
 
264
}
 
265
 
 
266
 
 
267
 
 
268
    /*DOC*/ static char doc_surf_unlock[] =
 
269
    /*DOC*/    "Surface.unlock() -> None\n"
 
270
    /*DOC*/    "locks Surface for pixel access\n"
 
271
    /*DOC*/    "\n"
 
272
    /*DOC*/    "After a surface has been locked, you will need to unlock it when\n"
 
273
    /*DOC*/    "you are done.\n"
 
274
    /*DOC*/    "\n"
 
275
    /*DOC*/    "You can doublecheck to really make sure a lock is needed by\n"
 
276
    /*DOC*/    "calling the mustlock() member. This should not be needed, since\n"
 
277
    /*DOC*/    "it is usually recommended to lock anyways and work with all\n"
 
278
    /*DOC*/    "surface types. If the surface does not need to be locked, the\n"
 
279
    /*DOC*/    "operation will return quickly with minute overhead.\n"
 
280
    /*DOC*/ ;
 
281
 
 
282
static PyObject* surf_unlock(PyObject* self, PyObject* args)
 
283
{
 
284
        if(!PyArg_ParseTuple(args, ""))
 
285
                return NULL;
 
286
 
 
287
        if(!PySurface_Unlock(self))
 
288
                return NULL;
 
289
 
 
290
        RETURN_NONE
 
291
}
 
292
 
 
293
 
 
294
 
 
295
    /*DOC*/ static char doc_surf_mustlock[] =
 
296
    /*DOC*/    "Surface.mustlock() -> bool\n"
 
297
    /*DOC*/    "check if the surface needs locking\n"
 
298
    /*DOC*/    "\n"
 
299
    /*DOC*/    "Returns true if the surface really does need locking to gain\n"
 
300
    /*DOC*/    "pixel access. Usually the overhead of checking before locking\n"
 
301
    /*DOC*/    "outweight the overhead of just locking any surface before access.\n"
 
302
    /*DOC*/ ;
 
303
 
 
304
static PyObject* surf_mustlock(PyObject* self, PyObject* args)
 
305
{
 
306
        SDL_Surface* surf = PySurface_AsSurface(self);
 
307
        return PyInt_FromLong(SDL_MUSTLOCK(surf) || ((PySurfaceObject*)self)->subsurface);
 
308
}
 
309
 
 
310
 
 
311
    /*DOC*/ static char doc_surf_get_locked[] =
 
312
    /*DOC*/    "Surface.get_locked() -> bool\n"
 
313
    /*DOC*/    "check if the surface needs locking\n"
 
314
    /*DOC*/    "\n"
 
315
    /*DOC*/    "Returns true if the surface is currently locked.\n"
 
316
    /*DOC*/ ;
 
317
 
 
318
static PyObject* surf_get_locked(PyObject* self, PyObject* args)
 
319
{
 
320
        PySurfaceObject* surf = (PySurfaceObject*)self;
 
321
 
 
322
        if(!PyArg_ParseTuple(args, ""))
 
323
                return NULL;
 
324
        
 
325
        return PyInt_FromLong(surf->lockcount);
 
326
}
 
327
 
 
328
 
 
329
 
 
330
    /*DOC*/ static char doc_surf_get_palette[] =
 
331
    /*DOC*/    "Surface.get_palette() -> [[r, g, b], ...]\n"
 
332
    /*DOC*/    "get the palette\n"
 
333
    /*DOC*/    "\n"
 
334
    /*DOC*/    "This will return the an array of all the color indexes in the\n"
 
335
    /*DOC*/    "Surface's palette.\n"
 
336
    /*DOC*/ ;
 
337
 
 
338
static PyObject* surf_get_palette(PyObject* self, PyObject* args)
 
339
{
 
340
        SDL_Surface* surf = PySurface_AsSurface(self);
 
341
        SDL_Palette* pal = surf->format->palette;
 
342
        PyObject* list;
 
343
        int i;
 
344
                
 
345
        if(!PyArg_ParseTuple(args, ""))
 
346
                return NULL;
 
347
 
 
348
        if(!pal)
 
349
                return RAISE(PyExc_SDLError, "Surface has no palette to get\n");
 
350
 
 
351
        list = PyTuple_New(pal->ncolors);
 
352
        if(!list)
 
353
                return NULL;
 
354
 
 
355
        for(i = 0;i < pal->ncolors;i++)
 
356
        {
 
357
                PyObject* color;
 
358
                SDL_Color* c = &pal->colors[i];
 
359
 
 
360
                color = Py_BuildValue("(bbb)", c->r, c->g, c->b);
 
361
                if(!color)
 
362
                {
 
363
                        Py_DECREF(list);
 
364
                        return NULL;
 
365
                }
 
366
 
 
367
                PyTuple_SET_ITEM(list, i, color);
 
368
        }
 
369
 
 
370
        return list;
 
371
}
 
372
 
 
373
 
 
374
 
 
375
    /*DOC*/ static char doc_surf_get_palette_at[] =
 
376
    /*DOC*/    "Surface.get_palette_at(index) -> r, g, b\n"
 
377
    /*DOC*/    "get a palette entry\n"
 
378
    /*DOC*/    "\n"
 
379
    /*DOC*/    "This will retreive an individual color entry from the Surface's\n"
 
380
    /*DOC*/    "palette.\n"
 
381
    /*DOC*/ ;
 
382
 
 
383
static PyObject* surf_get_palette_at(PyObject* self, PyObject* args)
 
384
{
 
385
        SDL_Surface* surf = PySurface_AsSurface(self);
 
386
        SDL_Palette* pal = surf->format->palette;
 
387
        SDL_Color* c;
 
388
        int index;
 
389
 
 
390
        if(!PyArg_ParseTuple(args, "i", &index))
 
391
                return NULL;
 
392
 
 
393
        if(!pal)
 
394
                return RAISE(PyExc_SDLError, "Surface has no palette to set\n");
 
395
        if(index >= pal->ncolors || index < 0)
 
396
                return RAISE(PyExc_IndexError, "index out of bounds");
 
397
 
 
398
        c = &pal->colors[index];
 
399
        return Py_BuildValue("(bbb)", c->r, c->g, c->b);
 
400
}
 
401
 
 
402
 
 
403
 
 
404
    /*DOC*/ static char doc_surf_set_palette[] =
 
405
    /*DOC*/    "Surface.set_palette([[r, g, b], ...]) -> None\n"
 
406
    /*DOC*/    "set the palette\n"
 
407
    /*DOC*/    "\n"
 
408
    /*DOC*/    "This will replace the entire palette with color\n"
 
409
    /*DOC*/    "information you provide.\n"
 
410
    /*DOC*/    "\n"
 
411
    /*DOC*/    "You can pass an incomplete list of RGB values, and\n"
 
412
    /*DOC*/    "this will only change the first colors in the palette.\n"
 
413
    /*DOC*/ ;
 
414
 
 
415
static PyObject* surf_set_palette(PyObject* self, PyObject* args)
 
416
{
 
417
        SDL_Surface* surf = PySurface_AsSurface(self);
 
418
        SDL_Palette* pal = surf->format->palette;
 
419
        SDL_Color* colors;
 
420
        PyObject* list, *item;
 
421
        int i, len;
 
422
        short r, g, b;
 
423
        
 
424
        if(!PyArg_ParseTuple(args, "O", &list))
 
425
                return NULL;
 
426
        if(!PySequence_Check(list))
 
427
                return RAISE(PyExc_ValueError, "Argument must be a sequence type");
 
428
 
 
429
        if(!pal)
 
430
                return RAISE(PyExc_SDLError, "Surface has no palette\n");
 
431
 
 
432
        if(!SDL_WasInit(SDL_INIT_VIDEO))
 
433
                return RAISE(PyExc_SDLError, "cannot set palette without pygame.display initialized");
 
434
 
 
435
        len = min(pal->ncolors, PySequence_Length(list));
 
436
 
 
437
        colors = (SDL_Color*)malloc(len * sizeof(SDL_Color));
 
438
        if(!colors)
 
439
                return NULL;
 
440
        
 
441
        for(i = 0; i < len; i++)
 
442
        {
 
443
                item = PySequence_GetItem(list, i);
 
444
 
 
445
                if(!PySequence_Check(item) || PySequence_Length(item) != 3)
 
446
                {
 
447
                        Py_DECREF(item);
 
448
                        free((char*)colors);
 
449
                        return RAISE(PyExc_TypeError, "takes a sequence of sequence of RGB");
 
450
                }
 
451
                if(!ShortFromObjIndex(item, 0, &r) || !ShortFromObjIndex(item, 1, &g) || !ShortFromObjIndex(item, 2, &b))
 
452
                        return RAISE(PyExc_TypeError, "RGB sequence must contain numeric values");
 
453
 
 
454
                colors[i].r = (unsigned char)r;
 
455
                colors[i].g = (unsigned char)g;
 
456
                colors[i].b = (unsigned char)b;
 
457
                Py_DECREF(item);
 
458
        }
 
459
 
 
460
        SDL_SetColors(surf, colors, 0, len);
 
461
        free((char*)colors);
 
462
        RETURN_NONE
 
463
}
 
464
 
 
465
 
 
466
 
 
467
    /*DOC*/ static char doc_surf_set_palette_at[] =
 
468
    /*DOC*/    "Surface.set_palette_at(index, [r, g, b]) -> None\n"
 
469
    /*DOC*/    "set a palette entry\n"
 
470
    /*DOC*/    "\n"
 
471
    /*DOC*/    "This function sets the palette color at a specific entry.\n"
 
472
    /*DOC*/ ;
 
473
 
 
474
static PyObject* surf_set_palette_at(PyObject* self, PyObject* args)
 
475
{
 
476
        SDL_Surface* surf = PySurface_AsSurface(self);
 
477
        SDL_Palette* pal = surf->format->palette;
 
478
        SDL_Color color;
 
479
        int index;
 
480
        Uint8 r, g, b;
 
481
 
 
482
        if(!PyArg_ParseTuple(args, "i(bbb)", &index, &r, &g, &b))
 
483
                return NULL;
 
484
 
 
485
        if(!pal)
 
486
        {
 
487
                PyErr_SetString(PyExc_SDLError, "Surface is not palettized\n");
 
488
                return NULL;
 
489
        }
 
490
 
 
491
        if(index >= pal->ncolors || index <= 0)
 
492
        {
 
493
                PyErr_SetString(PyExc_IndexError, "index out of bounds");
 
494
                return NULL;
 
495
        }
 
496
 
 
497
        if(!SDL_WasInit(SDL_INIT_VIDEO))
 
498
                return RAISE(PyExc_SDLError, "cannot set palette without pygame.display initialized");
 
499
 
 
500
        color.r = r;
 
501
        color.g = g;
 
502
        color.b = b;
 
503
 
 
504
        SDL_SetColors(surf, &color, index, 1);
 
505
 
 
506
        RETURN_NONE
 
507
}
 
508
 
 
509
 
 
510
 
 
511
    /*DOC*/ static char doc_surf_set_colorkey[] =
 
512
    /*DOC*/    "Surface.set_colorkey([color, [flags]]) -> None\n"
 
513
    /*DOC*/    "change colorkey information\n"
 
514
    /*DOC*/    "\n"
 
515
    /*DOC*/    "Set the colorkey for the surface by passing a mapped color value\n"
 
516
    /*DOC*/    "as the color argument. If no arguments or None is passed,\n"
 
517
    /*DOC*/    "colorkeying will be disabled for this surface.\n"
 
518
    /*DOC*/    "\n"
 
519
    /*DOC*/    "The color argument can be either a RGBA sequence or a mapped integer.\n"
 
520
    /*DOC*/    "\n"
 
521
    /*DOC*/    "If your image is nonchanging and will be used repeatedly, you\n"
 
522
    /*DOC*/    "will probably want to pass the RLEACCEL flag to the call. This\n"
 
523
    /*DOC*/    "will take a short time to compile your surface, and increase the\n"
 
524
    /*DOC*/    "blitting speed.\n"
 
525
    /*DOC*/ ;
 
526
 
 
527
static PyObject* surf_set_colorkey(PyObject* self, PyObject* args)
 
528
{
 
529
        SDL_Surface* surf = PySurface_AsSurface(self);
 
530
        Uint32 flags = 0, color = 0;
 
531
        PyObject* rgba_obj = NULL, *intobj = NULL;
 
532
        Uint8 rgba[4];
 
533
        int result, hascolor=0;
 
534
 
 
535
        if(!PyArg_ParseTuple(args, "|Oi", &rgba_obj, &flags))
 
536
                return NULL;
 
537
 
 
538
        if(surf->flags & SDL_OPENGL)
 
539
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
540
 
 
541
        if(rgba_obj && rgba_obj!=Py_None)
 
542
        {
 
543
                if(PyNumber_Check(rgba_obj) && (intobj=PyNumber_Int(rgba_obj)))
 
544
                {
 
545
                        color = (Uint32)PyInt_AsLong(intobj);
 
546
                        Py_DECREF(intobj);
 
547
                }
 
548
                else if(RGBAFromObj(rgba_obj, rgba))
 
549
                        color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]);
 
550
                else
 
551
                        return RAISE(PyExc_TypeError, "invalid color argument");
 
552
                hascolor = 1;
 
553
        }
 
554
        if(hascolor)
 
555
                flags |= SDL_SRCCOLORKEY;
 
556
 
 
557
        PySurface_Prep(self);
 
558
        result = SDL_SetColorKey(surf, flags, color);
 
559
        PySurface_Unprep(self);
 
560
 
 
561
        if(result == -1)
 
562
                return RAISE(PyExc_SDLError, SDL_GetError());
 
563
        
 
564
        RETURN_NONE
 
565
}
 
566
 
 
567
 
 
568
    /*DOC*/ static char doc_surf_get_colorkey[] =
 
569
    /*DOC*/    "Surface.get_colorkey() -> RGBA\n"
 
570
    /*DOC*/    "query colorkey\n"
 
571
    /*DOC*/    "\n"
 
572
    /*DOC*/    "Returns the current mapped color value being used for\n"
 
573
    /*DOC*/    "colorkeying. If colorkeying is not enabled for this surface, it\n"
 
574
    /*DOC*/    "returns None\n"
 
575
    /*DOC*/ ;
 
576
 
 
577
static PyObject* surf_get_colorkey(PyObject* self, PyObject* args)
 
578
{
 
579
        SDL_Surface* surf = PySurface_AsSurface(self);
 
580
        Uint8 r, g, b, a;
 
581
 
 
582
        if(!PyArg_ParseTuple(args, ""))
 
583
                return NULL;
 
584
        
 
585
        if(surf->flags & SDL_OPENGL)
 
586
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
587
 
 
588
        if(!(surf->flags&SDL_SRCCOLORKEY))
 
589
                RETURN_NONE
 
590
 
 
591
        SDL_GetRGBA(surf->format->colorkey, surf->format, &r, &g, &b, &a);
 
592
        return Py_BuildValue("(bbbb)", r, g, b, a);
 
593
}
 
594
 
 
595
 
 
596
    /*DOC*/ static char doc_surf_set_alpha[] =
 
597
    /*DOC*/    "Surface.set_alpha([alpha, [flags]]) -> None\n"
 
598
    /*DOC*/    "change alpha information\n"
 
599
    /*DOC*/    "\n"
 
600
    /*DOC*/    "Set the overall transparency for the surface. If no alpha is\n"
 
601
    /*DOC*/    "passed, alpha blending is disabled for the surface. An alpha of 0\n"
 
602
    /*DOC*/    "is fully transparent, an alpha of 255 is fully opaque. If no\n"
 
603
    /*DOC*/    "arguments or None is passed, this will disable the surface alpha.\n"
 
604
    /*DOC*/    "\n"
 
605
    /*DOC*/    "If your surface has a pixel alpha channel, it will override the\n"
 
606
    /*DOC*/    "overall surface transparency. You'll need to change the actual\n"
 
607
    /*DOC*/    "pixel transparency to make changes.\n"
 
608
    /*DOC*/    "\n"
 
609
    /*DOC*/    "If your image also has pixel alpha values, will be used repeatedly, you\n"
 
610
    /*DOC*/    "will probably want to pass the RLEACCEL flag to the call. This\n"
 
611
    /*DOC*/    "will take a short time to compile your surface, and increase the\n"
 
612
    /*DOC*/    "blitting speed.\n"
 
613
    /*DOC*/ ;
 
614
 
 
615
static PyObject* surf_set_alpha(PyObject* self, PyObject* args)
 
616
{
 
617
        SDL_Surface* surf = PySurface_AsSurface(self);
 
618
        Uint32 flags = 0;
 
619
        PyObject* alpha_obj = NULL, *intobj=NULL;
 
620
        Uint8 alpha;
 
621
        int result, alphaval=0, hasalpha=0;
 
622
 
 
623
        if(!PyArg_ParseTuple(args, "|Oi", &alpha_obj, &flags))
 
624
                return NULL;
 
625
 
 
626
        if(surf->flags & SDL_OPENGL)
 
627
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
628
 
 
629
        if(alpha_obj && alpha_obj!=Py_None)
 
630
        {
 
631
                if(PyNumber_Check(alpha_obj) && (intobj=PyNumber_Int(alpha_obj)))
 
632
                {
 
633
                        alphaval = (int)PyInt_AsLong(intobj);
 
634
                        Py_DECREF(intobj);
 
635
                }
 
636
                else
 
637
                        return RAISE(PyExc_TypeError, "invalid alpha argument");
 
638
                hasalpha = 1;
 
639
        }
 
640
        if(hasalpha)
 
641
                flags |= SDL_SRCALPHA;
 
642
 
 
643
        if(alphaval>255) alpha = 255;
 
644
        else if(alphaval<0) alpha = 0;
 
645
        else alpha = (Uint8)alphaval;
 
646
 
 
647
        PySurface_Prep(self);
 
648
        result = SDL_SetAlpha(surf, flags, alpha);
 
649
        PySurface_Unprep(self);
 
650
                
 
651
        if(result == -1)
 
652
                return RAISE(PyExc_SDLError, SDL_GetError());
 
653
        
 
654
        RETURN_NONE
 
655
}
 
656
 
 
657
 
 
658
    /*DOC*/ static char doc_surf_get_alpha[] =
 
659
    /*DOC*/    "Surface.get_alpha() -> alpha\n"
 
660
    /*DOC*/    "query alpha information\n"
 
661
    /*DOC*/    "\n"
 
662
    /*DOC*/    "Returns the current alpha value for the Surface. If transparency\n"
 
663
    /*DOC*/    "is disabled for the Surface, it returns None.\n"
 
664
    /*DOC*/ ;
 
665
 
 
666
static PyObject* surf_get_alpha(PyObject* self, PyObject* args)
 
667
{
 
668
        SDL_Surface* surf = PySurface_AsSurface(self);
 
669
 
 
670
        if(!PyArg_ParseTuple(args, ""))
 
671
                return NULL;
 
672
        
 
673
        if(surf->flags & SDL_OPENGL)
 
674
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
675
 
 
676
        if(surf->flags&SDL_SRCALPHA)
 
677
                return PyInt_FromLong(surf->format->alpha);
 
678
 
 
679
        RETURN_NONE
 
680
}
 
681
 
 
682
 
 
683
    /*DOC*/ static char doc_surf_convert[] =
 
684
    /*DOC*/    "Surface.convert([src_surface] OR depth, [flags] OR masks) -> Surface\n"
 
685
    /*DOC*/    "new copy of surface with different format\n"
 
686
    /*DOC*/    "\n"
 
687
    /*DOC*/    "Creates a new copy of the surface with the desired pixel format.\n"
 
688
    /*DOC*/    "Surfaces with the same pixel format will blit much faster than\n"
 
689
    /*DOC*/    "those with mixed formats. The pixel format of the new surface\n"
 
690
    /*DOC*/    "will match the format given as the argument. If no surface is\n"
 
691
    /*DOC*/    "given, the new surface will have the same pixel format as the\n"
 
692
    /*DOC*/    "current display.\n"
 
693
    /*DOC*/    "\n"
 
694
    /*DOC*/    "convert() will also accept bitsize or mask arguments like the\n"
 
695
    /*DOC*/    "Surface() constructor function. Either pass an integer bitsize\n"
 
696
    /*DOC*/    "or a sequence of color masks to specify the format of surface\n"
 
697
    /*DOC*/    "you would like to convert to. When used this way you may also\n"
 
698
    /*DOC*/    "pass an optional flags argument (whew).\n"
 
699
    /*DOC*/ ;
 
700
 
 
701
static PyObject* surf_convert(PyObject* self, PyObject* args)
 
702
{
 
703
        SDL_Surface* surf = PySurface_AsSurface(self);
 
704
        PyObject* final;
 
705
        PyObject* argobject=NULL;
 
706
        SDL_Surface* src;
 
707
        SDL_Surface* newsurf;
 
708
        Uint32 flags=-1;
 
709
 
 
710
        if(!SDL_WasInit(SDL_INIT_VIDEO))
 
711
                return RAISE(PyExc_SDLError, "cannot convert without pygame.display initialized");
 
712
 
 
713
        if(!PyArg_ParseTuple(args, "|Oi", &argobject, &flags))
 
714
                return NULL;
 
715
 
 
716
        PySurface_Prep(self);
 
717
        if(argobject)
 
718
        {
 
719
                if(PySurface_Check(argobject))
 
720
                {
 
721
                        src = PySurface_AsSurface(argobject);
 
722
                        flags = src->flags | (surf->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA));
 
723
                        newsurf = SDL_ConvertSurface(surf, src->format, flags);
 
724
                }
 
725
                else 
 
726
                {
 
727
                        short bpp;
 
728
                        SDL_PixelFormat format;
 
729
                        memcpy(&format, surf->format, sizeof(format));
 
730
                        if(ShortFromObj(argobject, &bpp))
 
731
                        {
 
732
                                int Rmask, Gmask, Bmask, Amask;
 
733
                                if(flags!=-1 && flags&SDL_SRCALPHA)
 
734
                                {
 
735
                                        switch(bpp)
 
736
                                        {
 
737
                                        case 16:
 
738
                                                Rmask = 0xF<<8; Gmask = 0xF<<4; Bmask = 0xF; Amask = 0xF<<12; break;
 
739
                                        case 32:
 
740
                                                Rmask = 0xFF<<16; Gmask = 0xFF<<8; Bmask = 0xFF; Amask = 0xFF<<24; break;
 
741
                                        default:
 
742
                                                return RAISE(PyExc_ValueError, "no standard masks exist for given bitdepth with alpha");
 
743
                                        }
 
744
                                }
 
745
                                else
 
746
                                {
 
747
                                        Amask = 0;
 
748
                                        switch(bpp)
 
749
                                        {
 
750
                                        case 8:
 
751
                                                Rmask = 0xFF>>6<<5; Gmask = 0xFF>>5<<2; Bmask = 0xFF>>6; break;
 
752
                                        case 12:
 
753
                                                Rmask = 0xFF>>4<<8; Gmask = 0xFF>>4<<4; Bmask = 0xFF>>4; break;
 
754
                                        case 15:
 
755
                                                Rmask = 0xFF>>3<<10; Gmask = 0xFF>>3<<5; Bmask = 0xFF>>3; break;
 
756
                                        case 16:
 
757
                                                Rmask = 0xFF>>3<<11; Gmask = 0xFF>>2<<5; Bmask = 0xFF>>3; break;
 
758
                                        case 24:
 
759
                                        case 32:
 
760
                                                Rmask = 0xFF << 16; Gmask = 0xFF << 8; Bmask = 0xFF; break;
 
761
                                        default:
 
762
                                                return RAISE(PyExc_ValueError, "nonstandard bit depth given");
 
763
                                        }
 
764
                                }
 
765
                                format.Rmask = Rmask; format.Gmask = Gmask;
 
766
                                format.Bmask = Bmask; format.Amask = Amask;
 
767
                        }
 
768
                        else if(PySequence_Check(argobject) && PySequence_Size(argobject)==4)
 
769
                        {
 
770
                                Uint32 mask;
 
771
                                if(!UintFromObjIndex(argobject, 0, &format.Rmask) ||
 
772
                                                        !UintFromObjIndex(argobject, 1, &format.Gmask) ||
 
773
                                                        !UintFromObjIndex(argobject, 2, &format.Bmask) ||
 
774
                                                        !UintFromObjIndex(argobject, 3, &format.Amask))
 
775
                                {
 
776
                                        PySurface_Unprep(self);
 
777
                                        return RAISE(PyExc_ValueError, "invalid color masks given");
 
778
                                }
 
779
                                mask = format.Rmask|format.Gmask|format.Bmask|format.Amask;
 
780
                                for(bpp=0; bpp<32; ++bpp)
 
781
                                        if(!(mask>>bpp)) break;
 
782
                        }
 
783
                        else
 
784
                        {
 
785
                                PySurface_Unprep(self);
 
786
                                return RAISE(PyExc_ValueError, "invalid argument specifying new format to convert to");
 
787
                        }
 
788
                        format.BitsPerPixel = (Uint8)bpp;
 
789
                        format.BytesPerPixel = (bpp+7)/8;
 
790
                        if(flags == -1)
 
791
                                flags = surf->flags;
 
792
                        if(format.Amask)
 
793
                                flags |= SDL_SRCALPHA;
 
794
                        newsurf = SDL_ConvertSurface(surf, &format, flags);
 
795
                }
 
796
        }
 
797
        else
 
798
        {
 
799
                if(SDL_WasInit(SDL_INIT_VIDEO))
 
800
                        newsurf = SDL_DisplayFormat(surf);
 
801
                else
 
802
                        newsurf = SDL_ConvertSurface(surf, surf->format, surf->flags);
 
803
        }
 
804
        PySurface_Unprep(self);
 
805
 
 
806
        final = PySurface_New(newsurf);
 
807
        if(!final)
 
808
                SDL_FreeSurface(newsurf);
 
809
        return final;
 
810
}
 
811
 
 
812
 
 
813
 
 
814
    /*DOC*/ static char doc_surf_convert_alpha[] =
 
815
    /*DOC*/    "Surface.convert_alpha([src_surface]) -> Surface\n"
 
816
    /*DOC*/    "new copy of surface with different format and per pixel alpha\n"
 
817
    /*DOC*/    "\n"
 
818
    /*DOC*/    "Creates a new copy of the surface with the desired pixel format.\n"
 
819
    /*DOC*/    "The new surface will be in a format suited for quick blitting to\n"
 
820
    /*DOC*/    "the given format with per pixel alpha. If no surface is given,\n"
 
821
    /*DOC*/    "the new surface will be optimized for blittint to the current\n"
 
822
    /*DOC*/    "display.\n"
 
823
    /*DOC*/    "\n"
 
824
    /*DOC*/    "Unlike the convert() method, the pixel format for the new image\n"
 
825
    /*DOC*/    "will not be exactly the same as the requested source, but it will\n"
 
826
    /*DOC*/    "be optimized for fast alpha blitting to the destination.\n"
 
827
    /*DOC*/ ;
 
828
 
 
829
static PyObject* surf_convert_alpha(PyObject* self, PyObject* args)
 
830
{
 
831
        SDL_Surface* surf = PySurface_AsSurface(self);
 
832
        PyObject* final;
 
833
        PySurfaceObject* srcsurf = NULL;
 
834
        SDL_Surface* newsurf, *src;
 
835
        
 
836
        if(!PyArg_ParseTuple(args, "|O!", &PySurface_Type, &srcsurf))
 
837
                return NULL;
 
838
 
 
839
        PySurface_Prep(self);
 
840
        if(srcsurf)
 
841
        {
 
842
                /*hmm, we have to figure this out, not all depths have good support for alpha*/
 
843
                src = PySurface_AsSurface(srcsurf);
 
844
                newsurf = SDL_DisplayFormatAlpha(surf);
 
845
        }
 
846
        else
 
847
                newsurf = SDL_DisplayFormatAlpha(surf);
 
848
        PySurface_Unprep(self);
 
849
 
 
850
        final = PySurface_New(newsurf);
 
851
        if(!final)
 
852
                SDL_FreeSurface(newsurf);
 
853
        return final;
 
854
}
 
855
 
 
856
 
 
857
    /*DOC*/ static char doc_surf_set_clip[] =
 
858
    /*DOC*/    "Surface.set_clip([rectstyle]) -> None\n"
 
859
    /*DOC*/    "assign destination clipping rectangle\n"
 
860
    /*DOC*/    "\n"
 
861
    /*DOC*/    "Assigns the destination clipping rectangle for the Surface. When\n"
 
862
    /*DOC*/    "blit or fill operations are performed on the Surface, they are\n"
 
863
    /*DOC*/    "restricted to the inside of the clipping rectangle. If no\n"
 
864
    /*DOC*/    "rectangle is passed, the clipping region is set to the entire\n"
 
865
    /*DOC*/    "Surface area. The rectangle you pass will be clipped to the area of\n"
 
866
    /*DOC*/    "the Surface.\n"
 
867
    /*DOC*/ ;
 
868
 
 
869
static PyObject* surf_set_clip(PyObject* self, PyObject* args)
 
870
{
 
871
        SDL_Surface* surf = PySurface_AsSurface(self);
 
872
        PyObject* item;
 
873
        GAME_Rect *rect=NULL, temp;
 
874
        int result;
 
875
 
 
876
        if(PyTuple_Size(args))
 
877
        {
 
878
                item = PyTuple_GET_ITEM(args, 0);
 
879
                if(!(item == Py_None && PyTuple_Size(args) == 1))
 
880
                {
 
881
                    rect = GameRect_FromObject(args, &temp);
 
882
                    if(!rect)
 
883
                            return RAISE(PyExc_ValueError, "invalid rectstyle object");
 
884
                }
 
885
        }
 
886
                
 
887
        result = SDL_SetClipRect(surf, (SDL_Rect*)rect);
 
888
        if(result == -1)
 
889
                return RAISE(PyExc_SDLError, SDL_GetError());
 
890
 
 
891
        RETURN_NONE
 
892
}
 
893
 
 
894
 
 
895
 
 
896
    /*DOC*/ static char doc_surf_get_clip[] =
 
897
    /*DOC*/    "Surface.get_clip() -> rect\n"
 
898
    /*DOC*/    "query the clipping area\n"
 
899
    /*DOC*/    "\n"
 
900
    /*DOC*/    "Returns the current destination clipping area being used by the\n"
 
901
    /*DOC*/    "Surface. If the clipping area is not set, it will return a\n"
 
902
    /*DOC*/    "rectangle containing the full Surface area.\n"
 
903
    /*DOC*/ ;
 
904
 
 
905
static PyObject* surf_get_clip(PyObject* self, PyObject* args)
 
906
{
 
907
        SDL_Surface* surf = PySurface_AsSurface(self);
 
908
        return PyRect_New((GAME_Rect*)&surf->clip_rect);
 
909
}
 
910
 
 
911
 
 
912
 
 
913
    /*DOC*/ static char doc_surf_fill[] =
 
914
    /*DOC*/    "Surface.fill(color, [rectstyle])) -> Rect\n"
 
915
    /*DOC*/    "fill areas of a Surface\n"
 
916
    /*DOC*/    "\n"
 
917
    /*DOC*/    "Fills the specified area of the Surface with the mapped color\n"
 
918
    /*DOC*/    "value. If no destination rectangle is supplied, it will fill the\n"
 
919
    /*DOC*/    "entire Surface.\n"
 
920
    /*DOC*/    "\n"
 
921
    /*DOC*/    "The color argument can be a RGBA sequence or a mapped color integer.\n"
 
922
    /*DOC*/    "\n"
 
923
    /*DOC*/    "The fill is subject to be clipped by the active clipping\n"
 
924
    /*DOC*/    "rectangle. The return value contains the actual area filled.\n"
 
925
    /*DOC*/ ;
 
926
 
 
927
static PyObject* surf_fill(PyObject* self, PyObject* args)
 
928
{
 
929
        SDL_Surface* surf = PySurface_AsSurface(self);
 
930
        GAME_Rect *rect, temp;
 
931
        PyObject* r = NULL;
 
932
        Uint32 color;
 
933
        int result;
 
934
        PyObject* rgba_obj;
 
935
        Uint8 rgba[4];
 
936
        
 
937
        if(!PyArg_ParseTuple(args, "O|O", &rgba_obj, &r))
 
938
                return NULL;
 
939
 
 
940
        if(surf->flags & SDL_OPENGL)
 
941
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
942
 
 
943
        if(PyInt_Check(rgba_obj))
 
944
                color = (Uint32)PyInt_AsLong(rgba_obj);
 
945
        else if(RGBAFromObj(rgba_obj, rgba))
 
946
                color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]);
 
947
        else
 
948
                return RAISE(PyExc_TypeError, "invalid color argument");
 
949
 
 
950
        if(!r)
 
951
        {
 
952
                rect = &temp;
 
953
                temp.x = temp.y = (short)0;
 
954
                temp.w = surf->w;
 
955
                temp.h = surf->h;
 
956
        }
 
957
        else if(!(rect = GameRect_FromObject(r, &temp)))
 
958
                return RAISE(PyExc_ValueError, "invalid rectstyle object");
 
959
 
 
960
        /*we need a fresh copy so our Rect values don't get munged*/
 
961
        if(rect != &temp)
 
962
        {
 
963
                memcpy(&temp, rect, sizeof(temp));
 
964
                rect = &temp;
 
965
        }
 
966
 
 
967
        PySurface_Prep(self);
 
968
        result = SDL_FillRect(surf, (SDL_Rect*)rect, color);
 
969
        PySurface_Unprep(self);
 
970
 
 
971
        if(result == -1)
 
972
                return RAISE(PyExc_SDLError, SDL_GetError());
 
973
        return PyRect_New(rect);
 
974
}
 
975
 
 
976
 
 
977
 
 
978
 
 
979
    /*DOC*/ static char doc_surf_blit[] =
 
980
    /*DOC*/    "Surface.blit(source, destpos, [sourcerect]) -> Rect\n"
 
981
    /*DOC*/    "copy a one Surface to another.\n"
 
982
    /*DOC*/    "\n"
 
983
    /*DOC*/    "The blitting will transfer one surface to another. It will\n"
 
984
    /*DOC*/    "respect any special modes like colorkeying and alpha. If hardware\n"
 
985
    /*DOC*/    "support is available, it will be used. The given source is the\n"
 
986
    /*DOC*/    "Surface to copy from. The destoffset is a 2-number-sequence that\n"
 
987
    /*DOC*/    "specifies where on the destination Surface the blit happens (see below).\n"
 
988
    /*DOC*/    "When sourcerect isn't supplied, the blit will copy the\n"
 
989
    /*DOC*/    "entire source surface. If you would like to copy only a portion\n"
 
990
    /*DOC*/    "of the source, use the sourcerect argument to control\n"
 
991
    /*DOC*/    "what area is copied.\n"
 
992
    /*DOC*/    "\n"
 
993
    /*DOC*/    "The blit is subject to be clipped by the active clipping\n"
 
994
    /*DOC*/    "rectangle. The return value contains the actual area blitted.\n"
 
995
    /*DOC*/    "\n"
 
996
    /*DOC*/    "As a shortcut, the destination position can be passed as a\n"
 
997
    /*DOC*/    "rectangle. If a rectangle is given, the blit will use the topleft\n"
 
998
    /*DOC*/    "corner of the rectangle as the blit destination position. The\n"
 
999
    /*DOC*/    "rectangle sizes will be ignored.\n"
 
1000
#if 0  /* "" */
 
1001
    /*DOC*/    "\n"
 
1002
    /*DOC*/    "Note that blitting surfaces with alpha onto 8bit destinations will\n"
 
1003
    /*DOC*/    "not use the surface alpha values.\n"
 
1004
#endif /* "" */
 
1005
    /*DOC*/ ;
 
1006
 
 
1007
static PyObject* surf_blit(PyObject* self, PyObject* args)
 
1008
{
 
1009
        SDL_Surface* src, *dest = PySurface_AsSurface(self);
 
1010
        GAME_Rect* src_rect, temp;
 
1011
        PyObject* srcobject, *argpos, *argrect = NULL;
 
1012
        int dx, dy, result;
 
1013
        SDL_Rect dest_rect;
 
1014
        short sx, sy;
 
1015
        int didconvert = 0;
 
1016
 
 
1017
        if(!PyArg_ParseTuple(args, "O!O|O", &PySurface_Type, &srcobject, &argpos, &argrect))
 
1018
                return NULL;
 
1019
        src = PySurface_AsSurface(srcobject);
 
1020
 
 
1021
        if(dest->flags & SDL_OPENGL && !(dest->flags&(SDL_OPENGLBLIT&~SDL_OPENGL)))
 
1022
                return RAISE(PyExc_SDLError, "Cannot blit to OPENGL Surfaces (OPENGLBLIT is ok)");
 
1023
 
 
1024
        if(dest->format->BytesPerPixel == 1 && (src->flags&SDL_SRCALPHA && src->format->Amask))
 
1025
                return RAISE(PyExc_SDLError, "Alpha blits to 8bit surfaces currently unimplemented");
 
1026
 
 
1027
        if((src_rect = GameRect_FromObject(argpos, &temp)))
 
1028
        {
 
1029
                dx = src_rect->x;
 
1030
                dy = src_rect->y;
 
1031
        }
 
1032
        else if(TwoShortsFromObj(argpos, &sx, &sy))
 
1033
        {
 
1034
                dx = (int)sx;
 
1035
                dy = (int)sy;
 
1036
        }
 
1037
        else
 
1038
                return RAISE(PyExc_TypeError, "invalid destination position for blit");
 
1039
 
 
1040
        if(argrect)
 
1041
        {
 
1042
                if(!(src_rect = GameRect_FromObject(argrect, &temp)))
 
1043
                        return RAISE(PyExc_TypeError, "Invalid rectstyle argument");
 
1044
        }
 
1045
        else
 
1046
        {
 
1047
                temp.x = temp.y = 0;
 
1048
                temp.w = src->w;
 
1049
                temp.h = src->h;
 
1050
                src_rect = &temp;
 
1051
        }
 
1052
 
 
1053
        dest_rect.x = (short)dx;
 
1054
        dest_rect.y = (short)dy;
 
1055
        dest_rect.w = (unsigned short)src_rect->w;
 
1056
        dest_rect.h = (unsigned short)src_rect->h;
 
1057
 
 
1058
        PySurface_Prep(self);
 
1059
        PySurface_Prep(srcobject);
 
1060
        Py_BEGIN_ALLOW_THREADS
 
1061
 
 
1062
        /*can't blit alpha to 8bit, crashes SDL*/
 
1063
        if(dest->format->BytesPerPixel==1 && (src->format->Amask || src->flags&SDL_SRCALPHA))
 
1064
        {
 
1065
                didconvert = 1;
 
1066
                src = SDL_DisplayFormat(src);
 
1067
        }
 
1068
        result = SDL_BlitSurface(src, (SDL_Rect*)src_rect, dest, &dest_rect);
 
1069
        if(didconvert)
 
1070
                SDL_FreeSurface(src);
 
1071
 
 
1072
        Py_END_ALLOW_THREADS
 
1073
        PySurface_Unprep(self);
 
1074
        PySurface_Unprep(srcobject);
 
1075
 
 
1076
 
 
1077
        if(result == -1)
 
1078
                return RAISE(PyExc_SDLError, SDL_GetError());
 
1079
        if(result == -2)
 
1080
                return RAISE(PyExc_SDLError, "Surface was lost");
 
1081
 
 
1082
        return PyRect_New((GAME_Rect*)&dest_rect);
 
1083
}
 
1084
 
 
1085
 
 
1086
    /*DOC*/ static char doc_surf_get_flags[] =
 
1087
    /*DOC*/    "Surface.get_flags() -> flags\n"
 
1088
    /*DOC*/    "query the surface flags\n"
 
1089
    /*DOC*/    "\n"
 
1090
    /*DOC*/    "Returns the current state flags for the surface.\n"
 
1091
    /*DOC*/ ;
 
1092
 
 
1093
static PyObject* surf_get_flags(PyObject* self, PyObject* args)
 
1094
{
 
1095
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1096
        return PyInt_FromLong(surf->flags);
 
1097
}
 
1098
 
 
1099
 
 
1100
 
 
1101
    /*DOC*/ static char doc_surf_get_pitch[] =
 
1102
    /*DOC*/    "Surface.get_pitch() -> pitch\n"
 
1103
    /*DOC*/    "query the surface pitch\n"
 
1104
    /*DOC*/    "\n"
 
1105
    /*DOC*/    "The surface pitch is the number of bytes used in each\n"
 
1106
    /*DOC*/    "scanline. This function should rarely needed, mainly for\n"
 
1107
    /*DOC*/    "any special-case debugging.\n"
 
1108
    /*DOC*/ ;
 
1109
 
 
1110
static PyObject* surf_get_pitch(PyObject* self, PyObject* args)
 
1111
{
 
1112
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1113
        return PyInt_FromLong(surf->pitch);
 
1114
}
 
1115
 
 
1116
 
 
1117
 
 
1118
    /*DOC*/ static char doc_surf_get_size[] =
 
1119
    /*DOC*/    "Surface.get_size() -> x, y\n"
 
1120
    /*DOC*/    "query the surface size\n"
 
1121
    /*DOC*/    "\n"
 
1122
    /*DOC*/    "Returns the width and height of the Surface.\n"
 
1123
    /*DOC*/ ;
 
1124
 
 
1125
static PyObject* surf_get_size(PyObject* self, PyObject* args)
 
1126
{
 
1127
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1128
        return Py_BuildValue("(ii)", surf->w, surf->h);
 
1129
}
 
1130
 
 
1131
 
 
1132
 
 
1133
    /*DOC*/ static char doc_surf_get_width[] =
 
1134
    /*DOC*/    "Surface.get_width() -> width\n"
 
1135
    /*DOC*/    "query the surface width\n"
 
1136
    /*DOC*/    "\n"
 
1137
    /*DOC*/    "Returns the width of the Surface.\n"
 
1138
    /*DOC*/ ;
 
1139
 
 
1140
static PyObject* surf_get_width(PyObject* self, PyObject* args)
 
1141
{
 
1142
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1143
        return PyInt_FromLong(surf->w);
 
1144
}
 
1145
 
 
1146
 
 
1147
 
 
1148
    /*DOC*/ static char doc_surf_get_height[] =
 
1149
    /*DOC*/    "Surface.get_height() -> height\n"
 
1150
    /*DOC*/    "query the surface height\n"
 
1151
    /*DOC*/    "\n"
 
1152
    /*DOC*/    "Returns the height of the Surface.\n"
 
1153
    /*DOC*/ ;
 
1154
 
 
1155
static PyObject* surf_get_height(PyObject* self, PyObject* args)
 
1156
{
 
1157
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1158
        return PyInt_FromLong(surf->h);
 
1159
}
 
1160
 
 
1161
 
 
1162
 
 
1163
    /*DOC*/ static char doc_surf_get_rect[] =
 
1164
    /*DOC*/    "Surface.get_rect() -> rect\n"
 
1165
    /*DOC*/    "get a rectangle covering the entire surface\n"
 
1166
    /*DOC*/    "\n"
 
1167
    /*DOC*/    "Returns a new rectangle covering the entire surface.\n"
 
1168
    /*DOC*/    "This rectangle will always start at 0, 0 with a width.\n"
 
1169
    /*DOC*/    "and height the same size as the image.\n"
 
1170
    /*DOC*/ ;
 
1171
 
 
1172
static PyObject* surf_get_rect(PyObject* self, PyObject* args)
 
1173
{
 
1174
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1175
        return PyRect_New4(0, 0, (short)surf->w, (short)surf->h);
 
1176
}
 
1177
 
 
1178
 
 
1179
 
 
1180
    /*DOC*/ static char doc_surf_get_bitsize[] =
 
1181
    /*DOC*/    "Surface.get_bitsize() -> int\n"
 
1182
    /*DOC*/    "query size of pixel\n"
 
1183
    /*DOC*/    "\n"
 
1184
    /*DOC*/    "Returns the number of bits used to represent each pixel. This\n"
 
1185
    /*DOC*/    "value may not exactly fill the number of bytes used per pixel.\n"
 
1186
    /*DOC*/    "For example a 15 bit Surface still requires a full 2 bytes.\n"
 
1187
    /*DOC*/ ;
 
1188
 
 
1189
static PyObject* surf_get_bitsize(PyObject* self, PyObject* args)
 
1190
{
 
1191
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1192
        return PyInt_FromLong(surf->format->BitsPerPixel);
 
1193
}
 
1194
 
 
1195
 
 
1196
    /*DOC*/ static char doc_surf_get_bytesize[] =
 
1197
    /*DOC*/    "Surface.get_bytesize() -> int\n"
 
1198
    /*DOC*/    "query size of pixel\n"
 
1199
    /*DOC*/    "\n"
 
1200
    /*DOC*/    "Returns the number of bytes used to store each pixel.\n"
 
1201
    /*DOC*/ ;
 
1202
 
 
1203
static PyObject* surf_get_bytesize(PyObject* self, PyObject* args)
 
1204
{
 
1205
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1206
        return PyInt_FromLong(surf->format->BytesPerPixel);
 
1207
}
 
1208
 
 
1209
 
 
1210
    /*DOC*/ static char doc_surf_get_masks[] =
 
1211
    /*DOC*/    "Surface.get_masks() -> redmask, greenmask, bluemask, alphamask\n"
 
1212
    /*DOC*/    "get mapping bitmasks for each colorplane\n"
 
1213
    /*DOC*/    "\n"
 
1214
    /*DOC*/    "Returns the bitmasks for each color plane. The bitmask is used to\n"
 
1215
    /*DOC*/    "isolate each colorplane value from a mapped color value. A value\n"
 
1216
    /*DOC*/    "of zero means that colorplane is not used (like alpha)\n"
 
1217
    /*DOC*/ ;
 
1218
 
 
1219
static PyObject* surf_get_masks(PyObject* self, PyObject* args)
 
1220
{
 
1221
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1222
        return Py_BuildValue("(iiii)", surf->format->Rmask, surf->format->Gmask,
 
1223
                                surf->format->Bmask, surf->format->Amask);
 
1224
}
 
1225
 
 
1226
 
 
1227
    /*DOC*/ static char doc_surf_get_shifts[] =
 
1228
    /*DOC*/    "Surface.get_shifts() -> redshift, greenshift, blueshift,\n"
 
1229
    /*DOC*/    "alphashift\n"
 
1230
    /*DOC*/    "get mapping shifts for each colorplane\n"
 
1231
    /*DOC*/    "\n"
 
1232
    /*DOC*/    "Returns the bitshifts used for each color plane. The shift is\n"
 
1233
    /*DOC*/    "determine how many bits left-shifted a colorplane value is in a\n"
 
1234
    /*DOC*/    "mapped color value.\n"
 
1235
    /*DOC*/ ;
 
1236
 
 
1237
static PyObject* surf_get_shifts(PyObject* self, PyObject* args)
 
1238
{
 
1239
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1240
        return Py_BuildValue("(iiii)", surf->format->Rshift, surf->format->Gshift,
 
1241
                                surf->format->Bshift, surf->format->Ashift);
 
1242
}
 
1243
 
 
1244
 
 
1245
    /*DOC*/ static char doc_surf_get_losses[] =
 
1246
    /*DOC*/    "Surface.get_losses() -> redloss, greenloss, blueloss, alphaloss\n"
 
1247
    /*DOC*/    "get mapping losses for each colorplane\n"
 
1248
    /*DOC*/    "\n"
 
1249
    /*DOC*/    "Returns the bitloss for each color plane. The loss is the number\n"
 
1250
    /*DOC*/    "of bits removed for each colorplane from a full 8 bits of\n"
 
1251
    /*DOC*/    "resolution. A value of 8 usually indicates that colorplane is not\n"
 
1252
    /*DOC*/    "used (like the alpha)\n"
 
1253
    /*DOC*/ ;
 
1254
 
 
1255
static PyObject* surf_get_losses(PyObject* self, PyObject* args)
 
1256
{
 
1257
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1258
        return Py_BuildValue("(iiii)", surf->format->Rloss, surf->format->Gloss,
 
1259
                                surf->format->Bloss, surf->format->Aloss);
 
1260
}
 
1261
 
 
1262
 
 
1263
    /*DOC*/ static char doc_surf_subsurface[] =
 
1264
    /*DOC*/    "Surface.subsurface(rectstyle) -> Surface\n"
 
1265
    /*DOC*/    "create a new surface that shares pixel data\n"
 
1266
    /*DOC*/    "\n"
 
1267
    /*DOC*/    "Creates a new surface that shares pixel data of the given surface.\n"
 
1268
    /*DOC*/    "Note that only the pixel data is shared. Things like clipping rectangles\n"
 
1269
    /*DOC*/    "and colorkeys will be unique for the new surface.\n"
 
1270
    /*DOC*/    "\n"
 
1271
    /*DOC*/    "The new subsurface will inherit the palette, colorkey, and surface alpha\n"
 
1272
    /*DOC*/    "values from the base image.\n"
 
1273
    /*DOC*/    "\n"
 
1274
    /*DOC*/    "You should not use the RLEACCEL flag for parent surfaces of subsurfaces,\n"
 
1275
    /*DOC*/    "for the most part it will work, but it will cause a lot of extra work,\n"
 
1276
    /*DOC*/    "every time you change the subsurface, you must decode and recode the\n"
 
1277
    /*DOC*/    "RLEACCEL data for the parent surface.\n"
 
1278
    /*DOC*/    "\n"
 
1279
    /*DOC*/    "As for using RLEACCEL with the subsurfaces, that will work as you'd\n"
 
1280
    /*DOC*/    "expect, but changes the the parent Surface will not always take effect\n"
 
1281
    /*DOC*/    "in the subsurface.\n"
 
1282
    /*DOC*/ ;
 
1283
 
 
1284
static PyObject* surf_subsurface(PyObject* self, PyObject* args)
 
1285
{
 
1286
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1287
        SDL_PixelFormat* format = surf->format;
 
1288
        GAME_Rect *rect, temp;
 
1289
        SDL_Surface* sub;
 
1290
        PyObject* subobj;
 
1291
        int pixeloffset;
 
1292
        char* startpixel;
 
1293
        struct SubSurface_Data* data;
 
1294
 
 
1295
        if(surf->flags & SDL_OPENGL)
 
1296
                return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
 
1297
 
 
1298
        if(!(rect = GameRect_FromObject(args, &temp)))
 
1299
                return RAISE(PyExc_ValueError, "invalid rectstyle argument");
 
1300
        if(rect->x < 0 || rect-> y < 0 || rect->x + rect->w > surf->w || rect->y + rect->h > surf->h)
 
1301
                return RAISE(PyExc_ValueError, "subsurface rectangle outside surface area");
 
1302
 
 
1303
 
 
1304
        PySurface_Lock(self);
 
1305
 
 
1306
        pixeloffset = rect->x * format->BytesPerPixel + rect->y * surf->pitch;
 
1307
        startpixel = ((char*)surf->pixels) + pixeloffset;
 
1308
 
 
1309
        sub = SDL_CreateRGBSurfaceFrom(startpixel, rect->w, rect->h, format->BitsPerPixel, \
 
1310
                                surf->pitch, format->Rmask, format->Gmask, format->Bmask, format->Amask);
 
1311
 
 
1312
        PySurface_Unlock(self);
 
1313
 
 
1314
        if(!sub)
 
1315
                return RAISE(PyExc_SDLError, SDL_GetError());
 
1316
 
 
1317
        /*copy the colormap if we need it*/
 
1318
        if(surf->format->BytesPerPixel == 1 && surf->format->palette)
 
1319
                SDL_SetPalette(sub, SDL_LOGPAL, surf->format->palette->colors, 0, surf->format->palette->ncolors);
 
1320
        if(surf->flags & SDL_SRCALPHA)
 
1321
                SDL_SetAlpha(sub, surf->flags&SDL_SRCALPHA, format->alpha);
 
1322
        if(surf->flags & SDL_SRCCOLORKEY)
 
1323
                SDL_SetColorKey(sub, surf->flags&(SDL_SRCCOLORKEY|SDL_RLEACCEL), format->colorkey);
 
1324
 
 
1325
 
 
1326
        data = PyMem_New(struct SubSurface_Data, 1);
 
1327
        if(!data) return NULL;
 
1328
 
 
1329
        subobj = PySurface_New(sub);
 
1330
        if(!subobj)
 
1331
        {
 
1332
                PyMem_Del(data);
 
1333
                return NULL;
 
1334
        }
 
1335
 
 
1336
        Py_INCREF(self);
 
1337
        data->owner = self;
 
1338
        data->pixeloffset = pixeloffset;
 
1339
        ((PySurfaceObject*)subobj)->subsurface = data;
 
1340
 
 
1341
 
 
1342
 
 
1343
        return subobj;
 
1344
}
 
1345
 
 
1346
 
 
1347
 
 
1348
static struct PyMethodDef surface_methods[] =
 
1349
{
 
1350
        {"get_at",                      surf_get_at,            1, doc_surf_get_at },
 
1351
        {"set_at",                      surf_set_at,            1, doc_surf_set_at },
 
1352
 
 
1353
        {"map_rgb",                     surf_map_rgb,           1, doc_surf_map_rgb },
 
1354
        {"unmap_rgb",           surf_unmap_rgb,         1, doc_surf_unmap_rgb },
 
1355
 
 
1356
        {"get_palette",         surf_get_palette,       1, doc_surf_get_palette },
 
1357
        {"get_palette_at",      surf_get_palette_at,1, doc_surf_get_palette_at },
 
1358
        {"set_palette",         surf_set_palette,       1, doc_surf_set_palette },
 
1359
        {"set_palette_at",      surf_set_palette_at,1, doc_surf_set_palette_at },
 
1360
 
 
1361
        {"lock",                        surf_lock,                      1, doc_surf_lock },
 
1362
        {"unlock",                      surf_unlock,            1, doc_surf_unlock },
 
1363
        {"mustlock",            surf_mustlock,          1, doc_surf_mustlock },
 
1364
        {"get_locked",          surf_get_locked,        1, doc_surf_get_locked },
 
1365
 
 
1366
        {"set_colorkey",        surf_set_colorkey,      1, doc_surf_set_colorkey },
 
1367
        {"get_colorkey",        surf_get_colorkey,      1, doc_surf_get_colorkey },
 
1368
        {"set_alpha",           surf_set_alpha,         1, doc_surf_set_alpha },
 
1369
        {"get_alpha",           surf_get_alpha,         1, doc_surf_get_alpha },
 
1370
 
 
1371
        {"convert",                     surf_convert,           1, doc_surf_convert },
 
1372
        {"convert_alpha",       surf_convert_alpha,     1, doc_surf_convert_alpha },
 
1373
 
 
1374
        {"set_clip",            surf_set_clip,          1, doc_surf_set_clip },
 
1375
        {"get_clip",            surf_get_clip,          1, doc_surf_get_clip },
 
1376
 
 
1377
        {"fill",                        surf_fill,                      1, doc_surf_fill },
 
1378
        {"blit",                        surf_blit,                      1, doc_surf_blit },
 
1379
 
 
1380
        {"get_flags",           surf_get_flags,         1, doc_surf_get_flags },
 
1381
        {"get_size",            surf_get_size,          1, doc_surf_get_size },
 
1382
        {"get_width",           surf_get_width,         1, doc_surf_get_width },
 
1383
        {"get_height",          surf_get_height,        1, doc_surf_get_height },
 
1384
        {"get_rect",            surf_get_rect,          1, doc_surf_get_rect },
 
1385
        {"get_pitch",           surf_get_pitch,         1, doc_surf_get_pitch },
 
1386
        {"get_bitsize",         surf_get_bitsize,       1, doc_surf_get_bitsize },
 
1387
        {"get_bytesize",        surf_get_bytesize,      1, doc_surf_get_bytesize },
 
1388
        {"get_masks",           surf_get_masks,         1, doc_surf_get_masks },
 
1389
        {"get_shifts",          surf_get_shifts,        1, doc_surf_get_shifts },
 
1390
        {"get_losses",          surf_get_losses,        1, doc_surf_get_losses },
 
1391
 
 
1392
        {"subsurface",          surf_subsurface,        1, doc_surf_subsurface },
 
1393
 
 
1394
        {NULL,          NULL}
 
1395
};
 
1396
 
 
1397
 
 
1398
 
 
1399
/* surface object internals */
 
1400
 
 
1401
static void surface_dealloc(PyObject* self)
 
1402
{
 
1403
        PySurfaceObject* surf = (PySurfaceObject*)self;
 
1404
        struct SubSurface_Data* data = ((PySurfaceObject*)self)->subsurface;
 
1405
 
 
1406
        if(SDL_WasInit(SDL_INIT_VIDEO))
 
1407
        {
 
1408
                while(surf->lockcount > 0)
 
1409
                        PySurface_Unlock(self);
 
1410
                SDL_FreeSurface(surf->surf);
 
1411
        }
 
1412
        if(data)
 
1413
        {
 
1414
                Py_XDECREF(data->owner);
 
1415
                PyMem_Del(data);
 
1416
        }
 
1417
 
 
1418
        PyObject_DEL(self);     
 
1419
}
 
1420
 
 
1421
 
 
1422
 
 
1423
static PyObject *surface_getattr(PyObject *self, char *name)
 
1424
{
 
1425
        return Py_FindMethod(surface_methods, (PyObject *)self, name);
 
1426
}
 
1427
 
 
1428
 
 
1429
PyObject* surface_str(PyObject* self)
 
1430
{
 
1431
        char str[1024];
 
1432
        SDL_Surface* surf = PySurface_AsSurface(self);
 
1433
        const char* type;
 
1434
 
 
1435
        if(surf)
 
1436
        {
 
1437
            type = (surf->flags&SDL_HWSURFACE)?"HW":"SW";
 
1438
            sprintf(str, "<Surface(%dx%dx%d %s)>", surf->w, surf->h, surf->format->BitsPerPixel, type);
 
1439
        }
 
1440
        else
 
1441
        {
 
1442
            strcpy(str, "<Surface(Dead Display)>");
 
1443
        }
 
1444
 
 
1445
        return PyString_FromString(str);
 
1446
}
 
1447
 
 
1448
    /*DOC*/ static char doc_Surface_MODULE[] =
 
1449
    /*DOC*/    "Surface objects represent a simple memory buffer of pixels.\n"
 
1450
    /*DOC*/    "Surface objects can reside in system memory, or in special\n"
 
1451
    /*DOC*/    "hardware memory, which can be hardware accelerated. Surfaces that\n"
 
1452
    /*DOC*/    "are 8 bits per pixel use a colormap to represent their color\n"
 
1453
    /*DOC*/    "values. All Surfaces with higher bits per pixel use a packed\n"
 
1454
    /*DOC*/    "pixels to store their color values.\n"
 
1455
    /*DOC*/    "\n"
 
1456
    /*DOC*/    "Surfaces can have many extra attributes like alpha planes,\n"
 
1457
    /*DOC*/    "colorkeys, source rectangle clipping. These functions mainly\n"
 
1458
    /*DOC*/    "effect how the Surface is blitted to other Surfaces. The blit\n"
 
1459
    /*DOC*/    "routines will attempt to use hardware acceleration when possible,\n"
 
1460
    /*DOC*/    "otherwise will use highly optimized software blitting methods.\n"
 
1461
    /*DOC*/    "\n"
 
1462
    /*DOC*/    "There is support for pixel access for the Surfaces. Pixel access\n"
 
1463
    /*DOC*/    "on hardware surfaces is slow and not recommended. Pixels can be\n"
 
1464
    /*DOC*/    "accessed using the get_at() and set_at() functions. These methods\n"
 
1465
    /*DOC*/    "are fine for simple access, but will be considerably slow when\n"
 
1466
    /*DOC*/    "doing of pixel work with them. If you plan on doing a lot of\n"
 
1467
    /*DOC*/    "pixel level work, it is recommended to use the pygame.surfarray\n"
 
1468
    /*DOC*/    "module, which can treat the surfaces like large multidimensional\n"
 
1469
    /*DOC*/    "arrays (and it's quite quick).\n"
 
1470
    /*DOC*/ ;
 
1471
 
 
1472
 
 
1473
static PyTypeObject PySurface_Type =
 
1474
{
 
1475
        PyObject_HEAD_INIT(NULL)
 
1476
        0,                                              /*size*/
 
1477
        "Surface",                              /*name*/
 
1478
        sizeof(PySurfaceObject),/*basic size*/
 
1479
        0,                                              /*itemsize*/
 
1480
        surface_dealloc,                /*dealloc*/
 
1481
        0,                                              /*print*/
 
1482
        surface_getattr,                /*getattr*/
 
1483
        NULL,                                   /*setattr*/
 
1484
        NULL,                                   /*compare*/
 
1485
        surface_str,                    /*repr*/
 
1486
        NULL,                                   /*as_number*/
 
1487
        NULL,                                   /*as_sequence*/
 
1488
        NULL,                                   /*as_mapping*/
 
1489
        (hashfunc)NULL,                 /*hash*/
 
1490
        (ternaryfunc)NULL,              /*call*/
 
1491
        (reprfunc)NULL,                 /*str*/
 
1492
        0L,0L,0L,0L,
 
1493
        doc_Surface_MODULE /* Documentation string */
 
1494
};
 
1495
 
 
1496
 
 
1497
static PyObject* PySurface_New(SDL_Surface* s)
 
1498
{
 
1499
        PySurfaceObject* surf;
 
1500
 
 
1501
        if(!s) return RAISE(PyExc_SDLError, SDL_GetError());
 
1502
 
 
1503
        surf = PyObject_NEW(PySurfaceObject, &PySurface_Type);
 
1504
        if(surf)
 
1505
        {
 
1506
                surf->surf = s;
 
1507
                surf->subsurface = NULL;
 
1508
                surf->didlock = 0;
 
1509
                surf->lockcount = 0;
 
1510
        }
 
1511
        return (PyObject*)surf;
 
1512
}
 
1513
 
 
1514
 
 
1515
 
 
1516
/* surface module functions */
 
1517
 
 
1518
    /*DOC*/ static char doc_Surface[] =
 
1519
    /*DOC*/    "pygame.Surface(size, [flags, [Surface|depth, [masks]]]) -> Surface\n"
 
1520
    /*DOC*/    "create a new Surface\n"
 
1521
    /*DOC*/    "\n"
 
1522
    /*DOC*/    "Creates a new surface object. Size is a 2-int-sequence containing\n"
 
1523
    /*DOC*/    "width and height. Depth is the number of bits used per pixel. If\n"
 
1524
    /*DOC*/    "omitted, depth will use the current display depth. Masks is a\n"
 
1525
    /*DOC*/    "four item sequence containing the bitmask for r,g,b, and a. If\n"
 
1526
    /*DOC*/    "omitted, masks will default to the usual values for the given\n"
 
1527
    /*DOC*/    "bitdepth. Flags is a mix of the following flags: SWSURFACE,\n"
 
1528
    /*DOC*/    "HWSURFACE, ASYNCBLIT, or SRCALPHA. (flags = 0 is the\n"
 
1529
    /*DOC*/    "same as SWSURFACE). Depth and masks can be substituted for\n"
 
1530
    /*DOC*/    "another surface object which will create the new surface with the\n"
 
1531
    /*DOC*/    "same format as the given one. When using default masks, alpha\n"
 
1532
    /*DOC*/    "will always be ignored unless you pass SRCALPHA as a flag.\n"
 
1533
    /*DOC*/    "For a plain software surface, 0 can be used for the flag. \n"
 
1534
    /*DOC*/    "A plain hardware surface can just use 1 for the flag.\n"
 
1535
    /*DOC*/ ;
 
1536
 
 
1537
static PyObject* Surface(PyObject* self, PyObject* arg)
 
1538
{
 
1539
        Uint32 flags = 0;
 
1540
        int width, height;
 
1541
        PyObject *depth=NULL, *masks=NULL, *final;
 
1542
        short bpp;
 
1543
        Uint32 Rmask, Gmask, Bmask, Amask;
 
1544
        SDL_Surface* surface;
 
1545
        SDL_PixelFormat default_format;
 
1546
 
 
1547
        if(!PyArg_ParseTuple(arg, "(ii)|iOO", &width, &height, &flags, &depth, &masks))
 
1548
                return NULL;
 
1549
        if(depth && masks) /*all info supplied, most errorchecking needed*/
 
1550
        {
 
1551
                if(PySurface_Check(depth))
 
1552
                        return RAISE(PyExc_ValueError, "cannot pass surface for depth and color masks");
 
1553
                if(!ShortFromObj(depth, &bpp))
 
1554
                        return RAISE(PyExc_ValueError, "invalid bits per pixel depth argument");
 
1555
                if(!PySequence_Check(masks) || PySequence_Length(masks)!=4)
 
1556
                        return RAISE(PyExc_ValueError, "masks argument must be sequence of four numbers");
 
1557
                if(!UintFromObjIndex(masks, 0, &Rmask) || !UintFromObjIndex(masks, 1, &Gmask) ||
 
1558
                                        !UintFromObjIndex(masks, 2, &Bmask) || !UintFromObjIndex(masks, 3, &Amask))
 
1559
                        return RAISE(PyExc_ValueError, "invalid mask values in masks sequence");
 
1560
        }
 
1561
        else if(depth && PyNumber_Check(depth))/*use default masks*/
 
1562
        {
 
1563
                if(!ShortFromObj(depth, &bpp))
 
1564
                        return RAISE(PyExc_ValueError, "invalid bits per pixel depth argument");
 
1565
                if(flags & SDL_SRCALPHA)
 
1566
                {
 
1567
                        switch(bpp)
 
1568
                        {
 
1569
                        case 16:
 
1570
                                Rmask = 0xF<<8; Gmask = 0xF<<4; Bmask = 0xF; Amask = 0xF<<12; break;
 
1571
                        case 32:
 
1572
                                Rmask = 0xFF<<16; Gmask = 0xFF<<8; Bmask = 0xFF; Amask = 0xFF<<24; break;
 
1573
                        default:
 
1574
                                return RAISE(PyExc_ValueError, "no standard masks exist for given bitdepth with alpha");
 
1575
                        }
 
1576
                }
 
1577
                else
 
1578
                {
 
1579
                        Amask = 0;
 
1580
                        switch(bpp)
 
1581
                        {
 
1582
                        case 8:
 
1583
                                Rmask = 0xFF>>6<<5; Gmask = 0xFF>>5<<2; Bmask = 0xFF>>6; break;
 
1584
                        case 12:
 
1585
                                Rmask = 0xFF>>4<<8; Gmask = 0xFF>>4<<4; Bmask = 0xFF>>4; break;
 
1586
                        case 15:
 
1587
                                Rmask = 0xFF>>3<<10; Gmask = 0xFF>>3<<5; Bmask = 0xFF>>3; break;
 
1588
                        case 16:
 
1589
                                Rmask = 0xFF>>3<<11; Gmask = 0xFF>>2<<5; Bmask = 0xFF>>3; break;
 
1590
                        case 24:
 
1591
                        case 32:
 
1592
                                Rmask = 0xFF<<16; Gmask = 0xFF<<8; Bmask = 0xFF; break;
 
1593
                        default:
 
1594
                                return RAISE(PyExc_ValueError, "nonstandard bit depth given");
 
1595
                        }
 
1596
                }
 
1597
        }
 
1598
        else /*no depth or surface*/
 
1599
        {
 
1600
                SDL_PixelFormat* pix;
 
1601
                if(depth && PySurface_Check(depth))
 
1602
                        pix = ((PySurfaceObject*)depth)->surf->format;
 
1603
                else if(SDL_GetVideoSurface())
 
1604
                        pix = SDL_GetVideoSurface()->format;
 
1605
                else if(SDL_WasInit(SDL_INIT_VIDEO))
 
1606
                        pix = SDL_GetVideoInfo()->vfmt;
 
1607
                else
 
1608
                {
 
1609
                        pix = &default_format;
 
1610
                        pix->BitsPerPixel = 32; pix->Amask = 0;
 
1611
                        pix->Rmask = 0xFF0000; pix->Gmask = 0xFF00; pix->Bmask = 0xFF;
 
1612
                }
 
1613
                bpp = pix->BitsPerPixel;
 
1614
                Rmask = pix->Rmask;
 
1615
                Gmask = pix->Gmask;
 
1616
                Bmask = pix->Bmask;
 
1617
                Amask = pix->Amask;
 
1618
        }
 
1619
        surface = SDL_CreateRGBSurface(flags, width, height, bpp, Rmask, Gmask, Bmask, Amask);
 
1620
        final = PySurface_New(surface);
 
1621
        if(!final)
 
1622
                SDL_FreeSurface(surface);
 
1623
        return final;
 
1624
}
 
1625
 
 
1626
 
 
1627
 
 
1628
 
 
1629
static PyMethodDef surface_builtins[] =
 
1630
{
 
1631
        { "Surface", Surface, 1, doc_Surface },
 
1632
        { NULL, NULL }
 
1633
};
 
1634
 
 
1635
 
 
1636
 
 
1637
    /*DOC*/ static char doc_pygame_surface_MODULE[] =
 
1638
    /*DOC*/    "The surface module doesn't have much in the line of functions. It\n"
 
1639
    /*DOC*/    "does have the Surface object, and one routine to create new\n"
 
1640
    /*DOC*/    "surfaces, pygame.Surface().\n"
 
1641
    /*DOC*/ ;
 
1642
 
 
1643
PYGAME_EXPORT
 
1644
void initsurface(void)
 
1645
{
 
1646
        PyObject *module, *dict, *apiobj, *lockmodule;
 
1647
        static void* c_api[PYGAMEAPI_SURFACE_NUMSLOTS];
 
1648
 
 
1649
        PyType_Init(PySurface_Type);
 
1650
 
 
1651
 
 
1652
    /* create the module */
 
1653
        module = Py_InitModule3("surface", surface_builtins, doc_pygame_surface_MODULE);
 
1654
        dict = PyModule_GetDict(module);
 
1655
 
 
1656
        PyDict_SetItemString(dict, "SurfaceType", (PyObject *)&PySurface_Type);
 
1657
 
 
1658
        /* export the c api */
 
1659
        c_api[0] = &PySurface_Type;
 
1660
        c_api[1] = PySurface_New;
 
1661
        apiobj = PyCObject_FromVoidPtr(c_api, NULL);
 
1662
        PyDict_SetItemString(dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);
 
1663
        Py_DECREF(apiobj);
 
1664
 
 
1665
        /*imported needed apis*/
 
1666
        import_pygame_base();
 
1667
        import_pygame_rect();
 
1668
 
 
1669
        /*import the surflock module manually*/
 
1670
        lockmodule = PyImport_ImportModule("pygame.surflock");
 
1671
        if(lockmodule != NULL)
 
1672
        {
 
1673
                PyObject *dict = PyModule_GetDict(lockmodule);
 
1674
                PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY);
 
1675
                if(PyCObject_Check(c_api))
 
1676
                {
 
1677
                        int i; void** localptr = (void*)PyCObject_AsVoidPtr(c_api);
 
1678
                        for(i = 0; i < PYGAMEAPI_SURFLOCK_NUMSLOTS; ++i)
 
1679
                                PyGAME_C_API[i + PYGAMEAPI_SURFLOCK_FIRSTSLOT] = localptr[i];
 
1680
                }
 
1681
        }
 
1682
        Py_XDECREF(lockmodule);
 
1683
}
 
1684