Commits

Anonymous committed bf4bafb Merge

merge before push

Comments (0)

Files changed (21)

+# travisci continuous integration config file.
+
+language: python
+python:
+  #- "2.5"
+  - "2.6"
+  #- "2.7"
+  #- "3.2"
+# command to install
+install:
+#  - pip install . --use-mirrors
+#  - pip install -r requirements.txt --use-mirrors
+  - python config.py -auto
+  - python setup.py install -noheaders
+
+
+# command to run tests
+script: 
+  - python -m pygame.tests.__main__
+
+
+# Here we install the ubuntu dependencies with apt-get.
+before_install:
+  - sudo apt-get update
+  - sudo apt-get install python-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev libsmpeg-dev python-numpy libportmidi-dev ffmpeg libswscale-dev libavformat-dev libavcodec-dev libjpeg-dev libtiff4-dev libx11-6 libX11-dev
+
+# Here we can notify the pygame irc chat.
+
+#notifications:
+#  irc:
+#    channels: "irc.freenode.org#pygame"
+#    on_success: change
+#    on_failure: change

examples/__movie_test.py

 
 print ("Please give an (absolute)filename of a movie file you'd like to play: ")
 #filename = raw_input()
-filename="/home/tyler/War3.avi"
+filename="/tmp/testit.avi"
 #initialization. It could also have a surface as a second argument, and every 
 # frame will be blitted to that surface. It is the programmer's responsibility
 # to be on time for rendering that surface.
     #this is to test that the movie module tests filenames to make sure they exist
     m=movie.Movie("gsdsjgsdj")
 except Exception:
-    e = pygame.compat.get_error()
+    e = pygame.compat.geterror()
     print (e)
     del m
 
 try:
     m.surface = surf
 except Exception:
-    e = pygame.compat.get_error()
+    e = pygame.compat.geterror()
 
     print (e)
     del e
Add a comment to this file

examples/data/brick.png

Added
New image
Added
New image

examples/movieplayer.py

 
 import sys
 import os
+import time
 
 if sys.platform == 'win32' and sys.getwindowsversion()[0] >= 5: # condi. and
     # On NT like Windows versions smpeg video needs windb.
     os.environ['SDL_VIDEODRIVER'] = 'windib'
     
 import pygame
+import pygame._movie
 from pygame.locals import *
 
 try:
     pygame.mixer.quit()
     pygame.display.init()
 
-    f = BytesIO(open(filepath, 'rb').read())
-    movie = pygame.movie.Movie(f)
-    w, h = movie.get_size()
-    w = int(w * 1.3 + 0.5)
-    h = int(h * 1.3 + 0.5)
-    wsize = (w+10, h+10)
+    #f = BytesIO(open(filepath, 'rb').read())
+    #movie = pygame.movie.Movie(f)
+    #w, h = movie.get_size()
+    info = pygame._movie.MovieInfo(filepath)
+    w, h = info.width, info.height
     msize = (w, h)
-    screen = pygame.display.set_mode(wsize)
-    movie.set_display(screen, Rect((5, 5), msize))
 
-    pygame.event.set_allowed((QUIT, KEYDOWN))
-    pygame.time.set_timer(USEREVENT, 1000)
-    movie.play()
-    while movie.get_busy():
-        evt = pygame.event.wait()
-        if evt.type == QUIT:
-            break
-        if evt.type == KEYDOWN and evt.unicode == QUIT_CHAR:
-            break
-    if movie.get_busy():
+
+    print "new screen..."
+    screen = pygame.display.set_mode(msize)
+
+
+    pygame.display.set_caption(os.path.split(info.filename)[-1])
+
+
+    print "before movie = pygame._movie.Movie(filepath, screen)"
+    #surf = screen.copy().convert()
+    #movie = pygame._movie.Movie(filepath, screen)
+    movie = pygame._movie.Movie(filepath)
+    #movie.surface = surf
+    print "after movie = pygame._movie.Movie(filepath, screen)"
+    #movie.set_display(screen, Rect((5, 5), msize))
+
+    print dir(movie)
+    print movie.surface
+    #movie.xleft = 300
+    print "before movie.play()"
+    movie.play(0)
+    print "after movie.play()"
+
+    while movie.playing:
+
+        events = pygame.event.get()
+        for e in events:
+            print e
+            if e.type == QUIT or e.type == KEYDOWN and e.key == K_ESCAPE:
+                movie.stop()
+
+
+        if 1:
+            if(not screen.get_locked()):
+                try:
+                    #pygame.display.update()
+                    #pygame.display.flip()
+                    pass
+                except pygame.error:
+                    break
+        else:
+            if(not surf.get_locked() and not screen.get_locked()):
+                try:
+                    screen.blit(surf, (0,0))
+                except pygame.error:
+                    pass
+            
+        time.sleep(0.1) # release the GIL.
+
+
+    if movie.playing:
         movie.stop()
-    pygame.time.set_timer(USEREVENT, 0)
 
 if __name__ == '__main__':
     if len(sys.argv) != 2:
 This is probably the most popular method of installation. If you are
 running on windows, it is highly recommended you use this form
 of installing. The installers come with with nearly everything
-you need, and have an easy point and click installers.
+you need and have an easy point and click installers.
 </p><p>
 The first thing you will need is an installation of Python. Python
 binary installers make it easy to get this done. Pygame binaries
 Once that is in place, you want to download the appropriate
 windows binary. From the pygame downloads page you can find the .EXE
 file you need. This will automatically install all of pygame and all the SDL
-dependencies. The windows binaries have filenames like this; "http://www3.telus.net/len_l/pygame-1.8.0release.win32-py2.5.msi".
+dependencies. The windows binaries have filenames like this: "pygame-1.8.0release.win32-py2.5.msi".
 This would be the installer for pygame version 1.8.0, for Python version 2.5. You
 shouldn't have trouble finding the correct binary from the "Windows" section
 of the download page.
 You will also probably want to install the windows documentation and
 installation package. This will add easy links to the different documentation
 and games that come with pygame. The installer for this is found
-next to the other windows binary downloads. The filename looks like this;
+next to the other windows binary downloads. The filename looks like this:
 "pygame-docs-1.8.0.exe". And this would install the documentation and
 examples for pygame-1.8.0
 </p><p>
 Windows Binary Installer
 This is probably the most popular method of installation. If you are
 running on windows, it is highly recommended you use this form of
-installing. The installers come with with nearly everything you need,
+installing. The installers come with with nearly everything you need
 and have an easy point and click installers.
 
 The first thing you will need is an installation of Python. Python
 Once that is in place, you want to download the appropriate windows
 binary. From the pygame downloads page you can find the .EXE file you
 need. This will automatically install all of pygame and all the SDL
-dependencies. The windows binaries have filenames like this;
-"http://www3.telus.net/len_l/pygame-1.8.0release.win32-py2.5.msi".
+dependencies. The windows binaries have filenames like this:
+"pygame-1.8.0release.win32-py2.5.msi".
 This would be the installer for pygame version 1.8.0, for Python
 version 2.5. You shouldn't have trouble finding the correct binary
 from the "Windows" section of the download page.
 installation package. This will add easy links to the different
 documentation and games that come with pygame. The installer for this
 is found next to the other windows binary downloads. The filename
-looks like this; "pygame-docs-1.8.0.exe". And this would install the
+looks like this: "pygame-docs-1.8.0.exe". And this would install the
 documentation and examples for pygame-1.8.0
 
 One other thing the windows binaries are missing is the Numeric or

lib/_camera_vidcapture.py

                 # if there is a destination surface given, we blit onto that.
                 if dest_surf:
                     dest_surf.blit(surf, (0,0))
+                else:
+                    dest_surf = surf
                 return dest_surf
 
             else:
 ##    Pete Shinners
 ##    pete@shinners.org
 
+from pygame.compat import unicode_
+
 THECOLORS = {
 'gray17' : (43, 43, 43, 255) ,
 'gold' : (255, 215, 0, 255) ,
 'grey100' : (255, 255, 255, 255) ,
 'brown1' : (255, 64, 64, 255) ,
 }
+
+for k,v in THECOLORS.items():
+    THECOLORS[unicode_(k)] = v
 headers.remove(os.path.join('src', 'numeric_arrayobject.h'))
 headers.remove(os.path.join('src', 'scale.h'))
 
+# option for not installing the headers.
+if "-noheaders" in sys.argv:
+    headers = []
+    sys.argv.remove ("-noheaders")
+
+
 #sanity check for any arguments
 if len(sys.argv) == 1:
     reply = raw_input('\nNo Arguments Given, Perform Default Install? [Y/n]')
     RELEASEGIL
     AVPacket *pkt = &movie->audio_pkt;
     AVCodecContext *dec= movie->audio_st->codec;
-    int len1, data_size;
+    AVFrame *frame;
+    int len1, data_size, got_frame_ptr;
     int filled =0;
     len1=0;
+
+    frame=avcodec_alloc_frame();
+
+    dec->get_buffer(dec, frame);
+
     for(;;)
     {
         if(movie->stop || movie->audioq.abort_request)
         //fill up the buffer
         while(movie->audio_pkt_size > 0)
         {
+
+            //printf("asdf\n");
+            /* TODO: attempt to fix below... but this is just wrong... */
             data_size = sizeof(movie->audio_buf1);
-            len1 += avcodec_decode_audio2(dec, (int16_t *)movie->audio_buf1, &data_size, movie->audio_pkt_data, movie->audio_pkt_size);
+            len1 = avcodec_decode_audio4(dec, 
+                                         frame, 
+                                         &data_size, 
+                                         pkt);
+
+            movie->audio_pkt_size= frame->nb_samples;
             if (len1 < 0)
             {
-                /* if error, we skip the frame */
+                // if error, we skip the frame 
                 movie->audio_pkt_size = 0;
                 break;
             }
             //reformat_ctx here, but deleted
             filled=1;
 
+
+
+            /* TODO: FIXME uses old functions.
+            data_size = sizeof(movie->audio_buf1);
+            len1 += avcodec_decode_audio2(dec, 
+                                          (int16_t *)movie->audio_buf1, 
+                                          &data_size, 
+                                          movie->audio_pkt_data, 
+                                          movie->audio_pkt_size);
+            if (len1 < 0)
+            {
+                // if error, we skip the frame 
+                movie->audio_pkt_size = 0;
+                break;
+            }
+            movie->audio_pkt_data += len1;
+            movie->audio_pkt_size -= len1;
+            if (data_size <= 0)
+                continue;
+            //reformat_ctx here, but deleted
+            filled=1;
+            */
+
         }
         if(filled)
         {
     enc = ic->streams[stream_index]->codec;
     switch(enc->codec_type)
     {
-    case CODEC_TYPE_AUDIO:
+    case PYG_MEDIA_TYPE_AUDIO:
         movie->audio_stream = stream_index;
         movie->audio_st = ic->streams[stream_index];
         break;
-    case CODEC_TYPE_VIDEO:
+    case PYG_MEDIA_TYPE_VIDEO:
         movie->video_stream = stream_index;
         movie->video_st = ic->streams[stream_index];
         break;
     enc = ic->streams[stream_index]->codec;
     switch(enc->codec_type)
     {
-    case CODEC_TYPE_AUDIO:
+    case PYG_MEDIA_TYPE_AUDIO:
         if(movie->replay)
         {
             movie->audio_st = ic->streams[stream_index];
         soundStart();
         movie->audio_tid = SDL_CreateThread(audio_thread, movie);
         break;
-    case CODEC_TYPE_VIDEO:
+    case PYG_MEDIA_TYPE_VIDEO:
         if(movie->replay)
         {
             movie->video_stream = stream_index;
     //SubPicture *sp;
     switch(enc->codec_type)
     {
-    case CODEC_TYPE_AUDIO:
+    case PYG_MEDIA_TYPE_AUDIO:
         packet_queue_abort(&movie->audioq);
         SDL_WaitThread(movie->audio_tid, NULL);
         SDL_DestroyMutex(movie->audio_mutex);
         memset(&movie->audio_buf1, 0, sizeof(movie->audio_buf1));
         packet_queue_flush(&movie->audioq);
         break;
-    case CODEC_TYPE_VIDEO:
+    case PYG_MEDIA_TYPE_VIDEO:
         for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE;i++)
         {
             vp = &movie->pictq[i];
     int end = movie->loops;
     switch(enc->codec_type)
     {
-    case CODEC_TYPE_AUDIO:
+    case PYG_MEDIA_TYPE_AUDIO:
         soundQuit();
         packet_queue_end(&movie->audioq, end);
         break;
-    case CODEC_TYPE_VIDEO:
+    case PYG_MEDIA_TYPE_VIDEO:
         packet_queue_end(&movie->videoq, end);
         break;
     default:
     avcodec_close(enc);
     switch(enc->codec_type)
     {
-    case CODEC_TYPE_AUDIO:
+    case PYG_MEDIA_TYPE_AUDIO:
         movie->audio_st = NULL;
         movie->audio_stream = -1;
         break;
-    case CODEC_TYPE_VIDEO:
+    case PYG_MEDIA_TYPE_VIDEO:
         movie->video_st = NULL;
         movie->video_stream = -1;
         break;
         movie->ic->streams[i]->discard = AVDISCARD_ALL;
         switch(enc->codec_type)
         {
-        case CODEC_TYPE_AUDIO:
+        case PYG_MEDIA_TYPE_AUDIO:
             if (wanted_audio_stream-- >= 0 && !movie->audio_disable)
                 audio_index = i;
             break;
-        case CODEC_TYPE_VIDEO:
+        case PYG_MEDIA_TYPE_VIDEO:
             if (wanted_video_stream-- >= 0 && !movie->video_disable)
                 video_index = i;
             break;
-        case CODEC_TYPE_SUBTITLE:
+        case PYG_MEDIA_TYPE_SUBTITLE:
             //if(wanted_subti_stream -- >= 0 && !movie->subtitle_disable)
             //	subtitle_index=i;
         default:
     int freq, channels;
     enc = ic->streams[stream_index]->codec;
     /* prepare audio output */
-    if (enc->codec_type == CODEC_TYPE_AUDIO)
+    if (enc->codec_type == PYG_MEDIA_TYPE_AUDIO)
     {
 #if LIBAVCODEC_VERSION_INT>=3412992 //(52<<16)+(20<<8)+0 ie 52.20.0
         if (enc->channels > 0)
         return -1;
     }
     /* prepare audio output */
-    if (enc->codec_type == CODEC_TYPE_AUDIO)
+    if (enc->codec_type == PYG_MEDIA_TYPE_AUDIO)
     {
 
         freq = enc->sample_rate;
     Py_INCREF(movie);
     RELEASEGIL
 
-    if (codec_type == CODEC_TYPE_VIDEO)
+    if (codec_type == PYG_MEDIA_TYPE_VIDEO)
         start_index = movie->video_stream;
-    else if (codec_type == CODEC_TYPE_AUDIO)
+    else if (codec_type == PYG_MEDIA_TYPE_AUDIO)
         start_index = movie->audio_stream;
     stream_index = start_index;
     for(;;)
             /* check that parameters are OK */
             switch(codec_type)
             {
-            case CODEC_TYPE_AUDIO:
+            case PYG_MEDIA_TYPE_AUDIO:
                 if (st->codec->sample_rate != 0 &&
                         st->codec->channels != 0)
                     goto the_end;
                 break;
-            case CODEC_TYPE_VIDEO:
+            case PYG_MEDIA_TYPE_VIDEO:
             default:
                 break;
             }
                         int bytesDecoded, frameFinished;
                         AVFrame *frame;
                         frame=avcodec_alloc_frame();
-                        bytesDecoded = avcodec_decode_video(movie->video_st->codec, frame, &frameFinished, pkt->data, pkt->size);
+                        /* TODO: FIXME avcodec_decode_video is old api.
+                        bytesDecoded = avcodec_decode_video(movie->video_st->codec, 
+                                                            frame, 
+                                                            &frameFinished, 
+                                                            pkt->data, 
+                                                            pkt->size);
+                        */
+                        bytesDecoded = avcodec_decode_video2(movie->video_st->codec, 
+                                                             frame, 
+                                                             &frameFinished, 
+                                                             pkt);
+
                         if(frameFinished)
                         {
                             if((pkt->pts >= vid_seek_target) || (pkt->dts >= vid_seek_target))
 #else
         movie->video_st->codec->reordered_opaque= pkt->pts;
 #endif
+
+        /* TODO: FIXME: avcodec_decode_video is old API.
         len1 = avcodec_decode_video(movie->video_st->codec,
                                     frame, &got_picture,
                                     pkt->data, pkt->size);
+        */
+        len1 = avcodec_decode_video2(movie->video_st->codec,
+                                    frame, &got_picture,
+                                    pkt);
+
+
 #if LIBAVCODEC_VERSION_INT<3412992
 		if((pkt->dts == AV_NOPTS_VALUE)) //(52<<16)+(20<<8)+0 ie 52.20.0
         {
 
 #define BPP 1
 
+
+#define PYG_MEDIA_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
+#define PYG_MEDIA_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
+#define PYG_MEDIA_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE
+
+/*
+#define PYG_MEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
+#define PYG_MEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
+#define PYG_MEDIA_TYPE_SUBTITLE CODEC_TYPE_SUBTITLE
+*/
+
+
+
+
+/*
+#ifdef AVMEDIA_TYPE_AUDIO
+    #define PYG_MEDIA_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
+#endif
+#if defined(CODEC_TYPE_AUDIO)
+    #define PYG_MEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
+#endif
+
+#if defined(AVMEDIA_TYPE_VIDEO)
+    #define PYG_MEDIA_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
+#endif
+#if defined(CODEC_TYPE_VIDEO)
+    #define PYG_MEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
+#endif
+
+#if defined(AVMEDIA_TYPE_SUBTITLE)
+    #define PYG_MEDIA_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE
+#endif
+#if defined(CODEC_TYPE_SUBTITLE)
+    #define PYG_MEDIA_TYPE_SUBTITLE CODEC_TYPE_SUBTITLE
+#endif
+*/
+
+
+
+
 //enables profiling info to be gathered
 //#define PROFILE 1
 
 /* some constants used which are not defined on non-v4l machines. */
 #ifndef V4L2_PIX_FMT_RGB24
     #define V4L2_PIX_FMT_RGB24 'RGB3'
+#endif
+#ifndef V4L2_PIX_FMT_RGB444
     #define V4L2_PIX_FMT_RGB444 'R444'
+#endif
+#ifndef V4L2_PIX_FMT_YUYV
     #define V4L2_PIX_FMT_YUYV 'YUYV'
 #endif
 
-
-
 #define CLEAR(x) memset (&(x), 0, sizeof (x))
 #define SAT(c) if (c & (~255)) { if (c < 0) c = 0; else c = 255; }
 #define SAT2(c) ((c) & (~255) ? ((c) < 0 ? 0 : 255) : (c))
 
     if (!PyArg_ParseTuple (args, "O|OOO", &obj, &obj1, &obj2, &obj3))
         return NULL;
-
-    if (Text_Check (obj))
+    
+    if (Text_Check (obj) || PyUnicode_Check (obj))
     {
         /* Named color */
         PyObject *color = NULL;
 	
         switch(enc->codec_type)
         {
-        case CODEC_TYPE_AUDIO:
+        case PYG_MEDIA_TYPE_AUDIO:
             self->sample_rate=enc->sample_rate;
 	    	self->channels = enc->channels;
 	    	self->aud_codec = (char *)PyMem_Malloc((sizeof(char)*strlen(codec->name))+sizeof(char));
 	    	strncpy(self->aud_codec, codec->name, strlen(codec->name)+1);
 	    	break;
-        case CODEC_TYPE_VIDEO:
+        case PYG_MEDIA_TYPE_VIDEO:
             self->width = enc->width;
 	    	self->height = enc->height;
 	    	self->aspect_ratio = (double)self->width/(double)self->height;
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                                        0xff0000, 0xff00, 0xff, 0x000000ff
 #else
-                                       0xff, 0xff00, 0xff0000, 0xff000000
+                                       0xff00, 0xff, 0xff0000, 0xff000000
 #endif
         );
 
         ss_surface = SDL_CreateRGBSurface (SDL_SWSURFACE,
                                        ss_w, ss_h, pixel_bits,
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
-                                       0xff0000, 0xff00, 0xff, 0x000000ff
+                                       0xff00, 0xff, 0xff0000, 0xff000000
 #else
                                        0xff, 0xff00, 0xff0000, 0xff000000
 #endif

src/sdlmain_osx.m

 #include "pgcompat.h"
 #include "scrap.h"
 
+#include <AvailabilityMacros.h>
+/* We support OSX 10.6 and below. */
+#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1060
+	#define PYGAME_MAC_SCRAP_OLD 1
+#endif
+
+
+
+
 struct CPSProcessSerNum
 {
 	UInt32 lo;
 _ScrapGet(PyObject *self, PyObject *args) {
 	PyObject *ret = Py_None;
 	char *scrap_type;
-
+#if defined (PYGAME_MAC_SCRAP_OLD)
+	return Py_None;
+#else
 	if (!PyArg_ParseTuple (args, "s", &scrap_type))
 		return Py_None;
 
 		ret = PyUnicode_FromString([info UTF8String]);
 	[pool release];
 	return ret;
+#endif
 }
 
 static PyObject*
 _ScrapGetTypes(PyObject *self) {
+#if defined (PYGAME_MAC_SCRAP_OLD)
+	return Py_None;
+#else
 	PyObject *l = PyList_New(0);
 	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 	NSPasteboard *pb = [NSPasteboard generalPasteboard];
 		PyList_Append(l, PyUnicode_FromString([type UTF8String]));
 	[pool release];
 	return l;
+#endif
 }
 
 static PyObject*
 _ScrapPut(PyObject *self, PyObject *args) {
+#if defined (PYGAME_MAC_SCRAP_OLD)
+	return Py_None;
+#else
 	PyObject *ret = NULL;
 	char *scrap_type;
 	char *data;
 	[pb setString:ndata forType: NSStringPboardType];
 	[pool release];
 	return Py_None;
+#endif
 }
 
 static PyObject*
 _ScrapSetMode(PyObject *self, PyObject *args) {
+#if defined (PYGAME_MAC_SCRAP_OLD)
+	return Py_None;
+#else
 	char *mode;
 	if (!PyArg_ParseTuple (args, "s", &mode))
 		return Py_None;
 	return Py_None;
+#endif
 }
 
 static PyObject*
 _ScrapContains(PyObject *self, PyObject *args) {
+#if defined (PYGAME_MAC_SCRAP_OLD)
+	return Py_None;
+#else
 	char *mode;
 	int found = 0;
 	if (!PyArg_ParseTuple (args, "s", &mode))
 	[pool release];
 
 	return found ? Py_True : Py_False;
+#endif
 }
 
 static PyObject*
 _ScrapLost(PyObject *self) {
+#if defined (PYGAME_MAC_SCRAP_OLD)
+	return Py_None;
+#else
 	int found = 0;
 	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 	NSArray *supportedTypes =
 	[pool release];
 
 	return found ? Py_False : Py_True;
+#endif
 }
 
 static PyMethodDef macosx_builtins[] =
         sdlrect.y = rect->y;
         sdlrect.w = rect->w;
         sdlrect.h = rect->h;
-        
-
-
 
         // clip the rect to be within the surface.
+        if(sdlrect.x + sdlrect.w <= 0 || sdlrect.y + sdlrect.h <= 0) {
+            sdlrect.w = 0;
+            sdlrect.h = 0;
+        }
+
         if (sdlrect.x < 0) {
             sdlrect.x = 0;
         }
             sdlrect.h = sdlrect.h + (surf->h - (sdlrect.y + sdlrect.h));
         }
 
+        /* printf("%d, %d, %d, %d\n", sdlrect.x, sdlrect.y, sdlrect.w, sdlrect.h); */
 
 
         if (blendargs != 0) {
 int
 surface_fill_blend (SDL_Surface *surface, SDL_Rect *rect, Uint32 color,
                     int blendargs);
+                    
+void
+surface_respect_clip_rect (SDL_Surface *surface, SDL_Rect *rect);
 
 int 
 pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect,

src/surface_fill.c

 #define NO_PYGAME_C_API
 #include "surface.h"
 
+/*
+ * Changes SDL_Rect to respect any clipping rect defined on the surface.
+ * Necessary when modifying surface->pixels directly instead of through an
+ * SDL interface.
+ */
+void surface_respect_clip_rect (SDL_Surface *surface, SDL_Rect *rect)
+{
+	SDL_Rect tmp;
+	SDL_Rect *A, *B;
+    int x, y, w, h;
+
+    A = rect;
+	B = &tmp;
+    SDL_GetClipRect(surface, B);
+	
+	/* Code here is nearly identical to rect_clip in rect.c */
+
+    /* Left */
+    if ((A->x >= B->x) && (A->x < (B->x + B->w)))
+        x = A->x;
+    else if ((B->x >= A->x) && (B->x < (A->x + A->w)))
+        x = B->x;
+    else
+        return;
+
+    /* Right */
+    if (((A->x + A->w) > B->x) && ((A->x + A->w) <= (B->x + B->w)))
+        w = (A->x + A->w) - x;
+    else if (((B->x + B->w) > A->x) && ((B->x + B->w) <= (A->x + A->w)))
+        w = (B->x + B->w) - x;
+    else
+        return;
+
+    /* Top */
+    if ((A->y >= B->y) && (A->y < (B->y + B->h)))
+        y = A->y;
+    else if ((B->y >= A->y) && (B->y < (A->y + A->h)))
+        y = B->y;
+    else
+        return;
+
+    /* Bottom */
+    if (((A->y + A->h) > B->y) && ((A->y + A->h) <= (B->y + B->h)))
+        h = (A->y + A->h) - y;
+    else if (((B->y + B->h) > A->y) && ((B->y + B->h) <= (A->y + A->h)))
+        h = (B->y + B->h) - y;
+    else
+        return;
+
+    rect->x = x;
+    rect->y = y;
+    rect->w = w;
+    rect->h = h;
+}
 
 static int
 surface_fill_blend_add (SDL_Surface *surface, SDL_Rect *rect, Uint32 color)
 {
     int result = -1;
     int locked = 0;
+    
+    surface_respect_clip_rect(surface, rect);
 
     /* Lock the surface, if needed */
     if (SDL_MUSTLOCK (surface))

test/surface_test.py

 
 if is_pygame_pkg:
     from pygame.tests import test_utils
-    from pygame.tests.test_utils import test_not_implemented, unittest
+    from pygame.tests.test_utils import test_not_implemented, unittest, example_path
     try:
         from pygame.tests.test_utils.arrinter import *
     except ImportError:
         pass
 else:
     from test import test_utils
-    from test.test_utils import test_not_implemented, unittest
+    from test.test_utils import test_not_implemented, unittest, example_path
     try:
         from test.test_utils.arrinter import *
     except ImportError:
         for pt in test_utils.rect_outer_bounds(fill_rect):
             self.assert_(s1.get_at(pt) != color )
 
+
+
+    def test_fill_negative_coordinates(self):
+
+        # negative coordinates should be clipped by fill, and not draw outside the surface.
+        color = (25, 25, 25, 25)
+        color2 = (20, 20, 20, 25)
+        fill_rect = pygame.Rect(-10, -10, 16, 16)
+        
+        s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32)
+        r1 = s1.fill(color, fill_rect)   
+        c = s1.get_at((0,0))
+        self.assertEqual(c, color)
+
+        # make subsurface in the middle to test it doesn't over write.
+        s2 = s1.subsurface((5, 5, 5, 5))
+        r2 = s2.fill(color2, (-3, -3, 5, 5))
+        c2 = s1.get_at((4,4))
+        self.assertEqual(c, color)
+
+        # rect returns the area we actually fill.
+        r3 = s2.fill(color2, (-30, -30, 5, 5))
+        # since we are using negative coords, it should be an zero sized rect.
+        self.assertEqual(tuple(r3), (0, 0, 0, 0))
+
+
+
+
+
     def test_fill_keyword_args(self):
         color = (1, 2, 3, 255)
         area = (1, 1, 2, 2)
         source.set_at((0, 0), color)
         target.blit(source, (0, 0))
 
+    def test_image_convert_bug_131(self):
+        # Bitbucket bug #131: Unable to Surface.convert(32) some 1-bit images.
+        # https://bitbucket.org/pygame/pygame/issue/131/unable-to-surfaceconvert-32-some-1-bit
+        pygame.display.init()
+        pygame.display.set_mode((640,480))
+
+        im  = pygame.image.load(example_path(os.path.join("data", "city.png")))
+        im2 = pygame.image.load(example_path(os.path.join("data", "brick.png")))
+
+        self.assertEquals( im.get_palette(),  ((0, 0, 0, 255), (255, 255, 255, 255)) )
+        self.assertEquals( im2.get_palette(), ((0, 0, 0, 255), (0, 0, 0, 255)) )
+
+        self.assertEqual(repr(im.convert(32)),  '<Surface(24x24x32 SW)>')
+        self.assertEqual(repr(im2.convert(32)), '<Surface(469x137x32 SW)>')
+
     def todo_test_convert(self):
 
         # __doc__ (as of 2008-08-02) for pygame.surface.Surface.convert:
             d.blit(s, (0, 0))
         sub = surf.subsurface((1, 1, 2, 2))
         self.failUnlessRaises(pygame.error, do_blit, surf, sub)
-        
+
+
+class SurfaceFillTest(unittest.TestCase):
+    def test_fill(self):
+        pygame.init()
+        try:
+            screen = pygame.display.set_mode((640, 480))
+
+            # Green and blue test pattern
+            screen.fill((0, 255, 0), (0, 0, 320, 240))
+            screen.fill((0, 255, 0), (320, 240, 320, 240))
+            screen.fill((0, 0, 255), (320, 0, 320, 240))
+            screen.fill((0, 0, 255), (0, 240, 320, 240))
+
+            # Now apply a clip rect, such that only the left side of the
+            # screen should be effected by blit opperations.
+            screen.set_clip((0, 0, 320, 480))
+
+            # Test fills with each special flag, and additionaly without any.
+            screen.fill((255, 0, 0, 127), (160, 0, 320, 30), 0)
+            screen.fill((255, 0, 0, 127), (160, 30, 320, 30), pygame.BLEND_ADD)
+            screen.fill((0, 127, 127, 127), (160, 60, 320, 30), pygame.BLEND_SUB)
+            screen.fill((0, 63, 63, 127), (160, 90, 320, 30), pygame.BLEND_MULT)
+            screen.fill((0, 127, 127, 127), (160, 120, 320, 30), pygame.BLEND_MIN)
+            screen.fill((127, 0, 0, 127), (160, 150, 320, 30), pygame.BLEND_MAX)
+            screen.fill((255, 0, 0, 127), (160, 180, 320, 30), pygame.BLEND_RGBA_ADD)
+            screen.fill((0, 127, 127, 127), (160, 210, 320, 30), pygame.BLEND_RGBA_SUB)
+            screen.fill((0, 63, 63, 127), (160, 240, 320, 30), pygame.BLEND_RGBA_MULT)
+            screen.fill((0, 127, 127, 127), (160, 270, 320, 30), pygame.BLEND_RGBA_MIN)
+            screen.fill((127, 0, 0, 127), (160, 300, 320, 30), pygame.BLEND_RGBA_MAX)
+            screen.fill((255, 0, 0, 127), (160, 330, 320, 30), pygame.BLEND_RGB_ADD)
+            screen.fill((0, 127, 127, 127), (160, 360, 320, 30), pygame.BLEND_RGB_SUB)
+            screen.fill((0, 63, 63, 127), (160, 390, 320, 30), pygame.BLEND_RGB_MULT)
+            screen.fill((0, 127, 127, 127), (160, 420, 320, 30), pygame.BLEND_RGB_MIN)
+            screen.fill((255, 0, 0, 127), (160, 450, 320, 30), pygame.BLEND_RGB_MAX)
+
+            # Update the display so we can see the results
+            pygame.display.flip()
+
+            # Compare colors on both sides of window
+            y = 5
+            while y < 480:
+                self.assertEquals(screen.get_at((10, y)),
+                        screen.get_at((330, 480 - y)))
+                y += 10
+
+        finally:
+            pygame.quit()
 
 if __name__ == '__main__':
     unittest.main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.