Mercurial > pygame
changeset 1849:301bc61643a9 math_module
merged changes from trunk
line wrap: on
line diff
--- a/MANIFEST.in Mon Nov 16 18:05:30 2009 +0000 +++ b/MANIFEST.in Mon Nov 16 18:31:40 2009 +0000 @@ -1,4 +1,4 @@ -include Setup.in Setup_Darwin.in Setup_Win_Common.in *.py WHATSNEW readme.txt install.html LGPL +include Setup.in Setup_Darwin.in Setup_Win_Common.in *.py WHATSNEW readme.txt install.html readme.html LGPL recursive-include docs * recursive-include lib *
--- a/Makefile Mon Nov 16 18:05:30 2009 +0000 +++ b/Makefile Mon Nov 16 18:31:40 2009 +0000 @@ -15,6 +15,9 @@ check tests: $(PYTHON) run_tests.py +test: build test src + $(PYTHON) run_tests.py + docs: install cd docs/utils $(PYTHON) makedocs.py
--- a/Setup.in Mon Nov 16 18:05:30 2009 +0000 +++ b/Setup.in Mon Nov 16 18:31:40 2009 +0000 @@ -17,9 +17,11 @@ SCRAP = -lX11 PORTMIDI = -lportmidi PORTTIME = -lporttime +FREETYPE = -lfreetype +AVFORMAT = -lavformat +SWSCALE = -lswscale #--EndConfig -#DEBUG = -C-W -C-Wall DEBUG = #the following modules are optional. you will want to compile @@ -33,15 +35,18 @@ _numericsurfarray src/_numericsurfarray.c $(SDL) $(DEBUG) _numericsndarray src/_numericsndarray.c $(SDL) $(MIXER) $(DEBUG) movie src/movie.c $(SDL) $(SMPEG) $(DEBUG) +#_movie src/_gsound.c src/_gmovie.c src/_gcommand.c src/gmovie.c $(SDL) $(AVFORMAT) $(SWSCALE) $(MIXER) $(DEBUG) scrap src/scrap.c $(SDL) $(SCRAP) $(DEBUG) -_camera src/_camera.c src/camera_v4l2.c src/camera_v4l.c $(SDL) $(DEBUG) +#_camera src/_camera.c src/camera_v4l2.c src/camera_v4l.c $(SDL) $(DEBUG) pypm src/pypm.c $(SDL) $(PORTMIDI) $(PORTTIME) $(DEBUG) GFX = src/SDL_gfx/SDL_gfxPrimitives.c #GFX = src/SDL_gfx/SDL_gfxBlitFunc.c src/SDL_gfx/SDL_gfxPrimitives.c gfxdraw src/gfxdraw.c $(SDL) $(GFX) $(DEBUG) - +#optional freetype module (do not break in multiple lines +#or the configuration script will choke!) +#freetype src/freetype/ft_cache.c src/freetype/ft_metrics.c src/freetype/ft_wrap.c src/freetype/ft_render.c src/freetype/ft_render_cb.c src/freetype/ft_text.c src/freetype.c $(SDL) $(FREETYPE) $(DEBUG) #these modules are required for pygame to run. they only require #SDL as a dependency. these should not be altered
--- a/Setup_Darwin.in Mon Nov 16 18:05:30 2009 +0000 +++ b/Setup_Darwin.in Mon Nov 16 18:31:40 2009 +0000 @@ -1,2 +1,3 @@ #This file defines platform specific modules for mac os x sdlmain_osx src/sdlmain_osx.m $(SDL) $(DEBUG) +_camera src/_camera.c src/camera_mac.m $(SDL) $(DEBUG)
--- a/WHATSNEW Mon Nov 16 18:05:30 2009 +0000 +++ b/WHATSNEW Mon Nov 16 18:31:40 2009 +0000 @@ -4,6 +4,10 @@ # BREAK = change breaks existing code # BUG = fixed a bug that was (or could have been) crashing +[SVN 2573] August 6, 2009 + [BUG] missing readme.html in MANIFEST.in causes install to fail + on pythons with setuptools installed. + [SVN 2519] July 17, 2009 [BUG] fix pygame.font.get_fonts() bug for Python 3.1 and Windows.
--- a/config.py Mon Nov 16 18:05:30 2009 +0000 +++ b/config.py Mon Nov 16 18:31:40 2009 +0000 @@ -97,7 +97,26 @@ newsetup.write(d.line + '\n') lines = origsetup.readlines() - lines.extend(additional_lines) + + # overwrite lines which already exist with new ones. + new_lines = [] + for l in lines: + addit = 1 + parts = l.split() + for al in additional_lines: + aparts = al.split() + if aparts and parts: + if aparts[0] == parts[0]: + #print ('the same!' + repr(aparts) + repr(parts)) + #the same, we should not add the old one. + #It will be overwritten by the new one. + addit = 0 + if addit: + new_lines.append(l) + + new_lines.extend(additional_lines) + lines = new_lines + for line in lines: useit = 1 if not line.startswith('COPYLIB'):
--- a/config_darwin.py Mon Nov 16 18:05:30 2009 +0000 +++ b/config_darwin.py Mon Nov 16 18:31:40 2009 +0000 @@ -3,6 +3,7 @@ import os, sys, string from glob import glob from distutils.sysconfig import get_python_inc +from config_unix import DependencyProg class Dependency: libext = '.a' @@ -91,11 +92,16 @@ FrameworkDependency('IMAGE', 'SDL_image.h', 'libSDL_image', 'SDL_image'), FrameworkDependency('MIXER', 'SDL_mixer.h', 'libSDL_mixer', 'SDL_mixer'), FrameworkDependency('SMPEG', 'smpeg.h', 'libsmpeg', 'smpeg'), + FrameworkDependency('PORTTIME', 'CoreMidi.h', 'CoreMidi', 'CoreMidi'), + FrameworkDependency('QUICKTIME', 'QuickTime.h', 'QuickTime', 'QuickTime'), Dependency('PNG', 'png.h', 'libpng', ['png']), Dependency('JPEG', 'jpeglib.h', 'libjpeg', ['jpeg']), Dependency('SCRAP', '','',[]), Dependency('PORTMIDI', 'portmidi.h', 'libportmidi', ['portmidi']), - FrameworkDependency('PORTTIME', 'CoreMidi.h', 'CoreMidi', 'CoreMidi'), + DependencyProg('FREETYPE', 'FREETYPE_CONFIG', '/usr/X11R6/bin/freetype-config', '2.0', + ['freetype'], '--ftversion'), + Dependency('AVFORMAT', '','',[]), + Dependency('SWSCALE', '','',[]), ] @@ -103,7 +109,7 @@ global DEPS print ('Hunting dependencies...') - incdirs = ['/usr/local/include','/opt/local/include'] + incdirs = ['/usr/local/include','/opt/local/include', '/opt/local/include/freetype2/freetype'] libdirs = ['/usr/local/lib','/opt/local/lib'] newconfig = [] for d in DEPS:
--- a/config_msys.py Mon Nov 16 18:05:30 2009 +0000 +++ b/config_msys.py Mon Nov 16 18:31:40 2009 +0000 @@ -235,6 +235,11 @@ Dependency('JPEG', 'jpeglib.h', 'libjpeg.dll.a'), Dependency('PORTMIDI', 'portmidi.h', 'libportmidi.dll.a'), Dependency('PORTTIME', 'portmidi.h', 'libportmidi.dll.a'), + Dependency('AVFORMAT', 'libavformat/avformat.h', 'libavformat.a'), + Dependency('AVCODEC', 'libavcodec/avcodec.h', 'libavcodec.a'), + Dependency('AVUTIL', 'libavutil/avutil.h', 'libavutil.a'), + Dependency('AVDEVICE', 'libavdevice/avdevice.h', 'libavdevice.a'), + Dependency('SWSCALE', 'libswscale/swscale.h', 'libswscale.a'), DependencyDLL('TIFF'), DependencyDLL('VORBISFILE'), DependencyDLL('VORBIS'),
--- a/config_unix.py Mon Nov 16 18:05:30 2009 +0000 +++ b/config_unix.py Mon Nov 16 18:31:40 2009 +0000 @@ -16,7 +16,7 @@ #these get prefixes with '/usr' and '/usr/local' or the $LOCALBASE origincdirs = ['/include', '/include/SDL', '/include/SDL', - '/include/smpeg' ] + '/include/smpeg'] origlibdirs = ['/lib','/lib64','/X11R6/lib'] def confirm(message): @@ -27,7 +27,7 @@ return 1 class DependencyProg: - def __init__(self, name, envname, exename, minver, defaultlibs): + def __init__(self, name, envname, exename, minver, defaultlibs, version_flag="--version"): self.name = name command = os.environ.get(envname, exename) self.lib_dir = '' @@ -35,7 +35,12 @@ self.libs = [] self.cflags = '' try: - config = os.popen(command + ' --version --cflags --libs').readlines() + # freetype-config for freetype2 version 2.3.7 on Debian lenny + # does not recognize multiple command line options. So execute + # 'command' separately for each option. + config = (os.popen(command + ' ' + version_flag).readlines() + + os.popen(command + ' --cflags').readlines() + + os.popen(command + ' --libs').readlines()) flags = ' '.join(config[1:]).split() # remove this GNU_SOURCE if there... since python has it already, @@ -102,6 +107,40 @@ else: print (self.name + ' '[len(self.name):] + ': not found') + +class FFMPEGDependency(Dependency): + def __init__(self, name, checkhead, checklib, libs, dirs): + self.dirs=dirs + Dependency.__init__(self, name, checkhead, checklib, libs) + self.cflags="" + + def configure(self, incdirs, libdirs): + incname = self.checkhead + libnames = self.checklib, self.name.lower() + + dirs=self.dirs[:] + self.dirs = ["/usr"+d for d in dirs] + self.dirs += ["/usr/local"+d for d in dirs] + loc_incdirs = incdirs[:]+self.dirs + if incname: + for dir in loc_incdirs: + path = os.path.join(dir, incname) + if os.path.isfile(path): + self.inc_dir = dir + + for dir in libdirs: + for name in libnames: + path = os.path.join(dir, name) + if filter(os.path.isfile, glob(path+'*')): + self.lib_dir = dir + + if (incname and self.lib_dir and self.inc_dir) or (not incname and self.lib_dir): + print (self.name + ' '[len(self.name):] + ': found') + self.found = 1 + else: + print (self.name + ' '[len(self.name):] + ': not found') + + class DependencyPython: def __init__(self, name, module, header): self.name = name @@ -147,6 +186,9 @@ Dependency('SCRAP', '', 'libX11', ['X11']), Dependency('PORTMIDI', 'portmidi.h', 'libportmidi.so', ['portmidi']), Dependency('PORTTIME', 'porttime.h', 'libporttime.so', ['porttime']), + FFMPEGDependency('AVFORMAT', 'avformat.h', 'libavformat.a', ['avformat'], ['/include/libavformat', '/include/ffmpeg']), + FFMPEGDependency('SWSCALE', 'swscale.h', 'libswscale.a', ['swscale'], ['/include/libswscale', '/include/ffmpeg']), + DependencyProg('FREETYPE', 'FREETYPE_CONFIG', 'freetype-config', '2.0', ['freetype'], '--ftversion'), #Dependency('GFX', 'SDL_gfxPrimitives.h', 'libSDL_gfx.so', ['SDL_gfx']), ] if not DEPS[0].found:
--- a/config_win.py Mon Nov 16 18:05:30 2009 +0000 +++ b/config_win.py Mon Nov 16 18:31:40 2009 +0000 @@ -55,7 +55,7 @@ print ('Too bad that is a requirement! Hand-fix the "Setup"') elif len(self.paths) == 1: self.path = self.paths[0] - print ("Path for %s:' % self.name") + print ("Path for %s:%s" % (self.name, self.path)) else: print ("Select path for %s:" % self.name) for i in range(len(self.paths)): @@ -210,6 +210,12 @@ DEPS.add('PNG', 'png', ['libpng-[1-9].*'], r'(png|libpng13)\.dll$', ['z']) DEPS.add('JPEG', 'jpeg', ['jpeg-[6-9]*'], r'(lib){0,1}jpeg\.dll$') DEPS.add('PORTMIDI', 'portmidi', ['portmidi'], r'portmidi\.dll$') +#DEPS.add('FFMPEG', 'libavformat/avformat.h', 'libavformat.a', ['avformat', 'swscale', 'SDL_mixer'], r'avformat-52\.dll') +dep = Dependency('FFMPEG', [r'avformat\.dll', r'swscale\.dll', r'SDL_mixer-[1-9].*'], ['avformat', 'swscale', 'SDL_mixer'], required=0) +DEPS.dependencies.append(dep) +DEPS.dlls.append(DependencyDLL(r'avformat\.dll', link=dep, libs=['avformat'])) +DEPS.dlls.append(DependencyDLL(r'swscale\.dll', link=dep, libs=['swscale'])) +DEPS.dlls.append(DependencyDLL(r'(lib){0,1}SDL_mixer\.dll$', link=dep, libs=['SDL', 'vorbisfile', 'smpeg'])) #DEPS.add('PORTTIME', 'porttime', ['porttime'], r'porttime\.dll$') DEPS.add_dll(r'(lib){0,1}tiff\.dll$', 'tiff', ['tiff-[3-9].*'], ['jpeg', 'z']) DEPS.add_dll(r'(z|zlib1)\.dll$', 'z', ['zlib-[1-9].*'])
--- a/dll.py Mon Nov 16 18:05:30 2009 +0000 +++ b/dll.py Mon Nov 16 18:31:40 2009 +0000 @@ -34,6 +34,11 @@ ('SDL', 'SDL', r'SDL\.dll$', []), ('PORTMIDI', 'portmidi', r'portmidi\.dll', []), ('PORTTIME', 'portmidi', r'portmidi\.dll', []), + ('AVCODEC', 'avcodec', r'avcodec\.dll', []), + ('AVFORMAT', 'avformat', r'avformat-52\.dll', []), + ('AVDEVICE', 'avdevice', r'avdevice-52\.dll', []), + ('AVUTIL', 'avutil', r'avutil\.dll', []), + ('SWSCALE', 'swscale', r'swscale\.dll', []), ] # regexs: Maps name to DLL file name regex.
--- a/docs/ref/camera.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/camera.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/cdrom.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/cdrom.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/color.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/color.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/cursors.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/cursors.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/display.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/display.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/draw.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/draw.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/event.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/event.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/examples.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/examples.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/font.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/font.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> || @@ -147,7 +148,7 @@ <tt>pygame.font.Font(filename, size): return Font</tt><br> <tt>pygame.font.Font(object, size): return Font</tt><br> <ul><small><table> - <tr><td><a href="font.html#Font.render">Font.render</a> - <font size=-1>draw text on a new Surface</font></td><td>draw text on a new Surface</td></tr> + <tr><td><a href="freetype.html#Font.render">Font.render</a> - <font size=-1>Renders text on a surface</font></td><td>draw text on a new Surface</td></tr> <tr><td><a href="font.html#Font.size">Font.size</a> - <font size=-1>determine the amount of space needed to render text</font></td><td>determine the amount of space needed to render text</td></tr> <tr><td><a href="font.html#Font.set_underline">Font.set_underline</a> - <font size=-1>control if text is rendered with an underline</font></td><td>control if text is rendered with an underline</td></tr> <tr><td><a href="font.html#Font.get_underline">Font.get_underline</a> - <font size=-1>check if text will be rendered with an underline</font></td><td>check if text will be rendered with an underline</td></tr> @@ -170,7 +171,7 @@ <big><b>Font.render</big></b><br><ul> <i>draw text on a new Surface</i><br> <tt>Font.render(text, antialias, color, background=None): return Surface</tt><br> -<p>This creates a new Surface with the specified text rendered on it. Pygame provides no way to directly draw text on an existing Surface: instead you must use <tt><a href="font.html#Font.render">Font.render</a> - <font size=-1>draw text on a new Surface</font></tt> to create an image (Surface) of the text, then blit this image onto another Surface. </p> +<p>This creates a new Surface with the specified text rendered on it. Pygame provides no way to directly draw text on an existing Surface: instead you must use <tt><a href="freetype.html#Font.render">Font.render</a> - <font size=-1>Renders text on a surface</font></tt> to create an image (Surface) of the text, then blit this image onto another Surface. </p> <p>The text can only be a single line: newline characters are not rendered. The antialias argument is a boolean: if true the characters will have smooth edges. The color argument is the color of the text <tt>[e.g.:</tt> (0,0,255) for blue]. The optional background argument is a color to use for the text background. If no background is passed the area outside the text will be transparent. </p> <p>The Surface returned will be of the dimensions required to hold the text. (the same as those returned by <tt>Font.size())</tt>. If an empty string is passed for the text, a blank surface will be returned that is one pixel wide and the height of the font. </p> <p>Depending on the type of background and antialiasing used, this returns different types of Surfaces. For performance reasons, it is good to know what type of image will be used. If antialiasing is not used, the return image will always be an 8bit image with a two color palette. If the background is transparent a colorkey will be set. Antialiased images are rendered to 24-bit <tt>RGB</tt> images. If the background is transparent a pixel alpha will be included. </p>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/ref/freetype.html Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,289 @@ + +<html> +<title>freetype - Pygame Documentation</title> +<body bgcolor=#aaeebb text=#000000 link=#331111 vlink=#331111> + + +<table cellpadding=0 cellspacing=0 border=0 style='border: 3px solid black;' width='100%'> +<tr> +<td bgcolor='#c2fc20' style='padding: 6px;' align=center valign=center><a href='http://www.pygame.org/'><img src='../pygame_tiny.gif' border=0 width=200 height=60></a><br><b>pygame documentation</b></td> +<td bgcolor='#6aee28' style='border-left: 3px solid black; padding: 6px;' align=center valign=center> + || + <a href=http://www.pygame.org>Pygame Home</a> || + <a href=../index.html>Help Contents</a> || + <a href=index.html>Reference Index</a> || + <br> <br> + +<a href="camera.html">Camera</a> || +<a href="cdrom.html">Cdrom</a> || +<a href="color.html">Color</a> || +<a href="cursors.html">Cursors</a> || +<a href="display.html">Display</a> || +<a href="draw.html">Draw</a> || +<a href="event.html">Event</a> || +<a href="examples.html">Examples</a> || +<a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || +<a href="gfxdraw.html">Gfxdraw</a> || +<a href="image.html">Image</a> || +<a href="joystick.html">Joystick</a> || +<a href="key.html">Key</a> || +<a href="locals.html">Locals</a> || +<a href="mask.html">Mask</a> || +<a href="midi.html">Midi</a> || +<a href="mixer.html">Mixer</a> || +<a href="mouse.html">Mouse</a> || +<a href="movie.html">Movie</a> || +<a href="music.html">Music</a> || +<a href="overlay.html">Overlay</a> || +<a href="pixelarray.html">Pixelarray</a> || +<a href="pygame.html">Pygame</a> || +<a href="rect.html">Rect</a> || +<a href="scrap.html">Scrap</a> || +<a href="sndarray.html">Sndarray</a> || +<a href="sprite.html">Sprite</a> || +<a href="surface.html">Surface</a> || +<a href="surfarray.html">Surfarray</a> || +<a href="tests.html">Tests</a> || +<a href="time.html">Time</a> || +<a href="transform.html">Transform</a> +</td></tr></table> +<br> + + +<a name="pygame.freetype"> +<big><b>pygame.freetype</big></b><br><ul> + <i>Enhanced Pygame module for loading and rendering fonts</i><br> +<ul><small><table> + <tr><td><a href="freetype.html#pygame.freetype.get_error">pygame.freetype.get_error</a> - <font size=-1>Get the latest error</font></td><td>Get the latest error</td></tr> + <tr><td><a href="freetype.html#pygame.freetype.get_version">pygame.freetype.get_version</a> - <font size=-1>Get the FreeType version</font></td><td>Get the FreeType version</td></tr> + <tr><td><a href="freetype.html#pygame.freetype.init">pygame.freetype.init</a> - <font size=-1>Initialize the underlying FreeType 2 library.</font></td><td>Initialize the underlying FreeType 2 library.</td></tr> + <tr><td><a href="freetype.html#pygame.freetype.quit">pygame.freetype.quit</a> - <font size=-1>Shuts down the underlying FreeType 2 library.</font></td><td>Shuts down the underlying FreeType 2 library.</td></tr> + <tr><td><a href="freetype.html#pygame.freetype.was_init">pygame.freetype.was_init</a> - <font size=-1>Returns whether the the FreeType 2 library is initialized.</font></td><td>Returns whether the the FreeType 2 library is initialized.</td></tr> + <tr><td><a href="freetype.html#pygame.freetype.Font">pygame.freetype.Font</a> - <font size=-1>Creates a new Font from a supported font file.</font></td><td>Creates a new Font from a supported font file.</td></tr> +</table></small></ul> +<p>This module allows for rendering all font formats supported by FreeType, namely <tt>TTF</tt>, Type1, <tt>CFF</tt>, OpenType, <tt>SFNT</tt>, <tt>PCF</tt>, <tt>FNT</tt>, <tt>BDF</tt>, <tt>PFR</tt> and Type42 fonts. </p> +<p>This module is optional, and replaces all of the functionality of the original 'font' module, whilst expanding it. This module depends in no way on the SDL_ttf library. </p> +<p>You should test that <tt>pygame.freetype</tt> is initialized before attempting to use the module; if the module is available and loaded, it will be automatically initialized by <tt><a href="pygame.html#pygame.init">pygame.init</a> - <font size=-1>initialize all imported pygame modules</font></tt> </p> +<p>Most of the work done with fonts is done by using the actual Font objects. The module by itself only has routines to initialize itself and create Font objects with <tt><a href="freetype.html#pygame.freetype.Font">pygame.freetype.Font</a> - <font size=-1>Creates a new Font from a supported font file.</font></tt>. </p> +<p>You can load fonts from the system by using the <tt>pygame.freetype.SysFont()</tt> function. There are a few other functions to help lookup the system fonts. </p> +<p>Pygame comes with a builtin default font. This can always be accessed by passing None as the font name to the Font constructor. </p> +<!--COMMENTS:pygame.freetype--> <br> + + +<a name="pygame.freetype.get_error"> +<big><b>pygame.freetype.get_error</big></b><br><ul> + <i>Get the latest error</i><br> + <tt>pygame.freetype.get_error(): return str</tt><br> +<p>Returns the description of the last error which occurred in the FreeType library, or None if no errors have occurred. </p> +<!--COMMENTS:pygame.freetype.get_error--> <br> +<br></ul> + + +<a name="pygame.freetype.get_version"> +<big><b>pygame.freetype.get_version</big></b><br><ul> + <i>Get the FreeType version</i><br> + <tt>pygame.freetype.get_version(): return (int, int, int)</tt><br> +<p>Gets the version of the FreeType2 library which was used to build the 'freetype' module. </p> +<p>Note that the FreeType module depends on the FreeType 2 library, and will not compile with the original FreeType <tt>1.0</tt>, hence the first element of the tuple will always be 2. </p> +<!--COMMENTS:pygame.freetype.get_version--> <br> +<br></ul> + + +<a name="pygame.freetype.init"> +<big><b>pygame.freetype.init</big></b><br><ul> + <i>Initialize the underlying FreeType 2 library.</i><br> + <tt>pygame.freetype.init(default_cache_size=64): return None</tt><br> +<p>This function initializes the underlying FreeType 2 library and must be called before trying to use any of the functionality of the 'freetype' module. </p> +<p>However, if the module is available, this function will be automatically called by <tt><a href="pygame.html#pygame.init">pygame.init</a> - <font size=-1>initialize all imported pygame modules</font></tt>. It is safe to call this function more than once. </p> +<p>Optionally, you may specify a default size for the Glyph cache: this is the maximum amount of glyphs that will be cached at any given time by the module. Exceedingly small values will be automatically tuned for performance. </p> +<!--COMMENTS:pygame.freetype.init--> <br> +<br></ul> + + +<a name="pygame.freetype.quit"> +<big><b>pygame.freetype.quit</big></b><br><ul> + <i>Shuts down the underlying FreeType 2 library.</i><br> + <tt>pygame.freetype.quit(): return None</tt><br> +<p>This function de-initializes the 'freetype' module. After calling this function, you should not invoke any class, method or function related to the 'freetype' module as they are likely to fail or might give unpredictable results. It is safe to call this function even if the module hasn't been initialized yet. </p> +<!--COMMENTS:pygame.freetype.quit--> <br> +<br></ul> + + +<a name="pygame.freetype.was_init"> +<big><b>pygame.freetype.was_init</big></b><br><ul> + <i>Returns whether the the FreeType 2 library is initialized.</i><br> + <tt>pygame.freetype.quit(): return bool</tt><br> +<p>Returns whether the the FreeType 2 library is initialized. </p> +<!--COMMENTS:pygame.freetype.was_init--> <br> +<br></ul> + + +<a name="pygame.freetype.Font"> +<big><b>pygame.freetype.Font</big></b><br><ul> + <i>Creates a new Font from a supported font file.</i><br> + <tt>pygame.freetype.Font(file, style=STYLE_NONE, ptsize=-1, face_index=0): return Font</tt><br> +<ul><small><table> + <tr><td><a href="freetype.html#Font.name">Font.name</a> - <font size=-1>Gets the name of the font face.</font></td><td>Gets the name of the font face.</td></tr> + <tr><td><a href="freetype.html#Font.get_size">Font.get_size</a> - <font size=-1>Gets the size of rendered text</font></td><td>Gets the size of rendered text</td></tr> + <tr><td><a href="freetype.html#Font.get_metrics">Font.get_metrics</a> - <font size=-1>Gets glyph metrics for the font's characters</font></td><td>Gets glyph metrics for the font's characters</td></tr> + <tr><td><a href="freetype.html#Font.height">Font.height</a> - <font size=-1>Gets the height of the Font</font></td><td>Gets the height of the Font</td></tr> + <tr><td><a href="freetype.html#Font.render">Font.render</a> - <font size=-1>Renders text on a surface</font></td><td>Renders text on a surface</td></tr> + <tr><td><a href="freetype.html#Font.style">Font.style</a> - <font size=-1>Gets or sets the font's style</font></td><td>Gets or sets the font's style</td></tr> + <tr><td><a href="freetype.html#Font.underline">Font.underline</a> - <font size=-1>Gets or sets the font's underline style</font></td><td>Gets or sets the font's underline style</td></tr> + <tr><td><a href="freetype.html#Font.bold">Font.bold</a> - <font size=-1>Gets or sets the font's bold style</font></td><td>Gets or sets the font's bold style</td></tr> + <tr><td><a href="freetype.html#Font.italic">Font.italic</a> - <font size=-1>Gets or sets the font's italic style</font></td><td>Gets or sets the font's italic style</td></tr> + <tr><td><a href="freetype.html#Font.fixed_width">Font.fixed_width</a> - <font size=-1>Gets whether the font is fixed-width</font></td><td>Gets whether the font is fixed-width</td></tr> + <tr><td><a href="freetype.html#Font.antialiased">Font.antialiased</a> - <font size=-1>Font antialiasing mode</font></td><td>Font antialiasing mode</td></tr> + <tr><td><a href="freetype.html#Font.vertical">Font.vertical</a> - <font size=-1>Font vertical mode</font></td><td>Font vertical mode</td></tr> + <tr><td>None</td><td></td></tr> +</table></small></ul> +<p>'file' can be either a string representing the font's filename, a file-like object containing the font, or None; in this last case the default, built-in font will be used. </p> +<p>Optionally, a *ptsize* argument may be specified to set the default size in points which will be used to render the font. Such size can also be specified manually on each method call. Because of the way the caching system works, specifying a default size on the constructor doesn't imply a performance gain over manually passing the size on each function call. </p> +<p>If the font file has more than one face, the *index* argument may be specified to specify which face index to load. Defaults to 0; font loading will fail if the given index is not contained in the font. </p> +<p>The 'style' argument will set the default style (italic, underline, bold) used to draw this font. This style may be overriden on any <tt><a href="freetype.html#Font.render">Font.render</a> - <font size=-1>Renders text on a surface</font></tt> call. </p> +<!--COMMENTS:pygame.freetype.Font--> <br> + + +<a name="Font.name"> +<big><b>Font.name</big></b><br><ul> + <i>Gets the name of the font face.</i><br> + <tt>Font.name: return string</tt><br> +<p>Read only. Returns the real (long) name of the font type face, as specified on the font file. </p> +<!--COMMENTS:Font.name--> <br> +<br></ul> + + +<a name="Font.get_size"> +<big><b>Font.get_size</big></b><br><ul> + <i>Gets the size of rendered text</i><br> + <tt>Font.get_size(text, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (int, int)</tt><br> +<p>Gets the size in pixels which 'text' will occupy when rendered using this Font. The calculations will take into account the font's default style <tt>(e.g</tt>. underlined fonts take extra height for the underline), or the style may be overridden by the 'style' parameter. </p> +<p>Returns a tuple containing the width and height of the text's bounding box. </p> +<p>The calculations are done using the font's default size in points, without any rotation, and taking into account fonts which are set to be drawn vertically via the <tt>Font.vertical</tt> attribute. Optionally you may specify another point size to use via the 'ptsize' argument, or a text rotation via the 'rotation' argument. </p> +<!--COMMENTS:Font.get_size--> <br> +<br></ul> + + +<a name="Font.get_metrics"> +<big><b>Font.get_metrics</big></b><br><ul> + <i>Gets glyph metrics for the font's characters</i><br> + <tt>Font.get_metrics(text, bbmode=BBOX_PIXEL_GRIDFIT, ptsize=default): return [(...), ...]</tt><br> +<p>Returns the glyph metrics for each character in 'text'. </p> +<p>The glyph metrics are returned inside a list; each character will be represented as a tuple inside the list with the following values: </p> +<pre> (min_x, max_x, min_y, max_y, horizontal_advance) +</pre><p>By default, these values are returned as grid-fitted pixel coordinates (ints) but one of the following constants may be passed as the bbmode argument to change this: </p> +<pre> BBOX_EXACT: Return accurate floating point values. + BBOX_EXACT_GRIDFIT: Return accurate floating point values aligned + to the drawing grid. + BBOX_PIXEL: Return pixel coordinates (ints). + BBOX_PIXEL_GRIDFIT (default): Return grid-aligned pixel coordinates. +</pre><p>The calculations are done using the font's default size in points. Optionally you may specify another point size to use. </p> +<!--COMMENTS:Font.get_metrics--> <br> +<br></ul> + + +<a name="Font.height"> +<big><b>Font.height</big></b><br><ul> + <i>Gets the height of the Font</i><br> + <tt>Font.height: return int</tt><br> +<p>Read only. Gets the height of the Font. This is the average value of all glyphs in the font. </p> +<!--COMMENTS:Font.height--> <br> +<br></ul> + + +<a name="Font.render"> +<big><b>Font.render</big></b><br><ul> + <i>Renders text on a surface</i><br> + <tt>Font.render(dest, text, fgcolor, bgcolor=None, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (Surface, int, int)</tt><br> +<p>Renders the string 'text' to a <tt>pygame.Surface</tt>, using the color 'fgcolor'. </p> +<p>The 'dest' parameter is supposed to be a tuple containing the surface and the coordinates at which the text will be rendered, in that order. </p> +<p>If such tuple exists, and the destination surface is a valid <tt>pygame.Surface</tt> (independently of its bit depth), the text will be rendered directly on top of it at the passed coordinates, using the given 'fgcolor', and painting the background of the text with the given 'bgcolor', if available. The alpha values for both colors are always taken into account. The width and height of the rendered text will be returned in a tuple. </p> +<p>If 'None' is passed instead of the destination tuple, a new 32 bit <tt>pygame.Surface</tt> will be created with the required size to contain the drawn text, and using *bgcolor* as its background color. If a background color is not available, the surface will be filled with zero alpha opacity. The width and height of the rendered text, together with the new <tt>:class:`pygame2.sdl.video.Surface`</tt>, will be returned in a tuple. </p> +<p>The rendering is done using the font's default size in points and its default style, without any rotation, and taking into account fonts which are set to be drawn vertically via the <tt>Font.vertical</tt> attribute. Optionally you may specify another point size to use via the 'ptsize' argument, a text rotation via the 'rotation' argument, or a new text style via the 'style' argument. </p> +<!--COMMENTS:Font.render--> <br> +<br></ul> + + +<a name="Font.style"> +<big><b>Font.style</big></b><br><ul> + <i>Gets or sets the font's style</i><br> + <tt>Font.style: return int</tt><br> +<p>Gets or sets the default style of the Font. This default style will be used for all text rendering and size calculations unless overriden specifically in the `render()` or `get_size()` calls. The style value may be a bitwise <tt>OR</tt> of one or more of the following constants: </p> +<pre> STYLE_NONE + STYLE_UNDERLINE + STYLE_ITALIC + STYLE_BOLD +</pre><p>These constants may be found on the FreeType constants module. Optionally, the default style can be modified or obtained accessing the individual style attributes (underline, italic, bold). </p> +<!--COMMENTS:Font.style--> <br> +<br></ul> + + +<a name="Font.underline"> +<big><b>Font.underline</big></b><br><ul> + <i>Gets or sets the font's underline style</i><br> + <tt>Font.underline: return bool</tt><br> +<p>Gets or sets whether the font will be underlined when drawing text. This default style value will be used for all text rendering and size calculations unless overriden specifically in the `render()` or `get_size()` calls, via the 'style' parameter. </p> +<!--COMMENTS:Font.underline--> <br> +<br></ul> + + +<a name="Font.bold"> +<big><b>Font.bold</big></b><br><ul> + <i>Gets or sets the font's bold style</i><br> + <tt>Font.bold: return bool</tt><br> +<p>Gets or sets whether the font will be bold when drawing text. This default style value will be used for all text rendering and size calculations unless overriden specifically in the `render()` or `get_size()` calls, via the 'style' parameter. </p> +<!--COMMENTS:Font.bold--> <br> +<br></ul> + + +<a name="Font.italic"> +<big><b>Font.italic</big></b><br><ul> + <i>Gets or sets the font's italic style</i><br> + <tt>Font.italic: return bool</tt><br> +<p>Gets or sets whether the font will be in italics when drawing text. This default style value will be used for all text rendering and size calculations unless overriden specifically in the `render()` or `get_size()` calls, via the 'style' parameter. </p> +<!--COMMENTS:Font.italic--> <br> +<br></ul> + + +<a name="Font.fixed_width"> +<big><b>Font.fixed_width</big></b><br><ul> + <i>Gets whether the font is fixed-width</i><br> + <tt>Font.fixed_width: return bool</tt><br> +<p>Read only. Returns whether this Font is a fixed-width (bitmap) font. </p> +<p>Note that scalable fonts whose glyphs are all the same width <tt>(i.e</tt>. monospace <tt>TTF</tt> fonts used for programming) are not considered fixed width. </p> +<!--COMMENTS:Font.fixed_width--> <br> +<br></ul> + + +<a name="Font.antialiased"> +<big><b>Font.antialiased</big></b><br><ul> + <i>Font antialiasing mode</i><br> + <tt>Font.antialiased: return bool</tt><br> +<p>Gets or sets the font's antialiasing mode. This defaults to True on all fonts, which will be rendered by default antialiased. </p> +<p>Setting this to true will change all rendering methods to use glyph bitmaps without antialiasing, which supposes a small speed gain and a significant memory gain because of the way glyphs are cached. </p> +<!--COMMENTS:Font.antialiased--> <br> +<br></ul> + + +<a name="Font.vertical"> +<big><b>Font.vertical</big></b><br><ul> + <i>Font vertical mode</i><br> + <tt>Font.vertical: return bool</tt><br> +<p>Gets or sets whether the font is a vertical font such as fonts representing Kanji glyphs or other styles of vertical writing. </p> +<p>Changing this attribute will cause the font to be rendering vertically, and affects all other methods which manage glyphs or text layouts to use vertical metrics accordingly. </p> +<p>Note that the FreeType library doesn't automatically detect whether a font contains glyphs which are always supposed to be drawn vertically, so this attribute must be set manually by the user. </p> +<p>Also note that several font formats (specially bitmap based ones) don't contain the necessary metrics to draw glyphs vertically, so drawing in those cases will give unspecified results. </p> +<!--COMMENTS:Font.vertical--> <br> +<br></ul> + + +<a name=""> +<big><b></big></b><br><ul> + <br> +<!--COMMENTS:--> <br> +<br></ul> +<br></ul> +<br></ul> + +</body></html>
--- a/docs/ref/gfxdraw.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/gfxdraw.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/image.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/image.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/index.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/index.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> || @@ -299,7 +300,7 @@ <li><a href="font.html#Font.get_linesize">Font.get_linesize</a> - <font size=-1>get the line space of the font text</font></li> <li><a href="font.html#Font.get_underline">Font.get_underline</a> - <font size=-1>check if text will be rendered with an underline</font></li> <li><a href="font.html#Font.metrics">Font.metrics</a> - <font size=-1>Gets the metrics for each character in the pased string.</font></li> -<li><a href="font.html#Font.render">Font.render</a> - <font size=-1>draw text on a new Surface</font></li> +<li><a href="freetype.html#Font.render">Font.render</a> - <font size=-1>Renders text on a surface</font></li> <li><a href="font.html#Font.set_bold">Font.set_bold</a> - <font size=-1>enable fake rendering of bold text</font></li> <li><a href="font.html#Font.set_italic">Font.set_italic</a> - <font size=-1>enable fake rendering of italic text</font></li> <li><a href="font.html#Font.set_underline">Font.set_underline</a> - <font size=-1>control if text is rendered with an underline</font></li> @@ -313,6 +314,30 @@ <li><a href="font.html#pygame.font.match_font">pygame.font.match_font</a> - <font size=-1>find a specific font on the system</font></li> <li><a href="font.html#pygame.font.quit">pygame.font.quit</a> - <font size=-1>uninitialize the font module</font></li> </ul> +<li><a href="freetype.html#pygame.freetype">pygame.freetype</a> - <font size=-1>Enhanced Pygame module for loading and rendering fonts</font></li> +<ul> +<li><a href="freetype.html#pygame.freetype.Font">pygame.freetype.Font</a> - <font size=-1>Creates a new Font from a supported font file.</font></li> +<ul> +<li></li> +<li><a href="freetype.html#Font.antialiased">Font.antialiased</a> - <font size=-1>Font antialiasing mode</font></li> +<li><a href="freetype.html#Font.bold">Font.bold</a> - <font size=-1>Gets or sets the font's bold style</font></li> +<li><a href="freetype.html#Font.fixed_width">Font.fixed_width</a> - <font size=-1>Gets whether the font is fixed-width</font></li> +<li><a href="freetype.html#Font.get_metrics">Font.get_metrics</a> - <font size=-1>Gets glyph metrics for the font's characters</font></li> +<li><a href="freetype.html#Font.get_size">Font.get_size</a> - <font size=-1>Gets the size of rendered text</font></li> +<li><a href="freetype.html#Font.height">Font.height</a> - <font size=-1>Gets the height of the Font</font></li> +<li><a href="freetype.html#Font.italic">Font.italic</a> - <font size=-1>Gets or sets the font's italic style</font></li> +<li><a href="freetype.html#Font.name">Font.name</a> - <font size=-1>Gets the name of the font face.</font></li> +<li><a href="freetype.html#Font.render">Font.render</a> - <font size=-1>Renders text on a surface</font></li> +<li><a href="freetype.html#Font.style">Font.style</a> - <font size=-1>Gets or sets the font's style</font></li> +<li><a href="freetype.html#Font.underline">Font.underline</a> - <font size=-1>Gets or sets the font's underline style</font></li> +<li><a href="freetype.html#Font.vertical">Font.vertical</a> - <font size=-1>Font vertical mode</font></li> +</ul> +<li><a href="freetype.html#pygame.freetype.get_error">pygame.freetype.get_error</a> - <font size=-1>Get the latest error</font></li> +<li><a href="freetype.html#pygame.freetype.get_version">pygame.freetype.get_version</a> - <font size=-1>Get the FreeType version</font></li> +<li><a href="freetype.html#pygame.freetype.init">pygame.freetype.init</a> - <font size=-1>Initialize the underlying FreeType 2 library.</font></li> +<li><a href="freetype.html#pygame.freetype.quit">pygame.freetype.quit</a> - <font size=-1>Shuts down the underlying FreeType 2 library.</font></li> +<li><a href="freetype.html#pygame.freetype.was_init">pygame.freetype.was_init</a> - <font size=-1>Returns whether the the FreeType 2 library is initialized.</font></li> +</ul> <li><a href="pygame.html#pygame.get_error">pygame.get_error</a> - <font size=-1>get the current error message</font></li> <li><a href="pygame.html#pygame.get_sdl_byteorder">pygame.get_sdl_byteorder</a> - <font size=-1>get the byte order of SDL</font></li> <li><a href="pygame.html#pygame.get_sdl_version">pygame.get_sdl_version</a> - <font size=-1>get the version number of SDL</font></li>
--- a/docs/ref/joystick.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/joystick.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/key.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/key.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/locals.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/locals.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/mask.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/mask.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/midi.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/midi.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/mixer.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/mixer.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/mouse.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/mouse.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/movie.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/movie.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/music.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/music.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/overlay.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/overlay.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/pixelarray.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/pixelarray.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/pygame.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/pygame.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/rect.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/rect.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> || @@ -106,6 +107,7 @@ <i>copy the rectangle</i><br> <tt>Rect.copy(): return Rect</tt><br> <p>Returns a new rectangle having the same position and size as the orginal. </p> +<p>New in pygame <tt>1.9</tt> </p> <!--COMMENTS:Rect.copy--> <br> <br></ul>
--- a/docs/ref/scrap.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/scrap.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/sndarray.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/sndarray.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/sprite.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/sprite.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/surface.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/surface.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> || @@ -186,6 +187,7 @@ <i>Shift the surface image in place</i><br> <tt>Surface.scroll(dx=0, dy=0): return None</tt><br> <p>Move the image by dx pixels right and dy pixels down. dx and dy may be negative for left and up scrolls respectively. Areas of the surface that are not overwritten retain their original pixel values. Scrolling is contained by the Surface clip area. It is safe to have dx and dy values that exceed the surface size. </p> +<p>New in Pygame <tt>1.9</tt> </p> <!--COMMENTS:Surface.scroll--> <br> <br></ul>
--- a/docs/ref/surfarray.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/surfarray.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/tests.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/tests.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/time.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/time.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- a/docs/ref/transform.html Mon Nov 16 18:05:30 2009 +0000 +++ b/docs/ref/transform.html Mon Nov 16 18:31:40 2009 +0000 @@ -23,6 +23,7 @@ <a href="event.html">Event</a> || <a href="examples.html">Examples</a> || <a href="font.html">Font</a> || +<a href="freetype.html">Freetype</a> || <a href="gfxdraw.html">Gfxdraw</a> || <a href="image.html">Image</a> || <a href="joystick.html">Joystick</a> ||
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/__movie_test.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,216 @@ +import time +import pygame +pygame.init() #or we could just call pygame.display.init() as thats all we need +pygame.mixer.quit() #This needs to be done, as the default sound system of the + # ffmpeg-wrapper uses SDL_mixer, and this would cause major + # conflicts with the mixer module. +import pygame._movie as movie + +print "Please give an (absolute)filename of a movie file you'd like to play: ", +#filename = raw_input() +filename="/home/tyler/War3.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. +# Without a surface argument, the ffmpeg-wrapper uses the sdl_overlay library. +#screen=pygame.display.set_mode((640, 368)) + +info = movie.MovieInfo(filename) +print +print info.width, info.height +print info.filename +print info.aspect_ratio +print info.duration +print info.audio_codec +print info.video_codec + +try: + #this is to test that the movie module tests filenames to make sure they exist + m=movie.Movie("gsdsjgsdj") +except Exception, e: + print e + del m + + +m = movie.Movie(filename) +print m.paused #always False, unless .pause has been called +print m.playing #False until play has been called. Will return to false when +print m.finished# .stop() has been called. + +print m.width #default size values of the video file +print m.height # They can be modified on the fly, as will be demonstrated. + +print m #calls __repr__, which will show the filename, and the current + # timestamp. +#print "repeated looping plays.."# +#m.play(9) +#time.sleep(9*130) + +surf = pygame.surface.Surface((100, 100)) +#this should cause an error: +try: + m.surface = surf +except Exception, e: + print e + del e + +print "Playing infinitely" + +m.play(-1) #We're going to use infinite play, so we can demonstrate all + # the features. +time.sleep(2) #sleep for ten seconds to let one see the video play, and hear + # the audio +##print "Paused:",m.paused +##print "Playing:",m.playing +##print "Movie:",m +##print "Y Top:",m.ytop +##print "X Left:",m.xleft +time.sleep(10) +print "Testing seek..." +m.easy_seek(10, 1, 0, 0) +time.sleep(5) +m.easy_seek(10, 0, 0, 0) +time.sleep(1) +m.pause() +time.sleep(5) +m.pause() +time.sleep(10) + +print "Altering xleft and ytop..." +m.shift(10, 10) +time.sleep(10) +m.shift(0, 0) +#Now we're going to play with the size of the window, affecting the video on +#the fly. resize(width, height) is the main function, changes them both at +# the same time. +print "Resizing..." +m.resize(m.width/2, m.height*2) +print "sleeping..." +time.sleep(10) #another ten second nap. +print "Resizing again..." +m.width = m.width*4 +print "sleeping again" +time.sleep(10) +print "Back to normal!" +m.resize(m.width/2, m.height/2) +print "and again, sleeping..." +#back to our original size +time.sleep(10) + + +#Here we demonstrate the use of pause. You pause, then call pause again to play +print "Pausing..." +m.pause() +print "done pausing..." +print m.paused +print m.playing +time.sleep(10) +print "Unpausing..." +m.pause() +print m.paused +print m.playing +time.sleep(10) +#Here is the stop function. Right now, rewind is the exact same as stop. +print "Stopping..., sleeping for 3 seconds" +m.stop() +time.sleep(5) +#And now we restart playing. +del m +print "Playing again..." +m=movie.Movie(filename) +m.play(-1) +print "done restart play..." +time.sleep(10) +import sys +#sys.exit() +print "Surface time..." +m.stop() +time.sleep(5) + +del m + +screen = pygame.display.set_mode((info.width, info.height)) +##m.surface=screen +##time.sleep(1) +###This will move the movie player from overlay mode to blitting to the surface +### we've given it. This means it is our responsibility to update the display on +### time. +###while not m.finished: +### time.sleep(0.1) +### pygame.display.update() +##m.stop() +##time.sleep(5) +##del m + + +m=movie.Movie(filename, screen) +counter = 0 +actions = {1: lambda x: x.paused, 6: lambda x:x.pause(), 11: lambda x:x.pause(), 2000:lambda x: x.stop(), 3000: lambda x: x.play(-1)} +m.play(0) +prev_time = time.time() +#m.resize(m.width*2, m.height*2) +#m.surface = screen +print "About to do surface gymnastics..." +##while not m.finished: +## time.sleep(0.1) +## pygame.display.update() +##time.sleep(1000) +while(1): + new_time=time.time() + diff = int(new_time-prev_time) + if(diff>=1): + counter+=1 + print counter + prev_time=new_time + #print "testing counter" + if counter==3100: + #print "breaking" + break + #print "has_key" + if actions.has_key(counter): + print "Performing action at counter value: %d" % counter + actions[counter](m) + counter +=1 + #print "updating" + time.sleep(0.1) #we need to let go of the gil occassionally... + if(not screen.get_locked()): + try: + pygame.display.update() #we can do this because we're blitting each frame of the movie to the main screen we instantiated. + except pygame.error: + break + +print "Ending trial one..." +m.stop() +del m +#the end + +m=movie.Movie(filename, screen) +prev_time = time.time() +print "About to do surface gymnastics..." +counter = 0 +while(1): + new_time=time.time() + diff = int(new_time-prev_time) + if(diff>=1): + counter+=1 + print counter + prev_time=new_time + #print "testing counter" + if counter==30: + print "breaking" + break + #print "has_key" + if actions.has_key(counter): + print "Performing action at counter value: %d" % counter + actions[counter](m) + counter +=1 + #print "updating" + time.sleep(0.1) #we need to let go of the gil occassionally... + if(not screen.get_locked()): + try: + pygame.display.update() #we can do this because we're blitting each frame of the movie to the main screen we instantiated. + except pygame.error: + break + +del m +print "the end"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/freetype_misc.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,68 @@ +import sys, os +import pygame +from pygame.locals import * + +try: + import pygame.freetype as freetype +except ImportError: + print ("No FreeType support compiled") + sys.exit () + +colors = { + "grey_light" : pygame.Color(200, 200, 200), + "grey_dark" : pygame.Color(100, 100, 100), + "green" : pygame.Color(50, 255, 63), + "red" : pygame.Color(220, 30, 30), + "blue" : pygame.Color(50, 75, 245) +} + +def run(): + pygame.init() + + fontdir = os.path.dirname(os.path.abspath (__file__)) + font = freetype.Font(os.path.join (fontdir, "sans.ttf")) + + screen = pygame.display.set_mode((800, 600)) + screen.fill (colors["grey_light"]) + + font.render((screen, 32, 32), "Hello World", colors["red"], colors['grey_dark'], + ptsize=64, style=freetype.STYLE_UNDERLINE|freetype.STYLE_ITALIC) + + font.render((screen, 32, 128), "abcdefghijklm", colors["grey_dark"], colors["green"], + ptsize=64) + + font.vertical = True + font.render((screen, 32, 190), "Vertical?", colors["blue"], None, ptsize=32) + font.vertical = False + + font.render((screen, 64, 190), "Let's spin!", colors["red"], None, + ptsize=48, rotation=55) + + font.render((screen, 150, 270), "All around!", colors["green"], None, + ptsize=48, rotation=-55) + + font.render((screen, 250, 220), "and BLEND", pygame.Color(255, 0, 0, 128), None, + ptsize=64) + + font.render((screen, 258, 237), "or BLAND!", pygame.Color(0, 0xCC, 28, 128), None, + ptsize=64) + + font.render((screen, 298, 320), "I \u2665 Unicode", pygame.Color(0, 0xCC, 0xDD), None, + ptsize=64) + + font.render((screen, 480, 32), "\u2665", colors["grey_light"], colors["red"], + ptsize=148) + + font.render((screen, 380, 380), "...yes, this is a SDL surface", pygame.Color(0, 0, 0), None, + ptsize=24, style=freetype.STYLE_BOLD) + + pygame.display.flip() + + while 1: + if pygame.event.wait().type in (QUIT, KEYDOWN, MOUSEBUTTONDOWN): + break + + pygame.quit() + +if __name__ == "__main__": + run ()
--- a/lib/_camera_opencv_highgui.py Mon Nov 16 18:05:30 2009 +0000 +++ b/lib/_camera_opencv_highgui.py Mon Nov 16 18:31:40 2009 +0000 @@ -23,7 +23,7 @@ class Camera: - def __init__(self, device =0, size = (640,480), mode = "RGB"): + def __init__(self, device = 0, size = (640,480), mode = "RGB"): """ """ self.camera = highgui.cvCreateCameraCapture(device)
--- a/lib/_camera_vidcapture.py Mon Nov 16 18:05:30 2009 +0000 +++ b/lib/_camera_vidcapture.py Mon Nov 16 18:31:40 2009 +0000 @@ -18,9 +18,14 @@ def init(): global vidcap - import vidcap as vc vidcap = vc + try: + import vidcap as vc + except ImportError: + from VideoCapture import vidcap as vc + + def quit(): global vidcap pass
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/_dummybackend.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,30 @@ +"""dummy Movie class if all else fails """ +class Movie: + def __init__(self, filename, surface=None): + self.filename=filename + self.surface = surface + self.process = None + self.loops=0 + self.playing = False + self.paused = False + self._backend = "DUMMY" + self.width=0 + self.height=0 + self.finished = 1 + def play(self, loops=0): + self.playing= not self.playing + + def stop(self): + self.playing=not self.playing + self.paused =not self.paused + + def pause(self): + self.paused=not self.paused + + def resize(self, w, h): + self.width=w + self.height=h + + def __repr__(self): + return "(%s 0.0s)"%self.filename + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/_vlcbackend.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,194 @@ +import subprocess, os, time, socket, select +import threading +import re + +import sys +if('win' in sys.platform): + player="vlc.exe" +else: + player= "vlc" +remote= "-I rc" +port = 10000 +hostname = socket.getaddrinfo('localhost', 10000)[0][4][0] +extra = "--rc-host %s:%d" + +class Communicator: + def __init__(self, player, remote, extra, port, hostname): + self.socket = socket.socket() + #print (hostname, port) + while 1: + try: + self.socket.connect((hostname, port)) + break + except socket.error: + port+=1 + self.commands = ' '.join([player, remote, extra%(hostname, port)]) + print self.commands + self.patterns = { + 'size' : re.compile("Resolution: \d{1,4}x\d{1,4}"), + 'width' : re.compile("Resolution: \d{1,4}(?=\d{1,4})"), + 'height': re.compile("Resolution: (?<=\dx)\d{1,4}|(?<=\d\dx)\d{1,4}|(?<=\d\d\dx)\d{1,4}|(?<=\d\d\d\dx)\d{1,4}"), + } + def send(self, message): + self.socket.send(message) + + def add(self, filename): + self.send("add %s\n" % filename) + + def enqueue(self, filename): + self.send("enqueue %s\n" % filename) + + def pause(self): + self.send("pause\n") + + def stop(self): + self.send("stop\n") + + def logout(self): + self.send("logout\n") + + def info(self): + self.send("info\n") + d=[] + read =[0] + while(len(read)>0): + read, write, exce = select.select([self.socket], [], [], 0.10) + if(len(read)>0): + d.append(self.socket.recv(1)) + d=''.join(d) + return d + + def _get_time(self): + self.send("get_time\n") + d=[] + read =[0] + while(len(read)>0): + read, write, exce = select.select([self.socket], [], [], 0.10) + if(len(read)>0): + d.append(self.socket.recv(1)) + d=''.join(d) + d=int(d)#transforms into an int + return d + + def _get_height(self): + d=self.info() + p = self.patterns['height'] + m =p.search(d) + if not m: + return 0 + return int(m.group()) + + def _get_width(self): + d=self.info() + p= self.patterns['width'] + m=p.search(d) + if not m: + return 0 + return int(m.group()) + +class Movie(object): + """pygame._vlcbackend.Movie: + plays a video file via subprocess and the available vlc executable + """ + def __init__(self, filename, surface=None): + self.filename=filename + self._surface = surface + self.process = None + self.loops=0 + self.playing = False + self.paused = False + self._backend = "VLC" + self.comm = Communicator(player, remote, extra, port, hostname) + self.width = 0 + self.height =0 + self.finished =0 + def getSurface(self): + #special stuff here + return self._surface + + def setSurface(self, value): + #special stuff here, like redirecting movie output here + self._surface = value + def delSurface(self): + del self._surface + surface=property(fget=getSurface, fset=setSurface, fdel=delSurface) + + + + def play(self, loops=0): + self.loops=loops + if loops<=-1: self.eternity=1 + else: self.eternity=0 + self.loops -= 1 + if not self.process: + self._play() + #otherwise stop playback, and start again with the new loops value. + else: + self.stop() + self._play() + def _play(self): + comm = self.comm.commands + self.process=subprocess.Popen(comm, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self.playing = not self.playing + self.width = self.comm._get_width() + self.height = self.comm._get_height() + if(self.eternity): + #well, we need to watch vlc, see when it finishes playing, then play the video again, over and over + self.comm.add(self.filename) + self.t=MovieWatcher(self.comm, 0.1 , self.eternity, self.filename) + return + #otherwise, we add loops+1 copies of the video to the playlist + self.comm.add(self.filename) + for i in range(1, self.loops+1): + self.comm.enqueue(self.filename) + + + def pause(self): + if self.process: + #send value to pause playback + self.paused = not self.paused + self.comm.pause() + + def stop(self): + if self.process: + #we kill the process... + self.paused = not self.paused + self.playing= not self.playing + self.comm.stop() + self.commd.logout() + self.process.terminate() + self.process=None + self.finished = 1 + + def __repr__(self): + if self.process: + return "(%s: %ds)" % (self.filename, self._get_time()) #add on timestamp + else: + return "(%s: 0.0s)" % self.filename + + def _get_time(self): + if self.process: + return self.comm._get_time() + + + +class MovieWatcher(threading.Thread): + def __init__(self, comm, time, eternity, filename): + threading.Thread.__init__(self) + self.comm=comm + self.time = time + self.eternity = eternity + self.filename = filename + def run(): + while(1): + time.sleep(self.time) + read, write, exce = select.select([self.comm.socket], [], [], 0.1) + d=[] + while(len(read)>0): + d.append(self.comm.socket.recv(1)) + read, write, exce = select.select([self.comm.socket], [], [], 0.1) + s = ''.join(d) + if("status change: ( stop state: 0 )" in s): + if("nothing to play" in s): + self.comm.add(self.filename) + \ No newline at end of file
--- a/lib/camera.py Mon Nov 16 18:05:30 2009 +0000 +++ b/lib/camera.py Mon Nov 16 18:31:40 2009 +0000 @@ -19,7 +19,8 @@ elif "linux" in sys.platform: use__camera = True - + elif "darwin" in sys.platform: + use__camera = True else: use_opencv = True
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/nmovie.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,32 @@ +"""Main newmovie module, imports first from _movie.so, then _vlcbackend if it finds the vlc executable.""" + +try: + from pygame._movie import Movie +except ImportError: + #try to transparently load the _vlcbackend.py Movie object. + import os, os.path, sys + path=os.path + if('win' in sys.platform): + if(os.path.exists(path.join(path.join(path.join('C:', 'Program Files'), 'VideoLan'), 'VLC'))): + try: + from pygame._vlcbackend import Movie, MovieWatcher + except ImportError: + #you're really hooped now... + print "Unable to find a working movie backend. Loading the dummy movie class..." + from pygame._dummybackend import Movie + else: + print "Unable to find a working movie backend. Loading the dummy movie class..." + from pygame._dummybackend import Movie + else: + #POSIX + if(os.path.exists(path.join(path.join(path.join(os.sep, 'usr'), 'bin'), 'vlc'))): + try: + from pygame._vlcbackend import Movie, MovieWatcher + except ImportError: + #oh man, I didn't mean for this to happen so badly... + print "Unable to find a working movie backend. Loading the dummy movie class..." + from pygame._dummybackend import Movie + else: + print "Unable to find a working movie backend. Loading the dummy movie class..." + from pygame._dummybackend import Movie +
--- a/lib/version.py Mon Nov 16 18:05:30 2009 +0000 +++ b/lib/version.py Mon Nov 16 18:31:40 2009 +0000 @@ -27,5 +27,5 @@ releases. (hmm, until we get to versions > 10) """ -ver = '1.9.0rc3' -vernum = 1,9,0 +ver = '1.9.2pre' +vernum = 1,9,2
--- a/makeref.py Mon Nov 16 18:05:30 2009 +0000 +++ b/makeref.py Mon Nov 16 18:31:40 2009 +0000 @@ -87,20 +87,14 @@ HtmlOut(doc, index, outFile) outFile.write(HTMLFinish) outFile.close() - - outFile = open(os.path.join("src", "pygamedocs.h"), "w") - outFile.write("/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */\n") - for doc in justDocs: + + for name, doc in docs: + outFile = open(os.path.join("src", "doc", "%s_doc.h") % name, "w") + outFile.write("/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */\n") WriteDocHeader(outFile, doc, options.have_code_docs) - - - outFile.write("\n\n/* Docs in a comments... slightly easier to read. */\n\n\n/*") - # add the docs as comments to the header file. - for doc in justDocs: + outFile.write("\n\n/* Docs in a comments... slightly easier to read. */\n\n\n/*") WriteDocHeaderComments(outFile, doc) - - outFile.write("\n\n*/\n\n") - + outFile.write("\n\n*/\n\n") topDoc = LayoutDocs(justDocs) @@ -119,7 +113,7 @@ f.write('\n\n<a name="%s">\n' % doc.fullname) f.write("<big><b>%s</big></b><br><ul>\n" % doc.fullname) if doc.descr: - f.write(" <i>%s</i><br>\n" % doc.descr) + f.write(" <i>%s</i><br>\n" % doc.descr) if doc.protos: for p in doc.protos: f.write(" <tt>%s</tt><br>\n" % p)
--- a/msys_build_deps.py Mon Nov 16 18:05:30 2009 +0000 +++ b/msys_build_deps.py Mon Nov 16 18:31:40 2009 +0000 @@ -50,7 +50,7 @@ mingwrt-3.15.1 win32api-3.12 mingw32-make-3.81-20080326 -MSYS-1.0.10 +MSYS-1.0.11 msysDTK-1.0.1 msys-automake-1.8.2 msys-autocont-2.59 @@ -945,6 +945,8 @@ IHDR := -I$(pmcom) -I$(pmwin) -I$(pt) LIBS := $(LOADLIBES) $(LDLIBS) -lwinmm + + all : $(pmdll) .PHONY : all @@ -952,12 +954,12 @@ \tsed 's_#define DEBUG.*$$_/*&*/_' < "$<" > "$@" $(pmlib) : $(src) $(hdr) -\t$(CC) $(CPPFLAGS) $(IHDR) -c $(CFLAGS) $(src) +\tc++ $(CPPFLAGS) $(IHDR) -c $(CFLAGS) $(src) \tar rc $(pmlib) $(obj) \tranlib $(pmlib) $(pmdll) : $(pmlib) $(def) -\t$(CC) -shared $(LDFLAGS) -def $(def) $(pmlib) $(LIBS) -o $@ +\tc++ -shared $(LDFLAGS) -def $(def) $(pmlib) $(LIBS) -o $@ \tdlltool -D $(pmdll) -d $(def) -l $(pmimplib) \tranlib $(pmimplib) @@ -1052,7 +1054,43 @@ rm -f GNUmakefile portmidi.def fi """), - ] # End dependencies = [. + Dependency('FFMPEG', ['ffmpeg'], + ['avformat-52.dll', 'swscale-0.dll', 'SDL_mixer.dll'], """ + +set -e +cd $BDWD + +if [ x$BDCONF == x1 ]; then + ./configure --enable-shared --enable-memalign-hack +fi + +if [ x$BDCOMP == x1 ]; then + make +fi + +if [ x$BDINST == x1 ]; then + make install +fi + +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/SDL_ttf.dll +fi + +if [ x$BDINST == x1 ]; then + cd libswscale/ + make + make install + cd .. +fi + +if [ x$BDCLEAN == x1 ]; then + set +e + make clean +fi +"""), + + + ] # End dependencies = [. msys_prep = Preparation('/usr/local', """
--- a/prebuilt-template/Setup_Win.in Mon Nov 16 18:05:30 2009 +0000 +++ b/prebuilt-template/Setup_Win.in Mon Nov 16 18:31:40 2009 +0000 @@ -14,6 +14,8 @@ OGG = -Iprebuilt/include/ogg -logg PORTMIDI = -lportmidi PORTTIME = +AVFORMAT = -Iprebuilt/include -lavformat -lavcodec -lavutil -lws2_32 +SWSCALE = -Iprebuilt/include -lswscale -lavutil COPYLIB_SDL -Lprebuilt/lib/SDL.dll COPYLIB_SDL_ttf -lSDL -lfreetype -Lprebuilt/lib/SDL_ttf.dll COPYLIB_SDL_image -lSDL -ljpef -lpng -ltiff -Lprebuilt/lib/SDL_image.dll @@ -28,4 +30,8 @@ COPYLIB_vorbis -logg -Lprebuilt/lib/libvorbis-0.dll COPYLIB_ogg -Lprebuilt/lib/libogg-0.dll COPYLIB_portmidi -Lprebuilt/lib/portmidi.dll +COPYLIB_avformat -lavcodec -lavutil -Lprebuilt/lib/avformat-52.dll +COPYLIB_swscale -lavutil -Lprebuilt/lib/swscale-0.dll +COPYLIB_avcodec -lavutil -Lprebuilt/lib/avcodec-52.dll +COPYLIB_avutil -Lprebuilt/lib/avutil-50.dll
--- a/readme.html Mon Nov 16 18:05:30 2009 +0000 +++ b/readme.html Mon Nov 16 18:31:40 2009 +0000 @@ -6,7 +6,7 @@ <font size=+5><b>Pygame Readme</b></font> </td></tr><tr><td align=left width=33%><big> -Version 1.9.0rc3 +Version 1.9.2pre </td><td align=center width=34%><big> @@ -141,20 +141,9 @@ -<p><big><b><u>Todo / Ideas</u></b></big> (feel free to submit)<br><ul> -<li>transform.skew() function</li> -<li>transform.scroll() function</li> -<li>image filtering (colors,blurs,etc)</li> -<li>quake-like console with python interpreter</li> -<li>game lobby. client, simple server, and protocol</li> -<li>surfarrays should be able to do RGBA along with RGB</li> -<li>draw with transparancy</li> -<li>draw large sets of primitives with a single call</li> -<li>drawing offsets, perhaps as subsurfaces</li> -<li>new scale2x, scale3x, and scale4x from hiend3d</li> -<li>switch Numeric to numarray (see docs on how to do both)</li> -<li>audio resampling</li> -</ul></p><br> +<p><big><b><u>Todo / Ideas</u></b></big> (feel free to submit)<br> +<a href="http://www.pygame.org/wiki/todo/">http://www.pygame.org/wiki/todo/</a> +</p><br>
--- a/readme.txt Mon Nov 16 18:05:30 2009 +0000 +++ b/readme.txt Mon Nov 16 18:31:40 2009 +0000 @@ -1,6 +1,6 @@ Pygame Readme - Version 1.9.0rc3 Python Game Development + Version 1.9.2pre Python Game Development Originally by Pete Shinners, now an open source community project. http://www.pygame.org pygame@seul.org
--- a/setup.py Mon Nov 16 18:05:30 2009 +0000 +++ b/setup.py Mon Nov 16 18:31:40 2009 +0000 @@ -14,7 +14,7 @@ METADATA = { "name": "pygame", - "version": "1.9.0rc3", + "version": "1.9.2pre", "license": "LGPL", "url": "http://www.pygame.org", "author": "Pete Shinners, Rene Dudfield, Marcus von Appen, Bob Pendleton, others...", @@ -154,6 +154,7 @@ if sys.version_info >= (3, 0, 0): python3_skip = ['scrap', '_camera', + '_movie', '_numericsurfarray', '_numericsndarray', ] @@ -187,7 +188,9 @@ ['test', [['fixtures', [['xbm_cursors', - ['*.xbm']]]]]]) + ['*.xbm']], + ['fonts', + ['*.ttf', '*.otf']]]]]]) #examples add_datafiles(data_files, 'pygame/examples', @@ -363,7 +366,9 @@ if e.sources[i].endswith('scale_mmx.c'): del e.sources[i] return - replace_scale_mmx() + # linking to 64-bit mingw generated scale_mmx.obj fails + if not '64 bit' in sys.version: + replace_scale_mmx() #clean up the list of extensions
--- a/src/SDL_gfx/SDL_gfxPrimitives.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/SDL_gfx/SDL_gfxPrimitives.c Mon Nov 16 18:31:40 2009 +0000 @@ -776,7 +776,7 @@ */ switch (dst->format->BytesPerPixel) { case 1: - memset(pixel, color, dx); + memset(pixel, color, dx+1); break; case 2: pixellast = pixel + dx + dx; @@ -3029,6 +3029,12 @@ #if defined(_WIN32) && !defined(__MINGW_H) && !defined(__SYMBIAN32__) +#ifdef _M_X64 +#include <emmintrin.h> +static __inline long lrint(float f) { + return _mm_cvtss_si32(_mm_load_ss(&f)); +} +#else __inline long int lrint (double flt) { @@ -3040,9 +3046,12 @@ }; return intgr; } +#endif #endif + + /* Based on code from Anders Lindstroem, based on code from SGE, based on code from TwinLib */ int aaellipseColor(SDL_Surface * dst, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
--- a/src/_arraysurfarray.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/_arraysurfarray.c Mon Nov 16 18:31:40 2009 +0000 @@ -23,7 +23,7 @@ #include <stddef.h> #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/surfarray_doc.h" #include "pgarrinter.h" #include <SDL_byteorder.h>
--- a/src/_camera.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/_camera.c Mon Nov 16 18:31:40 2009 +0000 @@ -35,11 +35,14 @@ #include "camera.h" -#if defined(__unix__) +/* +#if defined(__unix__) || !defined(__APPLE__) #else #define V4L2_PIX_FMT_RGB24 1 #define V4L2_PIX_FMT_RGB444 1 #endif +*/ + /* functions available to pygame users */ PyObject* surf_colorspace (PyObject* self, PyObject* arg); @@ -62,8 +65,7 @@ */ /* colorspace() - Surface colorspace conversion */ -PyObject* surf_colorspace (PyObject* self, PyObject* arg) -{ +PyObject* surf_colorspace (PyObject* self, PyObject* arg) { PyObject *surfobj, *surfobj2; SDL_Surface* surf, *newsurf; char* color; @@ -125,9 +127,8 @@ } /* list_cameras() - lists cameras available on the computer */ -PyObject* list_cameras (PyObject* self, PyObject* arg) -{ -#if defined(__unix__) +PyObject* list_cameras (PyObject* self, PyObject* arg) { +#if defined(__unix__) || defined (__APPLE__) PyObject* ret_list; PyObject* string; char** devices; @@ -138,8 +139,12 @@ ret_list = PyList_New (0); if (!ret_list) return NULL; - + + #if defined(__unix__) devices = v4l2_list_cameras(&num_devices); + # elif defined(__APPLE__) + devices = mac_list_cameras(&num_devices); + # endif for(i = 0; i < num_devices; i++) { string = PyString_FromString(devices[i]); @@ -156,8 +161,7 @@ } /* start() - opens, inits, and starts capturing on the camera */ -PyObject* camera_start (PyCameraObject* self) -{ +PyObject* camera_start (PyCameraObject* self) { #if defined(__unix__) if (v4l2_open_device(self) == 0) { if (v4l_open_device(self) == 0) { @@ -185,13 +189,17 @@ return NULL; } } +#elif defined(__APPLE__) + if (! (mac_open_device(self) == 1 && mac_init_device(self) == 1 && mac_start_capturing(self) == 1)) { + mac_close_device(self); + return NULL; + } #endif Py_RETURN_NONE; } /* stop() - stops capturing, uninits, and closes the camera */ -PyObject* camera_stop (PyCameraObject* self) -{ +PyObject* camera_stop (PyCameraObject* self) { #if defined(__unix__) if (v4l2_stop_capturing(self) == 0) return NULL; @@ -199,16 +207,20 @@ return NULL; if (v4l2_close_device(self) == 0) return NULL; +#elif defined(__APPLE__) + if (mac_stop_capturing(self) == 0) + return NULL; + if (mac_close_device(self) == 0) + return NULL; #endif Py_RETURN_NONE; } /* get_controls() - gets current values of user controls */ /* TODO: Support brightness, contrast, and other common controls */ -PyObject* camera_get_controls (PyCameraObject* self) -{ +PyObject* camera_get_controls (PyCameraObject* self) { +#if defined(__unix__) int value; -#if defined(__unix__) if (v4l2_get_control(self->fd, V4L2_CID_HFLIP, &value)) self->hflip = value; @@ -217,13 +229,17 @@ if (v4l2_get_control(self->fd, V4L2_CID_BRIGHTNESS, &value)) self->brightness = value; -#endif + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(self->brightness)); +#elif defined(__APPLE__) + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(-1)); +#endif + Py_RETURN_NONE; } /* set_controls() - changes camera settings if supported by the camera */ -PyObject* camera_set_controls (PyCameraObject* self, PyObject* arg, PyObject *kwds) -{ +PyObject* camera_set_controls (PyCameraObject* self, PyObject* arg, PyObject *kwds) { +#if defined(__unix__) int hflip = 0, vflip = 0, brightness = 0; char *kwids[] = {"hflip", "vflip", "brightness", NULL}; @@ -234,7 +250,8 @@ if (!PyArg_ParseTupleAndKeywords(arg, kwds, "|iii", kwids, &hflip, &vflip, &brightness)) return NULL; -#if defined(__unix__) + +/* #if defined(__unix__) */ if (v4l2_set_control(self->fd, V4L2_CID_HFLIP, hflip)) self->hflip = hflip; @@ -243,29 +260,51 @@ if (v4l2_set_control(self->fd, V4L2_CID_BRIGHTNESS, brightness)) self->brightness = brightness; -#endif + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(self->brightness)); -} + +#elif defined(__APPLE__) + int hflip = 0, vflip = 0, brightness = 0; + char *kwids[] = {"hflip", "vflip", "brightness", NULL}; -/* get_size() - returns the dimensions of the images being recorded */ -PyObject* camera_get_size (PyCameraObject* self) -{ - return Py_BuildValue ("(ii)", self->width, self->height); -} - -/* query_image() - checks if a frame is ready */ -PyObject* camera_query_image (PyCameraObject* self) -{ -#if defined(__unix__) - return PyBool_FromLong(v4l2_query_buffer(self)); + camera_get_controls(self); + hflip = self->hflip; + vflip = self->vflip; + brightness = -1; + + if (!PyArg_ParseTupleAndKeywords(arg, kwds, "|iii", kwids, &hflip, &vflip, &brightness)) + return NULL; + + self->hflip = hflip; + self->vflip = vflip; + + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(-1)); #endif Py_RETURN_NONE; } +/* get_size() - returns the dimensions of the images being recorded */ +PyObject* camera_get_size (PyCameraObject* self) { +#if defined(__unix__) + return Py_BuildValue ("(ii)", self->width, self->height); +#elif defined(__APPLE__) + return Py_BuildValue ("(ii)", self->boundsRect.right, self->boundsRect.bottom); +#endif + Py_RETURN_NONE; +} + +/* query_image() - checks if a frame is ready */ +PyObject* camera_query_image(PyCameraObject* self) { +#if defined(__unix__) + return PyBool_FromLong(v4l2_query_buffer(self)); +#endif + Py_RETURN_TRUE; +} + /* get_image() - returns an RGB Surface */ /* code to reuse Surface from René Dudfield */ -PyObject* camera_get_image (PyCameraObject* self, PyObject* arg) -{ +PyObject* camera_get_image (PyCameraObject* self, PyObject* arg) { +#if defined(__unix__) SDL_Surface* surf = NULL; PyObject *surfobj = NULL; @@ -286,12 +325,12 @@ return RAISE (PyExc_ValueError, "Destination surface not the correct width or height."); } -#if defined(__unix__) + Py_BEGIN_ALLOW_THREADS; if (!v4l2_read_frame(self, surf)) return NULL; Py_END_ALLOW_THREADS; -#endif + if (!surf) return NULL; @@ -301,13 +340,60 @@ } else { return PySurface_New (surf); } +#elif defined(__APPLE__) + SDL_Surface* surf = NULL; + PyObject *surfobj = NULL; + + if (!PyArg_ParseTuple (arg, "|O!", &PySurface_Type, &surfobj)) + return NULL; + + if (!surfobj) { + surf = SDL_CreateRGBSurface( + 0, + self->boundsRect.right, + self->boundsRect.bottom, + 24, + 0xFF<<16, + 0xFF<<8, + 0xFF, + 0); + + } else { + surf = PySurface_AsSurface(surfobj); + } + + if (!surf) + return NULL; + + if (surf->w != self->boundsRect.right || surf->h != self->boundsRect.bottom) { + return RAISE (PyExc_ValueError, + "Destination surface not the correct width or height."); + } + /*is dit nodig op osx... */ + Py_BEGIN_ALLOW_THREADS; + + if (!mac_read_frame(self, surf)) + return NULL; + Py_END_ALLOW_THREADS; + if (!surf) + return NULL; + + if (surfobj) { + Py_INCREF (surfobj); + return surfobj; + } else { + return PySurface_New (surf); + } +#endif + Py_RETURN_NONE; } /* get_raw() - returns an unmodified image as a string from the buffer */ -PyObject* camera_get_raw(PyCameraObject* self) -{ +PyObject* camera_get_raw(PyCameraObject* self) { #if defined(__unix__) return v4l2_read_raw(self); +#elif defined(__APPLE__) + return mac_read_raw(self); #endif Py_RETURN_NONE; } @@ -318,8 +404,7 @@ /* converts from rgb Surface to yuv or hsv */ /* TODO: Allow for conversion from yuv and hsv to all */ -void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace) -{ +void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace) { switch (cspace) { case YUV_OUT: rgb_to_yuv (src->pixels, dst->pixels, src->h * src->w, 0, src->format); @@ -671,8 +756,7 @@ } /* Converts from rgb444 (R444) to rgb24 (RGB3) */ -void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) -{ +void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) { Uint8 *s, *d8; Uint16 *d16; Uint32 *d32; @@ -731,8 +815,7 @@ /* convert from 4:2:2 YUYV interlaced to RGB */ /* colorspace conversion routine from libv4l. Licensed LGPL 2.1 (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> */ -void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) -{ +void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) { Uint8 *s, *d8; Uint16 *d16; Uint32 *d32; @@ -802,8 +885,7 @@ } /* turn yuyv into packed yuv. */ -void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format) -{ +void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format) { Uint8 *s, *d8; Uint8 y1, u, y2, v; Uint16 *d16; @@ -896,8 +978,7 @@ /* FIXME: Seems to be grayscale and kind of dark on the OLPC XO Maybe the result of a different Bayer color order on the screen? */ /* TODO: Certainly not the most efficient way of doing this conversion. */ -void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) -{ +void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) { Uint8 *rawpt, *d8; Uint16 *d16; Uint32 *d32; @@ -999,8 +1080,7 @@ /* convert from YUV 4:2:0 (YU12) to RGB24 */ /* based on v4lconvert_yuv420_to_rgb24 in libv4l (C) 2008 Hans de Goede. LGPL */ -void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) -{ +void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) { int rshift, gshift, bshift, rloss, gloss, bloss, i, j, u1, v1, rg, y; const Uint8 *y1, *y2, *u, *v; Uint8 *d8_1, *d8_2; @@ -1190,8 +1270,7 @@ } /* turn yuv420 into packed yuv. */ -void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) -{ +void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) { const Uint8 *y1, *y2, *u, *v; Uint8 *d8_1, *d8_2; Uint16 *d16_1, *d16_2; @@ -1290,12 +1369,14 @@ } + + /* * Python API stuff */ - -PyMethodDef cameraobj_builtins[] = -{ + +/* Camera class definition */ +PyMethodDef cameraobj_builtins[] = { { "start", (PyCFunction) camera_start, METH_NOARGS, DOC_CAMERASTART }, { "stop", (PyCFunction) camera_stop, METH_NOARGS, DOC_CAMERASTOP }, { "get_controls", (PyCFunction) camera_get_controls, METH_NOARGS, DOC_CAMERAGETCONTROLS }, @@ -1307,19 +1388,16 @@ { NULL, NULL, 0, NULL } }; -void camera_dealloc (PyObject* self) -{ +void camera_dealloc (PyObject* self) { free(((PyCameraObject*) self)->device_name); PyObject_DEL (self); } -PyObject* camera_getattr(PyObject* self, char* attrname) -{ +PyObject* camera_getattr(PyObject* self, char* attrname) { return Py_FindMethod(cameraobj_builtins, self, attrname); } -PyTypeObject PyCamera_Type = -{ +PyTypeObject PyCamera_Type = { PyObject_HEAD_INIT(NULL) 0, "Camera", @@ -1328,21 +1406,21 @@ camera_dealloc, 0, camera_getattr, - NULL, /*setattr*/ - NULL, /*compare*/ - NULL, /*repr*/ - NULL, /*as_number*/ - NULL, /*as_sequence*/ - NULL, /*as_mapping*/ + NULL, /*setattr*/ + NULL, /*compare*/ + NULL, /*repr*/ + NULL, /*as_number*/ + NULL, /*as_sequence*/ + NULL, /*as_mapping*/ (hashfunc)NULL, /*hash*/ (ternaryfunc)NULL, /*call*/ (reprfunc)NULL, /*str*/ 0L,0L,0L,0L, - DOC_PYGAMECAMERACAMERA /* Documentation string */ + DOC_PYGAMECAMERACAMERA /* Documentation string */ }; -PyObject* Camera (PyCameraObject* self, PyObject* arg) -{ +PyObject* Camera (PyCameraObject* self, PyObject* arg) { +# if defined(__unix__) int w, h; char* dev_name = NULL; char* color = NULL; @@ -1384,36 +1462,78 @@ } return (PyObject*)cameraobj; + +# elif defined(__APPLE__) + int w, h; + char* dev_name = NULL; + char* color = NULL; + PyCameraObject *cameraobj; + + w = DEFAULT_WIDTH; + h = DEFAULT_HEIGHT; + + if (!PyArg_ParseTuple(arg, "s|(ii)s", &dev_name, &w, &h, &color)) + return NULL; + + cameraobj = PyObject_NEW (PyCameraObject, &PyCamera_Type); + + if (cameraobj) { + cameraobj->device_name = (char*) malloc((strlen(dev_name)+1)*sizeof(char)); + strcpy(cameraobj->device_name, dev_name); + if (color) { + if (!strcmp(color, "YUV")) { + cameraobj->color_out = YUV_OUT; + } else if (!strcmp(color, "HSV")) { + cameraobj->color_out = HSV_OUT; + } else { + cameraobj->color_out = RGB_OUT; + } + } else { + cameraobj->color_out = RGB_OUT; + } + cameraobj->component = NULL; + cameraobj->channel = NULL; + cameraobj->gworld = NULL; + cameraobj->boundsRect.top = 0; + cameraobj->boundsRect.left = 0; + cameraobj->boundsRect.bottom = h; + cameraobj->boundsRect.right = w; + cameraobj->size = w * h; + cameraobj->hflip = 0; + cameraobj->vflip = 0; + } + + return (PyObject*)cameraobj; + # endif } -PyMethodDef camera_builtins[] = -{ - { "colorspace", surf_colorspace, METH_VARARGS, DOC_PYGAMECAMERACOLORSPACE }, - { "list_cameras", list_cameras, METH_NOARGS, DOC_PYGAMECAMERALISTCAMERAS }, - { "Camera", (PyCFunction) Camera, METH_VARARGS, DOC_PYGAMECAMERACAMERA }, - { NULL, NULL, 0, NULL } +/* Camera module definition */ +PyMethodDef camera_builtins[] = { + {"colorspace", surf_colorspace, METH_VARARGS, DOC_PYGAMECAMERACOLORSPACE }, + {"list_cameras", list_cameras, METH_NOARGS, DOC_PYGAMECAMERALISTCAMERAS }, + {"Camera", (PyCFunction) Camera, METH_VARARGS, DOC_PYGAMECAMERACAMERA }, + {NULL, NULL, 0, NULL } }; -void init_camera(void) -{ - PyObject *module, *dict; - /* imported needed apis; Do this first so if there is an error - the module is not loaded. - */ - import_pygame_base (); - if (PyErr_Occurred ()) { - return; - } - import_pygame_surface (); - if (PyErr_Occurred ()) { - return; - } +void init_camera(void) { + PyObject *module, *dict; + /* imported needed apis; Do this first so if there is an error + * the module is not loaded. + */ + import_pygame_base(); + if (PyErr_Occurred()) { + return; + } + import_pygame_surface(); + if (PyErr_Occurred()) { + return; + } - /* type preparation */ - PyType_Init(PyCamera_Type); + /* type preparation */ + PyType_Init(PyCamera_Type); - /* create the module */ - module = Py_InitModule3("_camera", camera_builtins, DOC_PYGAMECAMERA); - dict = PyModule_GetDict(module); - PyDict_SetItemString(dict, "CameraType", (PyObject *)&PyCamera_Type); + /* create the module */ + module = Py_InitModule3("_camera", camera_builtins, DOC_PYGAMECAMERA); + dict = PyModule_GetDict(module); + PyDict_SetItemString(dict, "CameraType", (PyObject *)&PyCamera_Type); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/_gcommand.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,115 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + * _movie - movie support for pygame with ffmpeg + * Author: Tyler Laing + * + * This module allows for the loading of, playing, pausing, stopping, and so on + * of a video file. Any format supported by ffmpeg is supported by this + * video player. Any bugs, please email trinioler@gmail.com :) + */ + +#include "_gcommand.h" + +/* command queue management routines... I make a lot of queues, don't I? */ +void addCommand(CommandQueue *q, Command *comm) +{ + SDL_LockMutex(q->q_mutex); + comm->next=NULL; + q->registry[comm->type]++; + if(!q->size) + { + q->first=comm; + q->size++; + SDL_UnlockMutex(q->q_mutex); + return; + } + if(q->size==1) + { + q->last=comm; + q->first->next=comm; + q->size++; + SDL_UnlockMutex(q->q_mutex); + return; + } + q->last->next=comm; + q->last=comm; + q->size++; + SDL_UnlockMutex(q->q_mutex); + return; +} + +Command *getCommand(CommandQueue *q) +{ + SDL_LockMutex(q->q_mutex); + Command *comm; + if(!q->last && q->first) + { + comm=q->first; + q->size--; + SDL_UnlockMutex(q->q_mutex); + return comm; + } + else if (!q->last && !q->first) + { + SDL_UnlockMutex(q->q_mutex); + return NULL; + } + comm=q->first; + q->first=q->first->next; + q->size--; + SDL_UnlockMutex(q->q_mutex); + return comm; +} + +inline int hasCommand(CommandQueue *q) +{ + if(q->size>0) + return 1; + return 0; +} + +void flushCommands(CommandQueue *q) +{ + SDL_LockMutex(q->q_mutex); + Command *prev; + Command *cur = q->first; + while(cur!=NULL) + { + prev=cur; + cur=cur->next; + PyMem_Free(prev); + q->size--; + } + SDL_UnlockMutex(q->q_mutex); +} + +/* registers a command with a particular movie object's command queue. + * Basically, this means, theoretically, different movie objects could have different commands... + */ +int registerCommand(CommandQueue *q) +{ + //int cur = q->reg_ix; + if(q->reg_ix>=1024) + q->reg_ix=0; + q->registry[q->reg_ix]=0; + q->reg_ix++; + return q->reg_ix-1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/_gcommand.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,87 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + * _movie - movie support for pygame with ffmpeg + * Author: Tyler Laing + * + * This module allows for the loading of, playing, pausing, stopping, and so on + * of a video file. Any format supported by ffmpeg is supported by this + * video player. Any bugs, please email trinioler@gmail.com :) + */ + + +#ifndef _GCOMMAND_H_ +#define _GCOMMAND_H_ +#include <SDL.h> +#include <SDL_thread.h> +#include <Python.h> + + +/* Documentation: Command Queue Infrastructure + * This lower-level infrastructure code is meant to provide greater stability and + * thread safety to the _movie module. Since we cannot manipulate the SDL event queue + * we have to use our own hand-rolled solution. It is just a singly linked list, + * with references to the first and last item, allowing us to do a + * simple push/pop implementation. The items in the list are structs that have + * all the first members of the default Command struct, making it safe to + * cast the pointers from the pseudo-Command structs to a pointer to + * Command struct. Realistically, you can cast any pointer to any other kind of + * pointer(as long as they are the same size!), and C will let you. This is dangerous, + * and should only be done very, very carefully. This facility is only useful + * when you need a OO approach, like we did here. + * + * When making new commands, use the FULL_COMMAND macro, and add a line to registerCommands + * in _gmovie.c to add a new type value. This also enables future proofing as any changes to + * the Command struct will be opaque to the user... mostly. + * + * -Tyler Laing, August 4th, 2009 + */ + +typedef struct Command +{ + int type; + struct Command *next; +} Command; + +#define FULL_COMMAND \ + int type;\ + struct Command *next; + +typedef struct CommandQueue +{ + int size; + SDL_mutex *q_mutex; + Command *first; + Command *last; + int registry[1024]; + int reg_ix; +} CommandQueue; + + +void addCommand(CommandQueue *q, Command *comm); +Command *getCommand(CommandQueue *q); +int hasCommand(CommandQueue *q); +void flushCommands(CommandQueue *q); +int registerCommand(CommandQueue *q); + +//convience function for allocating a new command, and ensuring its type is set properly. +#define ALLOC_COMMAND(command, name) command* name = (command *)PyMem_Malloc(sizeof(command)); name->type=movie->command##Type; + +#endif /*_GCOMMAND_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/_gmovie.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,2624 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + * _movie - movie support for pygame with ffmpeg + * Author: Tyler Laing + * + * This module allows for the loading of, playing, pausing, stopping, and so on + * of a video file. Any format supported by ffmpeg is supported by this + * video player. Any bugs, please email trinioler@gmail.com :) + */ + + +#ifndef _GMOVIE_H_ +#include "_gmovie.h" +#endif + +#ifdef __MINGW32__ +#undef main /* We don't want SDL to override our main() */ +#endif + +/* packet queue handling */ +void packet_queue_init(PacketQueue *q) +{ + if(!q) + { + q=(PacketQueue *)PyMem_Malloc(sizeof(PacketQueue)); + } + if(!q->mutex) + q->mutex = SDL_CreateMutex(); + q->abort_request=0; +} + +void packet_queue_flush(PacketQueue *q) +{ + AVPacketList *pkt, *pkt1; + + if(q->mutex) + SDL_LockMutex(q->mutex); + + for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) + { + pkt1 = pkt->next; + av_free_packet(&pkt->pkt); + PyMem_Free(pkt); + } + q->last_pkt = NULL; + q->first_pkt = NULL; + q->nb_packets = 0; + q->size = 0; + + if(q->mutex) + SDL_UnlockMutex(q->mutex); +} + +void packet_queue_end(PacketQueue *q, int end) +{ + AVPacketList *pkt, *pkt1; + + for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) + { + pkt1 = pkt->next; + av_free_packet(&pkt->pkt); + } + if(end==0) + { + //we only destroy the mutex if its the last loop. This way we just reuse and don't fragment memory. + if(q->mutex) + { + SDL_DestroyMutex(q->mutex); + } + } +} + +int packet_queue_put(PacketQueue *q, AVPacket *pkt) +{ + AVPacketList *pkt1; + + /* duplicate the packet */ + if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0) + return -1; + + pkt1 = PyMem_Malloc(sizeof(AVPacketList)); + + if (!pkt1) + return -1; + pkt1->pkt = *pkt; + pkt1->next = NULL; + + if(q->mutex) + SDL_LockMutex(q->mutex); + + if (!q->last_pkt) + q->first_pkt = pkt1; + else + q->last_pkt->next = pkt1; + q->last_pkt = pkt1; + q->nb_packets++; + q->size += pkt1->pkt.size; + /* XXX: should duplicate packet data in DV case */ + + + if(q->mutex) + SDL_UnlockMutex(q->mutex); + + return 0; +} + +void packet_queue_abort(PacketQueue *q) +{ + if(q->mutex) + SDL_LockMutex(q->mutex); + + q->abort_request = 1; + + if(q->mutex) + SDL_UnlockMutex(q->mutex); +} + +/* return < 0 if aborted, 0 if no packet and > 0 if packet. */ +int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) +{ + AVPacketList *pkt1; + int ret; + + if(q->mutex) + SDL_LockMutex(q->mutex); + + for(;;) + { + if (q->abort_request) + { + ret = -1; + break; + } + + pkt1 = q->first_pkt; + if (pkt1) + { + q->first_pkt = pkt1->next; + if (!q->first_pkt) + q->last_pkt = NULL; + q->nb_packets--; + q->size -= pkt1->pkt.size; + *pkt = pkt1->pkt; + PyMem_Free(pkt1); + ret = 1; + break; + } + else if (!block) + { + ret = 0; + break; + } + else + { + ret=0; + break; + } + } + if(q->mutex) + SDL_UnlockMutex(q->mutex); + + return ret; +} + +/* subtitles don't work yet. Code remains until it is needed */ +#if 0 +void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh) +{ + int wrap, wrap3, width2, skip2; + int y, u, v, a, u1, v1, a1, w, h; + uint8_t *lum, *cb, *cr; + const uint8_t *p; + const uint32_t *pal; + int dstx, dsty, dstw, dsth; + + dstw = av_clip(rect->w, 0, imgw); + dsth = av_clip(rect->h, 0, imgh); + dstx = av_clip(rect->x, 0, imgw - dstw); + dsty = av_clip(rect->y, 0, imgh - dsth); + lum = dst->data[0] + dsty * dst->linesize[0]; + cb = dst->data[1] + (dsty >> 1) * dst->linesize[1]; + cr = dst->data[2] + (dsty >> 1) * dst->linesize[2]; + + width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1); + skip2 = dstx >> 1; + wrap = dst->linesize[0]; + wrap3 = rect->pict.linesize[0]; + p = rect->pict.data[0]; + pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */ + + if (dsty & 1) + { + lum += dstx; + cb += skip2; + cr += skip2; + + if (dstx & 1) + { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = _ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = _ALPHA_BLEND(a >> 2, cr[0], v, 0); + cb++; + cr++; + lum++; + p += BPP; + } + for(w = dstw - (dstx & 1); w >= 2; w -= 2) + { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p + BPP, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = _ALPHA_BLEND(a, lum[1], y, 0); + cb[0] = _ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); + cr[0] = _ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); + cb++; + cr++; + p += 2 * BPP; + lum += 2; + } + if (w) + { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = _ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = _ALPHA_BLEND(a >> 2, cr[0], v, 0); + p++; + lum++; + } + p += wrap3 - dstw * BPP; + lum += wrap - dstw - dstx; + cb += dst->linesize[1] - width2 - skip2; + cr += dst->linesize[2] - width2 - skip2; + } + for(h = dsth - (dsty & 1); h >= 2; h -= 2) + { + lum += dstx; + cb += skip2; + cr += skip2; + + if (dstx & 1) + { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + p += wrap3; + lum += wrap; + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = _ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); + cr[0] = _ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); + cb++; + cr++; + p += -wrap3 + BPP; + lum += -wrap + 1; + } + for(w = dstw - (dstx & 1); w >= 2; w -= 2) + { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p + BPP, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = _ALPHA_BLEND(a, lum[1], y, 0); + p += wrap3; + lum += wrap; + + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p + BPP, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = _ALPHA_BLEND(a, lum[1], y, 0); + + cb[0] = _ALPHA_BLEND(a1 >> 2, cb[0], u1, 2); + cr[0] = _ALPHA_BLEND(a1 >> 2, cr[0], v1, 2); + + cb++; + cr++; + p += -wrap3 + 2 * BPP; + lum += -wrap + 2; + } + if (w) + { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + p += wrap3; + lum += wrap; + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = _ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); + cr[0] = _ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); + cb++; + cr++; + p += -wrap3 + BPP; + lum += -wrap + 1; + } + p += wrap3 + (wrap3 - dstw * BPP); + lum += wrap + (wrap - dstw - dstx); + cb += dst->linesize[1] - width2 - skip2; + cr += dst->linesize[2] - width2 - skip2; + } + /* handle odd height */ + if (h) + { + lum += dstx; + cb += skip2; + cr += skip2; + + if (dstx & 1) + { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = _ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = _ALPHA_BLEND(a >> 2, cr[0], v, 0); + cb++; + cr++; + lum++; + p += BPP; + } + for(w = dstw - (dstx & 1); w >= 2; w -= 2) + { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p + BPP, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = _ALPHA_BLEND(a, lum[1], y, 0); + cb[0] = _ALPHA_BLEND(a1 >> 2, cb[0], u, 1); + cr[0] = _ALPHA_BLEND(a1 >> 2, cr[0], v, 1); + cb++; + cr++; + p += 2 * BPP; + lum += 2; + } + if (w) + { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = _ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = _ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = _ALPHA_BLEND(a >> 2, cr[0], v, 0); + } + } +} + +void free_subpicture(SubPicture *sp) +{ + int i; + + for (i = 0; i < sp->sub.num_rects; i++) + { + av_freep(&sp->sub.rects[i]->pict.data[0]); + av_freep(&sp->sub.rects[i]->pict.data[1]); + av_freep(&sp->sub.rects[i]); + } + + av_free(sp->sub.rects); + + memset(&sp->sub, 0, sizeof(AVSubtitle)); +} +#endif + +/* Sets the value of the variable width. Acts like a macro */ +void inline get_width(PyMovie *movie, int *width) +{ + if(movie->resize_w) + { + *width=movie->width; + } + else + { + if(movie->video_st) + *width=movie->video_st->codec->width; + } +} +/* Sets the value of the variable height. Acts like a macro */ +void inline get_height(PyMovie *movie, int *height) +{ + if(movie->resize_h) + { + *height=movie->height; + } + else + { + if(movie->video_st) + *height=movie->video_st->codec->height; + } +} + +void get_height_width(PyMovie *movie, int *height, int*width) +{ + get_height(movie, height); + get_width(movie, width); +} + +inline void jamPixels(int ix, AVPicture *picture, uint32_t *rgb, SDL_Surface *surface) +{ + //uint32_t *rgb = surface->pixels; + uint8_t red = picture->data[0][ix]; + uint8_t green = picture->data[0][ix+1]; + uint8_t blue = picture->data[0][ix+2]; + //skip the alpha... we don't care + /* shift components to the correct place in pixel */ + + *rgb = ( red << (long) surface->format->Rshift) | /* red */ + ( blue << (long) surface->format->Bshift ) | /* green */ + ( green << (long) surface->format->Gshift ) | /* blue */ + ( 0 << (long) surface->format->Ashift); +} + +//transfers data from the AVPicture written to by swscale to a surface +void WritePicture2Surface(AVPicture *picture, SDL_Surface *surface, int w, int h) +{ + /* AVPicture initialized with PIX_FMT_RGBA only fills pict->data[0] + * This however is only in {R,G,B, A} format. So we just copy the data over. + */ + /* Loop unrolling: + * We define a blocksize, and so we increment the index counter by blocksize*rgbstep + * All common resolutions are nicely divisible by 8(because 8 is a power of 2...) + * An uncommon resolution could have between 1 and 7 bytes left to convert... + * which I guess we'll leave alone. Its just 1-2 pixels in the lower right corner. + * So we repeat the same actions blocksize times. + */ + int64_t blocksize = 8; + uint32_t *rgb = surface->pixels; + int BytesPerPixel = RGBSTEP; + int64_t size = w*h*BytesPerPixel; + int64_t ix = 0; + int64_t blocklimit = (size/blocksize)*blocksize; + while(ix<blocklimit) + { + //this will be unrolled by the compiler, meaning that we do less comparisons by a factor of blocksize + int i =0; + for(;i<blocksize;i++) + { + jamPixels(ix, picture, rgb, surface); + rgb++; + ix+=RGBSTEP; + } + } +} + + +int video_display(PyMovie *movie) +{ + double ret=1; + + VidPicture *vp = &movie->pictq[movie->pictq_rindex]; + if (movie->video_stream>=0 && vp->ready) + { + video_image_display(movie); + } + else if(!vp->ready) + { + ret=0; + } + + /* If we didn't actually display the image, we need to not clear our timer out in decoder */ + return ret; +} + +int video_image_display(PyMovie *movie) +{ + /* Wrapped by video_display, which has a lock on the movie object */ + DECLAREGIL + + VidPicture *vp; + //SubPicture *sp; + float aspect_ratio; + int width, height, x, y; + vp = &movie->pictq[movie->pictq_rindex]; + vp->ready =0; + //GRABGIL + //PySys_WriteStdout("video_current_pts: %f\tvp->pts: %f\ttime: %f\n", movie->video_current_pts, vp->pts, (av_gettime()/1000.0)-(movie->timing+movie->last_showtime)); + //RELEASEGIL + //set up the aspect ratio values.. +#if LIBAVFORMAT_VERSION_INT>= 3415808 + + if (movie->video_st->sample_aspect_ratio.num) + aspect_ratio = av_q2d(movie->video_st->sample_aspect_ratio); + else if (movie->video_st->codec->sample_aspect_ratio.num) + aspect_ratio = av_q2d(movie->video_st->codec->sample_aspect_ratio); + else + aspect_ratio = 0; + if (aspect_ratio <= 0.0) + aspect_ratio = 1.0; + +#else + + aspect_ratio = 1.0; + +#endif + //then we load in width and height values based on the aspect ration and w/h. + int w=0; + int h=0; + get_height_width(movie, &h, &w); + aspect_ratio *= (float)w / h; + /* XXX: we suppose the screen has a 1.0 pixel ratio */ + height = vp->height; + width = ((int)rint(height * aspect_ratio)) & ~1; + if (width > vp->width) + { + width = vp->width; + height = ((int)rint(width / aspect_ratio)) & ~1; + } + x = (vp->width - width) / 2; + y = (vp->height - height) / 2; + + //we set the rect to have the values we need for blitting/overlay display + + vp->dest_rect.x = vp->xleft + x; + vp->dest_rect.y = vp->ytop + y; + + vp->dest_rect.w=width; + vp->dest_rect.h=height; + + if (vp->dest_overlay && vp->overlay>0 && !movie->skip_frame) + { + //SDL_Delay(10); +#if 0 + if (movie->sub_st) + { + if (movie->subpq_size > 0) + { + sp = &movie->subpq[movie->subpq_rindex]; + AVPicture pict; + int i; + + if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) + { + SDL_LockYUVOverlay (vp->dest_overlay); + + pict.data[0] = vp->dest_overlay->pixels[0]; + pict.data[1] = vp->dest_overlay->pixels[2]; + pict.data[2] = vp->dest_overlay->pixels[1]; + + pict.linesize[0] = vp->dest_overlay->pitches[0]; + pict.linesize[1] = vp->dest_overlay->pitches[2]; + pict.linesize[2] = vp->dest_overlay->pitches[1]; + + for (i = 0; i < sp->sub.num_rects; i++) + blend_subrect(&pict, sp->sub.rects[i], + vp->dest_overlay->w, vp->dest_overlay->h); + + SDL_UnlockYUVOverlay (vp->dest_overlay); + } + } + } +#endif + if(vp->overlay>0) + { + SDL_LockYUVOverlay(vp->dest_overlay); + SDL_DisplayYUVOverlay(vp->dest_overlay, &vp->dest_rect); + SDL_UnlockYUVOverlay(vp->dest_overlay); + } + } + else if(vp->dest_surface && vp->overlay<=0) + { + SDL_BlitSurface(vp->dest_surface, &vp->dest_rect, movie->canon_surf, &vp->dest_rect); + } + + movie->pictq_rindex= (movie->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE; + movie->pictq_size--; + if(movie->skip_frame) + movie->skip_frame=0; + video_refresh_timer(movie); + return 1; +} + +int video_open(PyMovie *movie, int index) +{ + int w=0; + int h=0; + + DECLAREGIL + get_height_width(movie, &h, &w); + int tw=w; + int th=h; + VidPicture *vp; + for(index=0;index<VIDEO_PICTURE_QUEUE_SIZE; index++) + { + vp = &movie->pictq[index]; + if( + //If we have no overlay, and we are supposed to, we jump right in + (!vp->dest_overlay && movie->overlay>0) || + ( + /* otherwise, we need to enter this block if + * we need to resize AND there is an overlay AND + * it is not the right size + */ + (movie->resize_w||movie->resize_h) && + vp->dest_overlay && + (vp->height!=h || vp->width!=w) + ) + ) + { + if(movie->resize_w || movie->resize_h) + { + //we free this overlay, because we KNOW its not the right size. + SDL_FreeYUVOverlay(vp->dest_overlay); + } + if(movie->overlay>0) + { + //now we have to open an overlay up + SDL_Surface *screen; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + { + GRABGIL + RAISE(PyExc_SDLError,"cannot create overlay without pygame.display initialized"); + RELEASEGIL + return -1; + } + screen = SDL_GetVideoSurface (); + if (!screen || (screen && (screen->w!=w || screen->h !=h))) + { + //resize the main screen + screen = SDL_SetVideoMode(w, h, 0, SDL_SWSURFACE); + if(!screen) + { + GRABGIL + RAISE(PyExc_SDLError, "Could not initialize a new video surface."); + RELEASEGIL + return -1; + } + } + //create a new overlay + vp->dest_overlay = SDL_CreateYUVOverlay (w, h, SDL_YV12_OVERLAY, screen); + if (!vp->dest_overlay) + { + GRABGIL + RAISE (PyExc_SDLError, "Cannot create overlay"); + RELEASEGIL + return -1; + } + vp->overlay = movie->overlay; + } + } + if (!vp->dest_surface && movie->overlay<=0) + { + //now we have to open an overlay up + if(movie->overlay<=0) + { + SDL_Surface *screen = movie->canon_surf; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + { + GRABGIL + RAISE(PyExc_SDLError,"cannot create surfaces without pygame.display initialized"); + RELEASEGIL + return -1; + } + if (!screen) + { + GRABGIL + RAISE(PyExc_SDLError, "No video surface given."); //ideally this should have + RELEASEGIL // happen if there's some cleaning up. + return -1; + } + if(screen->h!=h) + { + th=screen->h; + } + if(screen->w!=w) + { + tw=screen->w; + } + + vp->dest_surface = SDL_CreateRGBSurface(screen->flags, + tw, + th, + screen->format->BitsPerPixel, + screen->format->Rmask, + screen->format->Gmask, + screen->format->Bmask, + screen->format->Amask); + + if (!vp->dest_surface) + { + GRABGIL + RAISE (PyExc_SDLError, "Cannot create new surface."); + RELEASEGIL + return -1; + } + vp->overlay = movie->overlay; + } + } + vp->width = tw; + vp->height = th; + vp->ytop=movie->ytop; + vp->xleft=movie->xleft; + + } + return 0; +} + +/* called to determine a time to show each frame */ +void video_refresh_timer(PyMovie* movie) +{ + DECLAREGIL + double actual_delay, delay, sync_threshold, ref_clock, diff; + VidPicture *vp; + + double cur_time=av_gettime(); + + if (movie->video_st) + { /*shouldn't ever even get this far if no video_st*/ + movie->diff_co ++; + + /* dequeue the picture */ + vp = &movie->pictq[movie->pictq_rindex]; + + /* update current video pts */ + movie->video_current_pts = vp->pts; + movie->video_current_pts_time = cur_time; + + /* compute nominal delay */ + delay = movie->video_current_pts - movie->frame_last_pts; + if (delay <= 0 || delay >= 10.0) + { + /* if incorrect delay, use previous one */ + delay = movie->frame_last_delay; + } + else + { + movie->frame_last_delay = delay; + } + movie->frame_last_pts = movie->video_current_pts; + + /* update delay to follow master synchronisation source */ + if (((movie->av_sync_type == AV_SYNC_AUDIO_MASTER && movie->audio_st) || + movie->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) + { + /* if video is slave, we try to correct big delays by + duplicating or deleting a frame */ + ref_clock = getAudioClock(); + diff = movie->video_current_pts - ref_clock; + /* skip or repeat frame. We take into account the + delay to compute the threshold. I still don't know + if it is the best guess */ + + sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay); + if (fabs(diff) < AV_NOSYNC_THRESHOLD) + { + if (diff <= -sync_threshold) + { + movie->skip_frame=1; + delay = 0; + } + else if (diff >= sync_threshold) + delay = 2 * delay; + } + } + + movie->frame_timer += delay; + /* compute the REAL delay (we need to do that to avoid + long term errors */ + actual_delay = movie->frame_timer - (cur_time / 1000000.0); + if (actual_delay < 0.010) + { + /* XXX: should skip picture */ + actual_delay = 0.010; + } + + GRABGIL + //PySys_WriteStdout("Actual Delay: %f\tdelay: %f\tdiff: %f\tpts: %f\tFrame-timer: %f\tCurrent_time: %f\tsync_thres: %f\n", (actual_delay*1000.0)+10, delay, diff, movie->video_current_pts, movie->frame_timer, (cur_time / 1000000.0), sync_threshold); + //double audio = getAudioClock(); + //PySys_WriteStdout("Audio_Clock: %f\tVideo_Clock: %f\tDiff: %f\n", ref_clock, movie->video_current_pts, ref_clock-movie->video_current_pts); + movie->timing = (actual_delay*1000.0)+10; + RELEASEGIL + } + +} + +int queue_picture(PyMovie *movie, AVFrame *src_frame) +{ + DECLAREGIL + int dst_pix_fmt; + AVPicture pict; + VidPicture *vp; + struct SwsContext *img_convert_ctx=movie->img_convert_ctx; + + vp = &movie->pictq[movie->pictq_windex]; + + int w=0; + int h=0; + get_height_width(movie, &h, &w); + int pw, ph; + + if(vp->dest_surface) + { + pw=vp->dest_surface->w; + ph=vp->dest_surface->h; + } + + dst_pix_fmt = PIX_FMT_YUV420P; +#ifdef PROFILE + + int64_t before = av_gettime(); +#endif + + if (vp->dest_overlay && vp->overlay>0) + { + /* get a pointer on the bitmap */ + SDL_LockYUVOverlay(vp->dest_overlay); + + pict.data[0] = vp->dest_overlay->pixels[0]; + pict.data[1] = vp->dest_overlay->pixels[2]; + pict.data[2] = vp->dest_overlay->pixels[1]; + pict.linesize[0] = vp->dest_overlay->pitches[0]; + pict.linesize[1] = vp->dest_overlay->pitches[2]; + pict.linesize[2] = vp->dest_overlay->pitches[1]; + } + else if(vp->dest_surface) + { + /* get a pointer on the bitmap */ + if(RGB24) + { + dst_pix_fmt = PIX_FMT_RGB24; + } + else if(RGBA) + { + dst_pix_fmt = PIX_FMT_RGBA; + } + avpicture_alloc(&pict, dst_pix_fmt, pw, ph); + SDL_LockSurface(vp->dest_surface); + } + int sws_flags = SWS_BICUBIC; + img_convert_ctx = sws_getCachedContext(img_convert_ctx, + movie->video_st->codec->width, + movie->video_st->codec->height, + movie->video_st->codec->pix_fmt, + w, + h, + dst_pix_fmt, + sws_flags, + NULL, NULL, NULL); + if (img_convert_ctx == NULL) + { + fprintf(stderr, "Cannot initialize the conversion context\n"); + exit(1); + } + movie->img_convert_ctx = img_convert_ctx; + + if((movie->resize_w||movie->resize_h) || vp->dest_overlay) + { + sws_scale(img_convert_ctx, + src_frame->data, + src_frame->linesize, + 0, + h, + pict.data, + pict.linesize); + } + else if(vp->dest_surface) + { + sws_scale(img_convert_ctx, + src_frame->data, + src_frame->linesize, + 0, + ph, + pict.data, + pict.linesize); + } + + if (vp->dest_overlay && vp->overlay>0) + { + SDL_UnlockYUVOverlay(vp->dest_overlay); + } + else if(vp->dest_surface) + { + WritePicture2Surface(&pict, vp->dest_surface, pw, ph); + SDL_UnlockSurface(vp->dest_surface); + //avpicture_free(&pict); + } +#ifdef PROFILE + TimeSampleNode *sample = (TimeSampleNode *)PyMem_Malloc(sizeof(TimeSampleNode)); + sample->next=NULL; + sample->sample = av_gettime()-before; + if (!movie->istats->last || movie->istats->first->sample==0) + movie->istats->first = sample; + else + movie->istats->last->next = sample; + movie->istats->last = sample; + movie->istats->n_samples++; +#endif + + vp->pts = movie->pts; + movie->pictq_windex = (movie->pictq_windex+1)%VIDEO_PICTURE_QUEUE_SIZE; + movie->pictq_size++; + vp->ready=1; + return 0; +} + + +void update_video_clock(PyMovie *movie, AVFrame* frame, double pts1) +{ + double frame_delay, pts; + + pts = pts1; + + if (pts != 0) + { + /* update video clock with pts, if present */ + movie->video_current_pts = pts; + } + else + { + pts = movie->video_current_pts; + } + /* update video clock for next frame */ + frame_delay = av_q2d(movie->video_st->codec->time_base); + /* for MPEG2, the frame can be repeated, so we update the + clock accordingly */ + frame_delay += frame->repeat_pict * (frame_delay * 0.5); + movie->video_current_pts += frame_delay; + + movie->pts = pts; +} + +/* get the current audio clock value */ +double get_audio_clock(PyMovie *movie) +{ + return getAudioClock(); +} + +/* get the current video clock value */ +double get_video_clock(PyMovie *movie) +{ + double delta; + + if (movie->paused) + { + delta = 0; + } + else + { + delta = (av_gettime() - movie->video_current_pts_time) / 1000000.0; + } + double temp = movie->video_current_pts+delta; + return temp; +} + +/* get the current external clock value */ +double get_external_clock(PyMovie *movie) +{ + int64_t ti; + ti = av_gettime(); + double res = movie->external_clock + ((ti - movie->external_clock_time) * 1e-6); + return res; +} + +/* get the current master clock value */ +double get_master_clock(PyMovie *movie) +{ + double val; + + if (movie->av_sync_type == AV_SYNC_VIDEO_MASTER) + { + if (movie->video_st) + val = get_video_clock(movie); + else + val = get_audio_clock(movie); + } + else if (movie->av_sync_type == AV_SYNC_AUDIO_MASTER) + { + if (movie->audio_st) + val = get_audio_clock(movie); + else + val = get_video_clock(movie); + } + else + { + val = get_external_clock(movie); + } + return val; +} + +void registerCommands(PyMovie *self) +{ + self->seekCommandType=registerCommand(self->commands); + self->pauseCommandType=registerCommand(self->commands); + self->stopCommandType=registerCommand(self->commands); + self->resizeCommandType=registerCommand(self->commands); + self->shiftCommandType = registerCommand(self->commands); + self->surfaceCommandType = registerCommand(self->commands); +} + +/* seek in the stream */ +void stream_seek(PyMovie *movie, int64_t pos, int rel) +{ + ALLOC_COMMAND(seekCommand, seek) + seek->pos = pos; + seek->rel = rel; + addCommand(movie->commands, (Command *)seek); +} + +/* pause or resume the video */ +void stream_pause(PyMovie *movie) +{ + ALLOC_COMMAND(pauseCommand, pause); + addCommand(movie->commands, (Command *)pause); +} + +int audio_thread(void *arg) +{ + PyMovie *movie = arg; + DECLAREGIL + GRABGIL + Py_INCREF(movie); + RELEASEGIL + AVPacket *pkt = &movie->audio_pkt; + AVCodecContext *dec= movie->audio_st->codec; + int len1, data_size; + int filled =0; + len1=0; + for(;;) + { + if(movie->stop || movie->audioq.abort_request) + { + pauseBuffer(movie->channel); + stopBuffer(movie->channel); + goto closing; + } + if(movie->paused!=movie->audio_paused) + { + pauseBuffer(movie->channel); + movie->audio_paused=movie->paused; + if(movie->audio_paused) + { + movie->working=0; + continue; + } + } + + if(movie->paused) + { + SDL_Delay(10); + continue; + } + //check if the movie has ended + + if(getBufferQueueSize()>20) + { + SDL_Delay(100); + continue; + } + + //fill up the buffer + while(movie->audio_pkt_size > 0) + { + 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) + { + /* Buffer is filled up with a new frame, we spin lock/wait for a signal, where we then call playBuffer */ + int chan = playBuffer(movie->audio_buf1, data_size, movie->channel, movie->audio_pts); + if(chan==-1) + { + GRABGIL + char *s = Mix_GetError(); + PySys_WriteStdout("%s\n", s); + RELEASEGIL + } + movie->channel = chan; + filled=0; + len1=0; + } + + //either buffer filled or no packets yet + /* free the current packet */ + if (pkt->data) + av_free_packet(pkt); + + /* read next packet */ + if (packet_queue_get(&movie->audioq, pkt, 1) <= 0) + { + SDL_Delay(10); + continue; + } + + if(pkt->data == flush_pkt.data) + { + avcodec_flush_buffers(dec); + SDL_Delay(10); + continue; + } + + movie->audio_pts = pkt->pts; + movie->audio_pkt_data = pkt->data; + movie->audio_pkt_size = pkt->size; + + } +closing: + GRABGIL + Py_DECREF(movie); + RELEASEGIL + return 0; +} + +/* open a given stream. Return 0 if OK */ +int stream_component_open(PyMovie *movie, int stream_index, int threaded) +{ + DECLAREGIL + if(threaded) + { + GRABGIL + } + Py_INCREF( movie); + if(threaded) + { + RELEASEGIL + } + + AVFormatContext *ic = movie->ic; + AVCodecContext *enc; + if (stream_index < 0 || stream_index >= ic->nb_streams) + { + if(threaded) + {GRABGIL} + Py_DECREF(movie); + if(threaded) + {RELEASEGIL} + return -1; + } + + initialize_codec(movie, stream_index, threaded); + + enc = ic->streams[stream_index]->codec; + switch(enc->codec_type) + { + case CODEC_TYPE_AUDIO: + movie->audio_stream = stream_index; + movie->audio_st = ic->streams[stream_index]; + break; + case CODEC_TYPE_VIDEO: + movie->video_stream = stream_index; + movie->video_st = ic->streams[stream_index]; + break; +#if 0 + + case CODEC_TYPE_SUBTITLE: + movie->sub_stream = stream_index; + movie->sub_st = ic->streams[stream_index]; +#endif + + default: + break; + } + if(threaded) + { + GRABGIL + } + Py_DECREF( movie); + if(threaded) + { + RELEASEGIL + } + return 0; +} +/* open a given stream. Return 0 if OK */ +int stream_component_start(PyMovie *movie, int stream_index, int threaded) +{ + DECLAREGIL + if(threaded) + { + GRABGIL + } + Py_INCREF( movie); + if(threaded) + { + RELEASEGIL + } + AVFormatContext *ic = movie->ic; + AVCodecContext *enc; + + if (stream_index < 0 || stream_index >= ic->nb_streams) + { + if(threaded) + { + GRABGIL + } + Py_DECREF(movie); + if(threaded) + { + RELEASEGIL + } + return -1; + } + initialize_codec(movie, stream_index, threaded); + enc = ic->streams[stream_index]->codec; + switch(enc->codec_type) + { + case CODEC_TYPE_AUDIO: + if(movie->replay) + { + movie->audio_st = ic->streams[stream_index]; + movie->audio_stream = stream_index; + } + memset(&movie->audio_pkt, 0, sizeof(movie->audio_pkt)); + packet_queue_init(&movie->audioq); + movie->audio_mutex = SDL_CreateMutex(); + soundStart(); + movie->audio_tid = SDL_CreateThread(audio_thread, movie); + break; + case CODEC_TYPE_VIDEO: + if(movie->replay) + { + movie->video_stream = stream_index; + movie->video_st = ic->streams[stream_index]; + } + movie->frame_last_delay = 40e-3; + movie->frame_timer = (double)av_gettime() / 1000000.0; + movie->video_current_pts_time = av_gettime(); + packet_queue_init(&movie->videoq); + break; +#if 0 + + case CODEC_TYPE_SUBTITLE: + if(movie->replay) + { + movie->sub_stream = stream_index; + movie->sub_st = ic->streams[stream_index]; + } + packet_queue_init(&movie->subq); +#endif + + default: + break; + } + if(threaded) + { + GRABGIL + } + Py_DECREF( movie); + if(threaded) + { + RELEASEGIL + } + return 0; +} + +void stream_component_end(PyMovie *movie, int stream_index, int threaded) +{ + DECLAREGIL + if(threaded) + { + GRABGIL + } + if(movie->ob_refcnt!=0) + Py_INCREF( movie); + if(threaded) + { + RELEASEGIL + } + AVFormatContext *ic = movie->ic; + AVCodecContext *enc; + + if (stream_index < 0 || stream_index >= ic->nb_streams) + { + if(threaded) + { + GRABGIL + } + if(movie->ob_refcnt!=0) + { + Py_DECREF(movie); + } + if(threaded) + { + RELEASEGIL + } + return; + } + movie->replay=1; + enc = ic->streams[stream_index]->codec; + int i; + VidPicture *vp; + //SubPicture *sp; + switch(enc->codec_type) + { + case CODEC_TYPE_AUDIO: + packet_queue_abort(&movie->audioq); + SDL_WaitThread(movie->audio_tid, NULL); + SDL_DestroyMutex(movie->audio_mutex); + soundEnd(); + memset(&movie->audio_buf1, 0, sizeof(movie->audio_buf1)); + packet_queue_flush(&movie->audioq); + break; + case CODEC_TYPE_VIDEO: + for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE;i++) + { + vp = &movie->pictq[i]; + vp->ready=0; + } + movie->video_current_pts=0; + packet_queue_abort(&movie->videoq); + packet_queue_flush(&movie->videoq); + break; +#if 0 + + case CODEC_TYPE_SUBTITLE: + packet_queue_abort(&movie->subq); + packet_queue_flush(&movie->subq); + break; +#endif + + default: + break; + } + ic->streams[stream_index]->discard = AVDISCARD_ALL; + + if(threaded) + { + GRABGIL + } + if(movie->ob_refcnt!=0) + { + Py_DECREF( movie); + } + if(threaded) + { + RELEASEGIL + } +} +void stream_component_close(PyMovie *movie, int stream_index, int threaded) +{ + DECLAREGIL + if(threaded) + { + GRABGIL + } + if(movie->ob_refcnt!=0) + { Py_INCREF( movie);} + if(threaded) + { + RELEASEGIL + } + AVFormatContext *ic = movie->ic; + AVCodecContext *enc; + + if (stream_index < 0 || stream_index >= ic->nb_streams) + { + if(threaded) + { + GRABGIL + } + if(movie->ob_refcnt!=0) + { + Py_DECREF(movie); + } + if(threaded) + { + RELEASEGIL + } + return; + } + enc = ic->streams[stream_index]->codec; + int end = movie->loops; + switch(enc->codec_type) + { + case CODEC_TYPE_AUDIO: + soundQuit(); + packet_queue_end(&movie->audioq, end); + break; + case CODEC_TYPE_VIDEO: + packet_queue_end(&movie->videoq, end); + break; + default: + break; + } + + ic->streams[stream_index]->discard = AVDISCARD_ALL; + avcodec_close(enc); + switch(enc->codec_type) + { + case CODEC_TYPE_AUDIO: + movie->audio_st = NULL; + movie->audio_stream = -1; + break; + case CODEC_TYPE_VIDEO: + movie->video_st = NULL; + movie->video_stream = -1; + break; +#if 0 + + case CODEC_TYPE_SUBTITLE: + movie->sub_st=NULL; + movie->sub_stream = -1; +#endif + + default: + break; + } + + if(threaded) + { + GRABGIL + } + if(movie->ob_refcnt!=0) + { + Py_DECREF( movie); + } + if(threaded) + { + RELEASEGIL + } +} + +void stream_open(PyMovie *movie, const char *filename, AVInputFormat *iformat, int threaded) +{ + if (!movie) + return; + DECLAREGIL + if(threaded) + { + GRABGIL + } + Py_INCREF(movie); + if(threaded) + { + RELEASEGIL + } + int i, ret, video_index, audio_index, subtitle_index; + + strncpy(movie->filename, filename, strlen(filename)+1); + movie->iformat = iformat; + + /* start video dmovieplay */ + movie->dest_mutex = SDL_CreateMutex(); + + //in case we've called stream open once before... + movie->abort_request = 0; + movie->av_sync_type = AV_SYNC_AUDIO_MASTER; + + video_index = -1; + audio_index = -1; + subtitle_index = -1; + movie->video_stream = -1; + movie->audio_stream = -1; + //movie->sub_stream = -1; + + initialize_context(movie, threaded); //moved a bunch of convenience stuff out of here for access at other times + + int wanted_video_stream=1; + int wanted_audio_stream=1; + + /* if seeking requested, we execute it */ + if (movie->start_time != AV_NOPTS_VALUE) + { + int64_t timestamp; + + timestamp = movie->start_time; + /* add the stream start time */ + if (movie->ic->start_time != AV_NOPTS_VALUE) + timestamp += movie->ic->start_time; + ret = av_seek_frame(movie->ic, -1, timestamp, AVSEEK_FLAG_BACKWARD); + if (ret < 0) + { + if(threaded) + { + GRABGIL + } + PyErr_Format(PyExc_IOError, "%s: could not seek to position %0.3f", movie->filename, (double)timestamp/AV_TIME_BASE); + if(threaded) + { + RELEASEGIL + } + } + } + for(i = 0; i < movie->ic->nb_streams; i++) + { + AVCodecContext *enc = movie->ic->streams[i]->codec; + movie->ic->streams[i]->discard = AVDISCARD_ALL; + switch(enc->codec_type) + { + case CODEC_TYPE_AUDIO: + if (wanted_audio_stream-- >= 0 && !movie->audio_disable) + audio_index = i; + break; + case CODEC_TYPE_VIDEO: + if (wanted_video_stream-- >= 0 && !movie->video_disable) + video_index = i; + break; + case CODEC_TYPE_SUBTITLE: + //if(wanted_subti_stream -- >= 0 && !movie->subtitle_disable) + // subtitle_index=i; + default: + break; + } + } + + /* open the streams */ + if (audio_index >= 0) + { + stream_component_open(movie, audio_index, threaded); + } + + if (video_index >= 0) + { + stream_component_open(movie, video_index, threaded); + } + if(subtitle_index >= 0) + { + stream_component_open(movie, subtitle_index, threaded); + } + + if (movie->video_stream < 0 && movie->audio_stream < 0) + { + if(threaded) + { + GRABGIL + } + PyErr_Format(PyExc_IOError, "%s: could not open codecs", movie->filename); + if(threaded) + { + RELEASEGIL + } + ret = -1; + goto fail; + } + movie->frame_delay = av_q2d(movie->video_st->codec->time_base); + + ret = 0; +fail: + if(ret!=0) + { + if(threaded) + { + GRABGIL + } + PyObject *er; + er=PyErr_Occurred(); + if(er) + { + PyErr_Print(); + } + Py_DECREF(movie); + if(threaded) + { + RELEASEGIL + } + return; + } + if(threaded) + { + GRABGIL + } + Py_DECREF(movie); + if(threaded) + { + RELEASEGIL + } + return; +} + + +int initialize_context(PyMovie *movie, int threaded) +{ + DECLAREGIL + AVFormatContext *ic; + AVFormatParameters params, *ap = ¶ms; + int ret, err; + + memset(ap, 0, sizeof(*ap)); + ap->width = 0; + ap->height= 0; + ap->time_base= (AVRational) + { + 1, 25 + }; + ap->pix_fmt = PIX_FMT_NONE; + + if (movie->ic) + { + av_close_input_file(movie->ic); + movie->ic = NULL; /* safety */ + } + movie->iformat = NULL; + err = av_open_input_file(&ic, movie->filename, movie->iformat, 0, ap); + if (err < 0) + { + if(threaded) + { + GRABGIL + } + PyErr_Format(PyExc_IOError, "There was a problem opening up %s, due to %i", movie->filename, err); + if(threaded) + { + RELEASEGIL + } + ret = -1; + goto fail; + } + err = av_find_stream_info(ic); + if (err < 0) + { + if(threaded) + { + GRABGIL + } + PyErr_Format(PyExc_IOError, "%s: could not find codec parameters", movie->filename); + if(threaded) + { + RELEASEGIL + } + ret = -1; + goto fail; + } +#if LIBAVCODEC_VERSION_INT>=3412992 //(52<<16)+(20<<8)+0 ie 52.20.0 + if(ic->pb) + ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end +#endif + + movie->ic = ic; + ret=0; +fail: + return ret; + +} + +int initialize_codec(PyMovie *movie, int stream_index, int threaded) +{ + DECLAREGIL + if(threaded) + { + GRABGIL + } + Py_INCREF(movie); + if(threaded) + { + RELEASEGIL + } + AVFormatContext *ic = movie->ic; + AVCodecContext *enc; + AVCodec *codec; + int freq, channels; + enc = ic->streams[stream_index]->codec; + /* prepare audio output */ + if (enc->codec_type == CODEC_TYPE_AUDIO) + { +#if LIBAVCODEC_VERSION_INT>=3412992 //(52<<16)+(20<<8)+0 ie 52.20.0 + if (enc->channels > 0) + { + enc->request_channels = FFMIN(2, enc->channels); + } + else + { + enc->request_channels = 2; + } +#endif + } + codec = avcodec_find_decoder(enc->codec_id); + enc->debug_mv = 0; + enc->debug = 0; + enc->workaround_bugs = 1; + enc->lowres = 0; + enc->idct_algo= FF_IDCT_AUTO; + if(0) + enc->flags2 |= CODEC_FLAG2_FAST; + enc->skip_frame= AVDISCARD_DEFAULT; + enc->skip_idct= AVDISCARD_DEFAULT; + enc->skip_loop_filter= AVDISCARD_DEFAULT; +#if LIBAVCODEC_VERSION_INT>=3412992 //(52<<16)+(20<<8)+0 ie 52.20.0 + + enc->error_recognition= FF_ER_CAREFUL; +#endif + enc->error_concealment= 3; + + + //TODO:proper error reporting here please + int ret =avcodec_open(enc, codec); + if(ret < 0) + { + if(threaded) + { + GRABGIL + } + Py_DECREF(movie); + if(threaded) + { + RELEASEGIL + } + return -1; + } + /* prepare audio output */ + if (enc->codec_type == CODEC_TYPE_AUDIO) + { + + freq = enc->sample_rate; + channels = enc->channels; + if(!movie->replay) + { + if (soundInit (freq, -16, channels, 1024, av_q2d(ic->streams[stream_index]->time_base)) < 0) + { + RAISE(PyExc_SDLError, SDL_GetError ()); + } + } + movie->audio_src_fmt= AUDIO_S16SYS; + } + + enc->thread_count= 1; + ic->streams[stream_index]->discard = AVDISCARD_DEFAULT; + if(threaded) + { + GRABGIL + } + Py_DECREF(movie); + if(threaded) + { + RELEASEGIL + } + return 0; +} +void stream_close(PyMovie *movie, int threaded) +{ + DECLAREGIL + if(threaded) + { + GRABGIL + } + if(movie->ob_refcnt!=0) + Py_INCREF(movie); + if(threaded) + { + RELEASEGIL + } + movie->abort_request = 1; + SDL_WaitThread(movie->parse_tid, NULL); + VidPicture *vp; + + if(movie) + { + int i; + for( i =0; i<VIDEO_PICTURE_QUEUE_SIZE; i++) + { + vp = &movie->pictq[i]; + if (vp->dest_overlay) + { + SDL_FreeYUVOverlay(vp->dest_overlay); + vp->dest_overlay = NULL; + } + if(vp->dest_surface) + { + SDL_FreeSurface(vp->dest_surface); + vp->dest_surface=NULL; + } + + } + SDL_DestroyMutex(movie->dest_mutex); + if(movie->img_convert_ctx) + { + sws_freeContext(movie->img_convert_ctx); + movie->img_convert_ctx=NULL; + } + } + /* close each stream */ + if (movie->audio_stream >= 0) + { + stream_component_close(movie, movie->audio_stream, threaded); + } + if (movie->video_stream >= 0) + { + stream_component_close(movie, movie->video_stream, threaded); + } +#if 0 + if (movie->sub_stream >= 0) + { + stream_component_close(movie, movie->sub_stream, threaded); + } +#endif + if (movie->ic) + { + av_close_input_file(movie->ic); + movie->ic = NULL; /* safety */ + } + + if(movie->ob_refcnt!=0) + { + if(threaded) + { + GRABGIL + } + Py_DECREF(movie); + if(threaded) + { + RELEASEGIL + } + } +} + +void stream_cycle_channel(PyMovie *movie, int codec_type) +{ + AVFormatContext *ic = movie->ic; + int start_index=0; + int stream_index; + AVStream *st; + DECLAREGIL + GRABGIL + Py_INCREF(movie); + RELEASEGIL + + if (codec_type == CODEC_TYPE_VIDEO) + start_index = movie->video_stream; + else if (codec_type == CODEC_TYPE_AUDIO) + start_index = movie->audio_stream; + stream_index = start_index; + for(;;) + { + if (++stream_index >= movie->ic->nb_streams) + { + stream_index = 0; + } + if (stream_index == start_index) + return; + st = ic->streams[stream_index]; + if (st->codec->codec_type == codec_type) + { + /* check that parameters are OK */ + switch(codec_type) + { + case CODEC_TYPE_AUDIO: + if (st->codec->sample_rate != 0 && + st->codec->channels != 0) + goto the_end; + break; + case CODEC_TYPE_VIDEO: + default: + break; + } + } + } +the_end: + stream_component_close(movie, start_index, 1); + stream_component_open(movie, stream_index, 1); + GRABGIL + Py_DECREF(movie); + RELEASEGIL +} + +int decoder_wrapper(void *arg) +{ + PyMovie *movie = arg; + DECLAREGIL + GRABGIL + Py_INCREF(movie); + RELEASEGIL + int state=0; + int eternity =0; + if(movie->loops==-1) + { + eternity=1; + } + while((movie->loops>-1||eternity) && !movie->stop ) + { + movie->loops--; + movie->paused=0; + //we have to (re)initialize the context when we start over. Most efficient way really. + if(movie->replay) + initialize_context(movie, 1); + /*starting a stream is different from opening it. + * *nix weenies see that they are the same, when really, they're not. + * In this case, starting a stream means we set all the values and stuff we need + * to play it as if it had just started, like initial time values, etc. + */ + + if(movie->video_st) + stream_component_start(movie, movie->video_stream, 1); + if(movie->audio_st) + stream_component_start(movie, movie->audio_stream, 1); +#if 0 + + if(movie->sub_st) + stream_component_start(movie, movie->sub_stream, 1); +#endif + /* Now we call the function that does the ACTUAL work. Just like us to loaf + * around while we make decoder work so hard... + */ + state =decoder(movie); + /* We've returned... for any number of reasons, like stopping, we're finished + * or as an omen of the impending apocalypse. I recommend you use the + * necronomicon to diagnose this. + * + * And now, we need to end a stream. Again, this is different from closing a stream. + * This just sets various variables and structs to their ended state, but they're still + * ready to be started again. We only close streams when we dealloc the movie. We want + * to be able to reuse the memory. Every memory page we reuse is another + * electronic tree saved! + */ + if(movie->video_st) + stream_component_end(movie, movie->video_st->index, 1); + if(movie->audio_st) + stream_component_end(movie, movie->audio_st->index, 1); +#if 0 + + if(movie->sub_st) + stream_component_end(movie, movie->sub_st->index, 1); +#endif + + if(movie->stop) + { + VidPicture *vp; + + int i; + for( i =0; i<VIDEO_PICTURE_QUEUE_SIZE; i++) + { + vp = &movie->pictq[i]; + if (vp->dest_overlay) + { + SDL_FreeYUVOverlay(vp->dest_overlay); + vp->dest_overlay = NULL; + } + if(vp->dest_surface) + { + SDL_FreeSurface(vp->dest_surface); + vp->dest_surface=NULL; + } + + } + /*if (SDL_WasInit (SDL_INIT_VIDEO)) + SDL_QuitSubSystem (SDL_INIT_VIDEO);*/ + } + if(state==-1) + { + if(PyErr_Occurred()) + { + PyErr_Print(); + } + break; + } + } + GRABGIL + Py_DECREF(movie); + RELEASEGIL + movie->playing=0; + movie->paused=0; + return state; +} + +int decoder(void *arg) +{ + /* This is the most-hardworking function in the entire module. So respect it! + * He's the blue collar worker amongst the white-collar data pushing functions. There's + * a few other blue collar functions, but decoder is boss o' them all. + * + * Here's decoder's work schedule: + * loop: + * checks status + * deals with seeking + * handles eofs and stuff + * read frame + * load frame into A/V queue + * video_render() + * //audio_thread() + * first two loops: + * video_refresh_timer <--- we do this or else we'd never start display frames + * if timing AND timing >=now: + * video_display + * + * And thats it! decoder does this till it ends. Then it cleans some stuff up, and exits gracefully for most any situation. + */ + PyMovie *movie = arg; + DECLAREGIL + GRABGIL +#ifdef PROFILE + if(movie->istats==NULL) + movie->istats = (ImageScaleStats *)PyMem_Malloc(sizeof(ImageScaleStats)); +#endif + + Py_INCREF( movie); + RELEASEGIL + AVFormatContext *ic; + int ret; + AVPacket pkt1, *pkt = &pkt1; + movie->stop=0; + movie->finished =0; + movie->playing=1; + ic=movie->ic; + int co=0; + int video_packet=0; + //we do video open as a batch, instead of on-demand. Much better performance that way. + video_open(movie, 0); + movie->last_showtime = av_gettime()/1000.0; + int seeking =0; + for(;;) + { + if(hasCommand(movie->commands) && !movie->working) + { + Command *comm = getCommand(movie->commands); + + if(comm->type==movie->seekCommandType) + { + seekCommand *seek = (seekCommand *)comm; + movie->seek_req=1; + movie->seek_pos = seek->pos; + movie->seek_flags |= seek->rel; + /* clear stuff away now */ + comm = NULL; + PyMem_Free(seek); + movie->working=1; + } + else if(comm->type==movie->pauseCommandType) + { + pauseCommand *pause = (pauseCommand *)comm; + movie->paused = !movie->paused; + movie->working = movie->paused; + if (!movie->paused) + { + movie->video_current_pts = get_video_clock(movie); + movie->frame_timer += (av_gettime() - movie->video_current_pts_time) / 1000000.0; + } + comm=NULL; + PyMem_Free(pause); + } + else if (comm->type ==movie->stopCommandType) + { + stopCommand *stop = (stopCommand *)comm; + movie->stop=1; + comm=NULL; + PyMem_Free(stop); + movie->working=1; + } + else if (comm->type == movie->resizeCommandType) + { + resizeCommand *resize=(resizeCommand *)comm; + if (resize->h!=0) + { + movie->resize_h=1; + movie->height=resize->h; + } + if(resize->w!=0) + { + movie->resize_w=1; + movie->width= resize->w; + } + comm=NULL; + PyMem_Free(resize); + video_open(movie, 0); + } + else if (comm->type == movie->shiftCommandType) + { + shiftCommand *shift = (shiftCommand *)comm; + + movie->xleft=shift->xleft; + movie->ytop=shift->ytop; + comm=NULL; + PyMem_Free(shift); + video_open(movie, 0); + } + else if(comm->type == movie->surfaceCommandType) + { + surfaceCommand *surf = (surfaceCommand *)comm; + if(movie->canon_surf) + { + SDL_FreeSurface(movie->canon_surf); + movie->canon_surf=NULL; + } + if(surf->surface) + { + movie->canon_surf=surf->surface; + movie->overlay=0; + } + else + { + movie->overlay=1; + } + + } + + } + + if (movie->abort_request) + { + break; + } + if(movie->stop) + { + break; + } + if (movie->paused != movie->last_paused) + { + movie->last_paused = movie->paused; + if (movie->paused) + { + av_read_pause(ic); + } + else + { + movie->last_showtime=av_gettime()/1000.0; + av_read_play(ic); + } + } + if(movie->paused) + { + SDL_Delay(10); + continue; + } + if (movie->seek_req) + { + movie->working=0; + int64_t seek_target= movie->seek_pos; + seek_target-=1*AV_TIME_BASE; + int aud_stream_index=-1; + int vid_stream_index=-1; + int64_t vid_seek_target=seek_target; + if (movie->video_stream >= 0) + { + vid_stream_index= movie->video_stream; + } + else if (movie->audio_stream >=0) + { + aud_stream_index = movie->audio_stream; + } + if(vid_stream_index>=0) + vid_seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, ic->streams[vid_stream_index]->time_base); + + if(vid_stream_index>=0) + { + if(vid_seek_target > movie->video_st->duration) + { + vid_seek_target = vid_seek_target%movie->video_st->duration; + } + ret = av_seek_frame(movie->ic, vid_stream_index, vid_seek_target, movie->seek_flags); + + if (ret < 0) + { + PyErr_Format(PyExc_IOError, "%s: error while seeking", movie->ic->filename); + } + } + if (movie->video_stream >= 0) + { + packet_queue_flush(&movie->videoq); + packet_queue_put(&movie->videoq, &flush_pkt); + } + if (movie->audio_stream >= 0) + { + packet_queue_flush(&movie->audioq); + packet_queue_put(&movie->audioq, &flush_pkt); + seeking=1; + + } + + movie->seek_req = 0; + //now we need to seek to a keyframe... + if(ic->streams[vid_stream_index]->duration>0) + { + while(av_read_frame(ic, pkt)>=0) + { + if(pkt->stream_index == movie->video_stream) + { + int bytesDecoded, frameFinished; + AVFrame *frame; + frame=avcodec_alloc_frame(); + bytesDecoded = avcodec_decode_video(movie->video_st->codec, frame, &frameFinished, pkt->data, pkt->size); + if(frameFinished) + { + if((pkt->pts >= vid_seek_target) || (pkt->dts >= vid_seek_target)) + { + av_free(frame); + break; + } + } + av_free(frame); + } + av_free_packet(pkt); + } + av_free_packet(pkt); + } + + } + /* if the queue are full, no need to read more */ + if ( //yay for short circuit logic testing + (movie->videoq.size > MAX_VIDEOQ_SIZE )) + { + /* wait 10 ms */ + if(!movie->paused) + { + //we only forcefully pull a packet of the queues when the queue is too large and the video file is not paused. + // The simple reason is that video_render and audio_thread do nothing, so its a waste of cycles to call them otherwise + if(movie->videoq.size > MAX_VIDEOQ_SIZE && movie->video_st) + { + video_render(movie); + } + } + continue; + } +#if LIBAVCODEC_VERSION_INT>=3412992 //(52<<16)+(20<<8)+0 ie 52.20.0 + if(url_feof(ic->pb)) + { + av_init_packet(pkt); + pkt->data=NULL; + pkt->size=0; + pkt->stream_index= movie->video_stream; + packet_queue_put(&movie->videoq, pkt); + continue; + } +#endif + if(movie->pictq_size<VIDEO_PICTURE_QUEUE_SIZE) + { + ret = av_read_frame(ic, pkt); + if (ret < 0) + { +#if LIBAVCODEC_VERSION_INT>=3412992 + if (ret != AVERROR_EOF && url_ferror(ic->pb) == 0) + { + goto fail; + } + else + { + break; + } +#else + goto fail; +#endif + } + if (pkt->stream_index == movie->audio_stream) + { + if(seeking) + { + seekBuffer(pkt->pts); + seeking=0; + } + packet_queue_put(&movie->audioq, pkt); + + } + else if (pkt->stream_index == movie->video_stream) + { + packet_queue_put(&movie->videoq, pkt); + video_packet=1; + } +#if 0 + else if (pkt->stream_index == movie->sub_stream) + { + packet_queue_put(&movie->subq, pkt); + } +#endif + else if(pkt) + { + av_free_packet(pkt); + } + } +#if 0 + SubPicture *sp; + SubPicture *sp2; + if(movie->sub_stream>=0) + { + if (movie->sub_stream_changed) + { + SDL_LockMutex(movie->subpq_mutex); + + while (movie->subpq_size) + { + free_subpicture(&movie->subpq[movie->subpq_rindex]); + + // update queue size and signal for next picture + if (++movie->subpq_rindex == SUBPICTURE_QUEUE_SIZE) + movie->subpq_rindex = 0; + + movie->subpq_size--; + } + movie->sub_stream_changed = 0; + + SDL_UnlockMutex(movie->subpq_mutex); + } + else + { + if (movie->subpq_size > 0) + { + sp = &movie->subpq[movie->subpq_rindex]; + + if (movie->subpq_size > 1) + sp2 = &movie->subpq[(movie->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE]; + else + sp2 = NULL; + + if ((movie->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000))) + || (sp2 && movie->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000)))) + { + free_subpicture(sp); + + // update queue size and signal for next picture + if (++movie->subpq_rindex == SUBPICTURE_QUEUE_SIZE) + movie->subpq_rindex = 0; + + SDL_LockMutex(movie->subpq_mutex); + movie->subpq_size--; + SDL_UnlockMutex(movie->subpq_mutex); + } + } + } + } +#endif + + if(movie->video_st && video_packet) + { + video_render(movie); + video_packet=0; + } + /*This is very important: without this if check, + * The video frames will not be displayed, ever. */ + if(co<1) + movie->timing=40; + co++; + + if(movie->timing>0) + { + /* Here, we check if the current time in milliseconds exceeds the scheduled time + * and if so, we display the frame. */ + double showtime = movie->timing+movie->last_showtime; + double now = av_gettime()/1000.0; + if(now >= showtime) + { + double temp = movie->timing; + double temp_showtime = movie->last_showtime; + movie->timing =0; + + if(!video_display(movie)) + { + //we do this because we haven't shown a frame yet, so we need to preserve the timings, etc. + // other we end up with slowdowns and speedups. Not good! + movie->timing=temp; + movie->last_showtime=temp_showtime; + } + else + { + movie->last_showtime = av_gettime()/1000.0; + } + } + } + + } + + ret = 0; +fail: + + if(ret!=0) + { + GRABGIL + RAISE(PyExc_Exception, "Something went wrong, so I'm throwing this error."); + RELEASEGIL + movie->abort_request=1; + } + movie->pictq_size=movie->pictq_rindex=movie->pictq_windex=0; + packet_queue_flush(&movie->videoq); + movie->finished=1; + movie->working=0; + GRABGIL +#ifdef PROFILE + //mean + int64_t sum =0; + int64_t max = 0; + int64_t min = 2<<24; + TimeSampleNode *cur = movie->istats->first; + while(cur!=NULL) + { + sum+= cur->sample; + if(cur->sample>max) + max=cur->sample; + if(cur->sample<min) + min=cur->sample; + if(cur->next==NULL) + break; + cur=cur->next; + } + movie->istats->mean = (double)sum/movie->istats->n_samples; + movie->istats->max = max; + movie->istats->min = min; + double total = 0; + double mean = movie->istats->mean; + cur = movie->istats->first; + while(cur->next!=NULL) + { + total+= pow(((double)cur->sample-mean), (double)2); + cur=cur->next; + } + movie->istats->stdev = sqrt(total/mean); + PySys_WriteStdout("# Samples: %i\nMean: %f\nMin: %i\nMax: %i\nStDev: %f\n", (int)movie->istats->n_samples, mean, (int)min, (int)max, movie->istats->stdev); + cur = movie->istats->first; + TimeSampleNode *prev; + while(cur->next!=NULL) + { + prev=cur; + cur=cur->next; + PyMem_Free(prev); + } + movie->istats->first=NULL; + movie->istats->last=NULL; + movie->istats->n_samples=0; +#endif + + Py_DECREF( movie); + RELEASEGIL + movie->playing=0; + if(movie->abort_request) + { + return -1; + } + return 0; +} + +int video_render(PyMovie *movie) +{ + /* Video render function. Only executed when there is a packet to decode. + * Here, we get the packet, check it, decode the packet, and queue it up. + */ + AVPacket pkt1, *pkt = &pkt1; + int len1, got_picture; + AVFrame *frame= avcodec_alloc_frame(); + double pts; + + do + { + + if (movie->paused && !movie->videoq.abort_request) + { + break; + } + if (packet_queue_get(&movie->videoq, pkt, 0) <=0) + break; + + if(pkt->data == flush_pkt.data) + { + avcodec_flush_buffers(movie->video_st->codec); + continue; + } + + /* NOTE: ipts is the PTS of the _first_ picture beginning in + this packet, if any */ + int64_t opaque; +#if LIBAVCODEC_VERSION_INT<3412992 //(52<<16)+(20<<8)+0 ie 52.20.0 + opaque=pkt->pts; +#else + movie->video_st->codec->reordered_opaque= pkt->pts; +#endif + len1 = avcodec_decode_video(movie->video_st->codec, + frame, &got_picture, + pkt->data, pkt->size); +#if LIBAVCODEC_VERSION_INT<3412992 + if((pkt->dts == AV_NOPTS_VALUE)) //(52<<16)+(20<<8)+0 ie 52.20.0 + { + //due to short circuiting this checks first, then if that fails it does the invalid old checks. :) + pts=opaque; + } +#else + if(( pkt->dts == AV_NOPTS_VALUE) && (frame->reordered_opaque != AV_NOPTS_VALUE)) + { + pts= frame->reordered_opaque; + } +#endif + else if(pkt->dts != AV_NOPTS_VALUE) + { + pts= pkt->dts; + } + else + { + pts= 0; + } + pts *= av_q2d(movie->video_st->time_base); + + if (got_picture) + { + update_video_clock(movie, frame, pts); + if (queue_picture(movie, frame) < 0) + { + goto the_end; + } + } + av_free_packet(pkt); + av_free(frame); + } + while(0); + +the_end: + return 0; +} +#if 0 +int subtitle_render(void *arg) +{ + PyMovie *movie = arg; + DECLAREGIL + GRABGIL + Py_INCREF(movie); + RELEASEGIL + SubPicture *sp; + AVPacket pkt1, *pkt = &pkt1; + int len1, got_subtitle; + double pts; + int i, j; + int r, g, b, y, u, v, a; + int co; + + for(co=0;co<2;co++) + { + if (movie->paused && !movie->subq.abort_request) + { + SDL_Delay(10); + goto the_end; + } + if (packet_queue_get(&movie->subq, pkt, 1) < 0) + break; + + if(pkt->data == flush_pkt.data) + { + avcodec_flush_buffers(movie->sub_st->codec); + goto the_end; + } + SDL_LockMutex(movie->subpq_mutex); + if (movie->subpq_size >= SUBPICTURE_QUEUE_SIZE && + !movie->subq.abort_request) + { + SDL_UnlockMutex(movie->subpq_mutex); + goto the_end; + } + SDL_UnlockMutex(movie->subpq_mutex); + + if (movie->subq.abort_request) + goto the_end; + + sp = &movie->subpq[movie->subpq_windex]; + + /* NOTE: ipts is the PTS of the _first_ picture beginning in + this packet, if any */ + pts = 0; + if (pkt->pts != AV_NOPTS_VALUE) + pts = av_q2d(movie->sub_st->time_base)*pkt->pts; + + len1 = avcodec_decode_subtitle(movie->sub_st->codec, + &sp->sub, &got_subtitle, + pkt->data, pkt->size); + if (got_subtitle && sp->sub.format == 0) + { + sp->pts = pts; + + for (i = 0; i < sp->sub.num_rects; i++) + { + for (j = 0; j < sp->sub.rects[i]->nb_colors; j++) + { + RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j); + y = RGB_TO_Y_CCIR(r, g, b); + u = RGB_TO_U_CCIR(r, g, b, 0); + v = RGB_TO_V_CCIR(r, g, b, 0); + YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a); + } + } + + /* now we can update the picture count */ + if (++movie->subpq_windex == SUBPICTURE_QUEUE_SIZE) + movie->subpq_windex = 0; + SDL_LockMutex(movie->subpq_mutex); + movie->subpq_size++; + SDL_UnlockMutex(movie->subpq_mutex); + } + av_free_packet(pkt); + } +the_end: + GRABGIL + Py_DECREF(movie); + RELEASEGIL + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/_gmovie.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,466 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + * _movie - movie support for pygame with ffmpeg + * Author: Tyler Laing + * + * This module allows for the loading of, playing, pausing, stopping, and so on + * of a video file. Any format supported by ffmpeg is supported by this + * video player. Any bugs, please email trinioler@gmail.com :) + */ + + +#ifndef _GMOVIE_H_ +#define _GMOVIE_H_ + +/* local includes */ +#include "doc/_movie_doc.h" +#include "pygame.h" +#include "pgcompat.h" +#include "surface.h" +#include "_gsound.h" +#include "structmember.h" +#include "_gcommand.h" + +/* Library includes */ +/* This is as small as I could make it... */ +#include <Python.h> +#include <SDL.h> +#include <SDL_thread.h> +#include <avformat.h> +#include <swscale.h> + + +/*constant definitions */ +#define MAX_VIDEOQ_SIZE (5 * 256 * 1024) +#define MAX_AUDIOQ_SIZE (5 * 16 * 1024) +#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024) + +/* no AV sync correction is done if below the AV sync threshold */ +#define AV_SYNC_THRESHOLD 0.01 +/* no AV correction is done if too big error */ +#define AV_NOSYNC_THRESHOLD 10.0 + +//sets the module to single-thread mode. +#define THREADFREE 0 + +/*Thread management macros to save me a load of typing...*/ +#if THREADFREE!=1 + #define DECLAREGIL PyThreadState *_oldtstate; + #define GRABGIL PyEval_AcquireLock();_oldtstate = PyThreadState_Swap(movie->_tstate); + #define RELEASEGIL PyThreadState_Swap(_oldtstate); PyEval_ReleaseLock(); +#else + #define DECLAREGIL + #define GRABGIL + #define RELEASEGIL +#endif + +/* Used to indicate when to flush the queues for seeking */ +AVPacket flush_pkt; + +/* Queues for already-loaded pictures, for rapid display */ +#define VIDEO_PICTURE_QUEUE_SIZE 2 +#define SUBPICTURE_QUEUE_SIZE 4 +/* RGB24 or RGBA... */ +/* In this case I've chosen RGB24 because its smaller */ +#define RGB24 1 +#define RGBA 0 + +#if RGB24 + #define RGBSTEP 3 +#else + #define RGBSTEP 4 +#endif + +#define BPP 1 + +//enables profiling info to be gathered +//#define PROFILE 1 + +#ifdef PROFILE +#include <math.h> + typedef struct TimeSampleNode + { + int64_t sample; + struct TimeSampleNode *next; + }TimeSampleNode; + typedef struct ImageScaleStats + { + double mean; + int64_t max; + int64_t min; + double stdev; + double median; + double firstqu; + double thirdqu; + double serror; + int64_t n_samples; + struct TimeSampleNode *first; + struct TimeSampleNode *last; + }ImageScaleStats; +#endif +//included from ffmpeg header files, as the header file is not publically available. +#if defined(__ICC) || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n))) + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__GNUC__) + #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n))) + #define DECLARE_ASM_CONST(n,t,v) static const t v attribute_used __attribute__ ((aligned (n))) +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#elif HAVE_INLINE_ASM + #error The asm code needs alignment, but we do not know how to do it for this compiler. +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) + +#define RGB_TO_Y_CCIR(r, g, b) \ +((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ + FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ +(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ + FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define _ALPHA_BLEND(a, oldp, newp, s)\ +((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s)) + +#define RGBA_IN(r, g, b, a, s)\ +{\ + unsigned int v = ((const uint32_t *)(s))[0];\ + a = (v >> 24) & 0xff;\ + r = (v >> 16) & 0xff;\ + g = (v >> 8) & 0xff;\ + b = v & 0xff;\ +} + +#define YUVA_IN(y, u, v, a, s, pal)\ +{\ + unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\ + a = (val >> 24) & 0xff;\ + y = (val >> 16) & 0xff;\ + u = (val >> 8) & 0xff;\ + v = val & 0xff;\ +} + +#define YUVA_OUT(d, y, u, v, a)\ +{\ + ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\ +} + + +/* structure definitions */ +/* PacketQueue to hold incoming ffmpeg packets from the stream */ +typedef struct PacketQueue +{ + AVPacketList *first_pkt, *last_pkt; + int nb_packets; + int size; + int abort_request; + SDL_mutex *mutex; +} +PacketQueue; + +/* Holds already loaded pictures, so that decoding, and writing to a overlay/surface can happen while waiting + * the <strong> very </strong> long time(in computer terms) to show the next frame. + */ +typedef struct VidPicture +{ + SDL_Overlay *dest_overlay; /* Overlay for fast speedy yuv-rendering of the video */ + SDL_Surface *dest_surface; /* Surface for other desires, for example, rendering a video in a small portion of the screen */ + SDL_Rect dest_rect; /* Dest-rect, which tells where to locate the video */ + int width; /* Width and height */ + int height; + int xleft; /* Where left border of video is located */ + int ytop; /* Where top border of video is located */ + int overlay; /* Whether or not to use the overlay */ + int ready; /* Boolean to indicate this picture is ready to be used. After displaying the contents, it changes to False */ + double pts; /* presentation time-stamp of the picture */ +} +VidPicture; + +#if 0 +typedef struct SubPicture +{ + double pts; + AVSubtitle sub; +} SubPicture; +#endif +enum { + AV_SYNC_AUDIO_MASTER, /* default choice */ + AV_SYNC_VIDEO_MASTER, + AV_SYNC_SUB_MASTER, + AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */ +}; + +typedef struct PyMovie +{ + PyObject_HEAD + /* General purpose members */ + SDL_Thread *parse_tid; /* Thread id for the decode_thread call */ + int abort_request; /* Tells whether or not to stop playing and return */ + int paused; /* Boolean for communicating to the threads to pause playback */ + int last_paused; /* For comparing the state of paused to what it was last time around. */ + int working; + char filename[1024]; + char *_backend; //"FFMPEG_WRAPPER"; + int overlay; //>0 if we are to use the overlay, otherwise <=0 + int playing; + int height; + int width; + int ytop; //For use with SDL_Rect + int xleft; + int loops; //Number of times to play the video + int resize_h; //Indicator values that we have resized the video screen from the default + int resize_w; + int replay; //we've played this once before, we're playing it again. + AVInputFormat *iformat; //Format of the file + SDL_mutex *dest_mutex; //mutex to control access to important info + int av_sync_type; //determines the clock type we use + AVFormatContext *ic; /* context information about the format of the video file */ + int stop; //whether we're in a stop state... + SDL_Surface *canon_surf; //pointer to the surface given by the programmer. We do NOT free this... it is not ours. We just write to it. + PyThreadState *_tstate; //really do not touch this unless you have to. This is used for threading control and primitives. + int finished; + int skip_frame; + + /* command queue stuff */ + CommandQueue *commands; + int seekCommandType; + int pauseCommandType; + int stopCommandType; + int resizeCommandType; + int shiftCommandType; + int surfaceCommandType; + int diff_co; //counter + + /* Seek-info */ + int seek_req; + int seek_flags; + int64_t seek_pos; + int64_t start_time; //used for seeking + + /* external clock members */ + double external_clock; /* external clock base */ + int64_t external_clock_time; + + /* Audio stream members */ + double audio_clock; + AVStream *audio_st; //audio stream struct + PacketQueue audioq; //audio packets + /* samples output by the codec. we reserve more space for avsync compensation */ + DECLARE_ALIGNED(16,uint8_t,audio_buf1[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]); + uint8_t *audio_buf; //pointer to a buffer + AVPacket audio_pkt; //current packet + uint8_t *audio_pkt_data; //current packet data + int audio_pkt_size; //current packet size + int64_t audio_pts; + //int audio_volume; /*must self implement*/ + enum SampleFormat audio_src_fmt; + //AVAudioConvert *reformat_ctx; + int audio_stream; + int audio_disable; + SDL_mutex *audio_mutex; + SDL_Thread *audio_tid; + int channel; + int audio_paused; + + /* Frame/Video Management members */ + double frame_timer; + double frame_last_pts; + double frame_last_delay; + double frame_delay; /*display time of each frame, based on fps*/ + double video_clock; /*seconds of video frame decoded*/ + AVStream *video_st; + double video_current_pts; /* current displayed pts (different from + video_clock if frame fifos are used) */ + double video_current_pts_time; + double timing; + double last_showtime; + double pts; + int video_stream; + int video_disable; + /* simple ring_buffer queue for holding VidPicture structs */ + VidPicture pictq[VIDEO_PICTURE_QUEUE_SIZE]; + int pictq_size, pictq_windex, pictq_rindex; + + /* Thread id for the video_thread, when used in threaded mode */ + SDL_Thread *video_tid; + + PacketQueue videoq; + SDL_mutex *videoq_mutex; + SDL_cond *videoq_cond; + struct SwsContext *img_convert_ctx; +#if 0 + /*subtitle */ + int sub_stream; + int sub_stream_changed; + AVStream *sub_st; + PacketQueue subq; + SubPicture subpq[SUBPICTURE_QUEUE_SIZE]; + int subpq_rindex, subpq_windex, subpq_size; + SDL_mutex *subpq_mutex; + int subtitle_disable; +#endif +#ifdef PROFILE + ImageScaleStats *istats; +#endif + +} +PyMovie; + +typedef struct PyMovieInfo +{ + PyObject_HEAD + /* General purpose members */ + double duration; //check + int width;//check + int height;//check + int sample_rate;//check + int channels;//check + char *vid_codec;//check + char *aud_codec;//check + char *filename;//check + double aspect_ratio;//check +} PyMovieInfo; + + + +/*command definitions */ +typedef struct seekCommand +{ + FULL_COMMAND + int64_t pos; + int rel; +} seekCommand; + + +typedef struct pauseCommand +{ + FULL_COMMAND +} pauseCommand; + +typedef struct stopCommand +{ + FULL_COMMAND +} stopCommand; + +typedef struct resizeCommand +{ + FULL_COMMAND + int h; + int w; +} resizeCommand; + +typedef struct shiftCommand +{ + FULL_COMMAND + int barrier; + int ytop; + int xleft; +} shiftCommand; + +typedef struct surfaceCommand +{ + FULL_COMMAND + SDL_Surface *surface; +} surfaceCommand; + +/* end of struct definitions */ +/* function definitions */ + +/* PacketQueue Management */ +void packet_queue_init (PacketQueue *q); +void packet_queue_flush (PacketQueue *q); +void packet_queue_end (PacketQueue *q, int end); +int packet_queue_put (PacketQueue *q, AVPacket *pkt); +void packet_queue_abort (PacketQueue *q); +int packet_queue_get (PacketQueue *q, AVPacket *pkt, int block); + +/* Misc*/ +int initialize_context (PyMovie *movie, int threaded); +int initialize_codec (PyMovie *movie, int stream_index, int threaded); +/* Video Management */ +int video_open (PyMovie *is, int index); +int video_image_display (PyMovie *is); +int video_display (PyMovie *is); +int video_render (PyMovie *movie); +int queue_picture (PyMovie *is, AVFrame *src_frame); +void update_video_clock (PyMovie *movie, AVFrame* frame, double pts); +void video_refresh_timer (PyMovie *movie); //unlike in ffplay, this does the job of compute_frame_delay + +/* Audio management */ +int synchronize_audio (PyMovie *is, short *samples, int samples_size1, double pts); +int audio_decode_frame (PyMovie *is, double *pts_ptr); + +/* General Movie Management */ +void stream_seek (PyMovie *is, int64_t pos, int rel); +void stream_pause (PyMovie *is); +int stream_component_open (PyMovie *is, int stream_index, int threaded); //TODO: break down into separate functions +int stream_component_start (PyMovie *is, int stream_index, int threaded); +void stream_component_end (PyMovie *is, int stream_index, int threaded); +void stream_component_close (PyMovie *is, int stream_index, int threaded); +int decoder (void *arg); +void stream_open (PyMovie *is, const char *filename, AVInputFormat *iformat, int threaded); +void stream_close (PyMovie *is, int threaded); +void stream_cycle_channel (PyMovie *is, int codec_type); +int decoder_wrapper (void *arg); + +/* Clock Management */ +double get_audio_clock (PyMovie *is); +double get_video_clock (PyMovie *is); +double get_external_clock (PyMovie *is); +double get_master_clock (PyMovie *is); + +/* Command management */ +void registerCommands(PyMovie *movie); + +/* MovieInfo management*/ +int _info_init(PyObject *self, PyObject *args, PyObject *kwds); +void _info_init_internal(PyMovieInfo *self, const char *filename); +void _info_dealloc(PyMovieInfo *info); +PyObject* _info_get_duration (PyMovieInfo *info, void *closure); +PyObject* _info_get_aspect_ratio (PyMovieInfo *info, void *closure); +PyObject* _info_get_width (PyMovieInfo *info, void *closure); +PyObject* _info_get_height (PyMovieInfo *info, void *closure); +PyObject* _info_get_sample_rate(PyMovieInfo *info, void *closure); +PyObject* _info_get_channels(PyMovieInfo *info, void *closure); +PyObject* _info_get_video_codec(PyMovieInfo *info, void *closure); +PyObject* _info_get_audio_codec(PyMovieInfo *info, void *closure); +PyObject* _info_get_filename(PyMovieInfo *info, void *closure); + + +#if 0 +/* Subtitle Management*/ +int subtitle_render(void *arg); +void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh); +void free_subpicture(SubPicture *sp); +#endif +#endif /*_GMOVIE_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/_gsound.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,428 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + * _movie - movie support for pygame with ffmpeg + * Author: Tyler Laing + * + * This module allows for the loading of, playing, pausing, stopping, and so on + * of a video file. Any format supported by ffmpeg is supported by this + * video player. Any bugs, please email trinioler@gmail.com :) + */ + +/* Sound module: + * We use SDL_mixer to manage things, and provide a simple callback. + * The interface is simple, to avoid the mess of dealing with sound and + * channel management within _gmovie.c which was getting long enough as it was. + */ + +#include "_gsound.h" + +/* Default values if none given */ +#define _MIXER_DEFAULT_FREQUENCY 22050 +#define _MIXER_DEFAULT_SIZE -16 +#define _MIXER_DEFAULT_CHANNELS 2 +#define _MIXER_DEFAULT_CHUNKSIZE 4096 + +/* queue management functions */ +int queue_get(BufferQueue *q, BufferNode **pkt1) +{ + int ret; + SDL_mutexP(q->mutex); //lock + for(;;) + { + *pkt1 = q->first; + if (*pkt1) + { + q->first = (*pkt1)->next; + if (!q->first) + q->last = NULL; + q->size--; + ret = 1; + break; + } + else + { + ret=0; + break; + } + } + SDL_mutexV(q->mutex);//unlock + return ret; +} + +int queue_put(BufferQueue *q, BufferNode *pkt) +{ + if (!pkt) + return -1; + SDL_mutexP(q->mutex); //lock + pkt->next = NULL; + if (!q->last) + q->first = pkt; + else + q->last->next = pkt; + q->last = pkt; + q->size++; + SDL_mutexV(q->mutex);//unlock + return 0; +} +void queue_flush(BufferQueue *q) +{ + while(q->size>0) + { + BufferNode *node; + queue_get(q, &node); + PyMem_Free(node->buf); + node->buf=NULL; //safety + PyMem_Free(node); + node=NULL;//safety + } +} + +/* SDL mixer callback function: + * The idea is to get the next sound sample played as quickly as possible. + * We free the last played chunk, then call playBufferQueue, explained ' + * below. + */ +void cb_mixer(int channel) +{ + Mix_Chunk *mix; + mix= Mix_GetChunk(channel); + if(mix->abuf) + PyMem_Free(mix->abuf); + if(mix) + PyMem_Free(mix); + playBufferQueue(channel); + +} + +//initialize the mixer audio subsystem, code cribbed from mixer.c +int soundInit (int freq, int size, int channels, int chunksize, double time_base) +{ + Uint16 fmt = 0; + int i; + + if (!freq) + { + freq = _MIXER_DEFAULT_FREQUENCY; + } + if (!size) + { + size = _MIXER_DEFAULT_SIZE; + } + if (!channels) + { + channels = _MIXER_DEFAULT_CHANNELS; + } + if (!chunksize) + { + chunksize = _MIXER_DEFAULT_CHUNKSIZE; + } + if (channels >= 2) + channels = 2; + else + channels = 1; + + switch (size) + { + case 8: + fmt = AUDIO_U8; + break; + case -8: + fmt = AUDIO_S8; + break; + case 16: + fmt = AUDIO_U16SYS; + break; + case -16: + fmt = AUDIO_S16SYS; + break; + default: + PyErr_Format(PyExc_ValueError, "unsupported size %i", size); + return -1; + } + + /*make chunk a power of 2*/ + for (i = 0; 1 << i < chunksize; ++i) + ; //yes, semicolon on for loop + if(1<<i >= 256) + chunksize = 1<<i; + else + { + chunksize=256; + } + if (!SDL_WasInit (SDL_INIT_AUDIO)) + { + + if (SDL_InitSubSystem (SDL_INIT_AUDIO) == -1) + return -1; + + if (Mix_OpenAudio (freq, fmt, channels, chunksize) == -1) + { + SDL_QuitSubSystem (SDL_INIT_AUDIO); + return -1; + } + + /* A bug in sdl_mixer where the stereo is reversed for 8 bit. + So we use this CPU hogging effect to reverse it for us. + Hopefully this bug is fixed in SDL_mixer 1.2.9 + printf("MIX_MAJOR_VERSION :%d: MIX_MINOR_VERSION :%d: MIX_PATCHLEVEL :%d: \n", + MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL); + */ + +#if MIX_MAJOR_VERSION>=1 && MIX_MINOR_VERSION>=2 && MIX_PATCHLEVEL<=8 + if(fmt == AUDIO_U8) + { + if(!Mix_SetReverseStereo(MIX_CHANNEL_POST, 1)) + { + /* We do nothing... because might as well just let it go ahead. */ + /* return RAISE (PyExc_SDLError, Mix_GetError()); + */ + } + } +#endif + + } + /* global struct initialization */ + ainfo = (AudioInfo *)PyMem_Malloc(sizeof(AudioInfo)); + ainfo->channel = 0; + ainfo->channels = channels; + ainfo->audio_clock=0.0; + ainfo->queue.size=0; + ainfo->queue.first=ainfo->queue.last=NULL; + ainfo->sample_rate=freq; + ainfo->mutex = SDL_CreateMutex(); + ainfo->queue.mutex = SDL_CreateMutex(); + ainfo->ended=1; + ainfo->time_base=time_base; + Mix_VolumeMusic (127); + + //ainfo->_tstate = _tstate; + return 0; +} + +/* basic sound quit routine */ +int soundQuit(void) +{ + if (SDL_WasInit (SDL_INIT_AUDIO)) + { + Mix_HaltMusic (); + queue_flush(&ainfo->queue); + Mix_ChannelFinished(NULL); + Mix_CloseAudio (); + SDL_QuitSubSystem (SDL_INIT_AUDIO); + } + return 0; +} + +/* basic sound start routine */ +int soundStart (void) +{ + Mix_ChannelFinished(&cb_mixer); + ainfo->ended=0; + ainfo->audio_clock =0.0; + ainfo->playing=0; + ainfo->channel=0; + ainfo->current_frame_size=1; + return 0; +} +/*basic sound end routine, used for pauses, the movie object ends, but the + * movie object isn't deallocated yet, etc */ +int soundEnd (void) +{ + ainfo->ended = 1; + ainfo->restart=1; + queue_flush(&ainfo->queue); + ainfo->queue.size=0; + return 0; +} + +/* Play a sound buffer, with a given length + * This will place the buffer on the queue, if a sound is already playing. + */ +int playBuffer (uint8_t *buf, uint32_t len, int channel, int64_t pts) +{ + //SDL_mutexP(ainfo->mutex); + Mix_Chunk *mix; + if(!ainfo->ended && (ainfo->queue.size>0||ainfo->playing)) + { + //not a callback call, so we copy the buffer into a buffernode and add it to the queue. + BufferNode *node; + node = (BufferNode *)PyMem_Malloc(sizeof(BufferNode)); + node->buf = (uint8_t *)PyMem_Malloc((size_t)len); + memcpy(node->buf, buf, (size_t)len); + node->len = len; + node->next =NULL; + node->pts = pts; + queue_put(&ainfo->queue, node); + //SDL_mutexV(ainfo->mutex); + if(ainfo->channel<0) + ainfo->channel=channel; + return ainfo->channel; + } + //regardless of 1st call, or a callback, we load the data from buf into a newly allocated block. + mix= (Mix_Chunk *)PyMem_Malloc(sizeof(Mix_Chunk)); + mix->allocated=1; + mix->abuf = (Uint8 *)PyMem_Malloc((size_t)len); + memcpy(mix->abuf, buf, len); + mix->alen = (Uint32 )len; + mix->volume = 127; + ainfo->playing = 1; + if(!ainfo->ended && len!=0) + { + int bytes_per_sec = ainfo->channels*ainfo->sample_rate*2; + ainfo->audio_clock+= (double) len/(double) bytes_per_sec; + + } + ainfo->current_frame_size =len; + int playing = Mix_Playing(channel); + if(playing) + { + return channel; + } + int ret = Mix_PlayChannel(channel, mix, 0); + ainfo->channel = ret; + return ret; +} + +int stopBuffer (int channel) +{ + queue_flush(&ainfo->queue); + return 0; +} + +void playBufferQueue(int channel) +{ + uint8_t *buf; + int len=0; + int64_t pts; + int playing = Mix_Playing(channel); + if (playing) + return; + if(!ainfo->ended && ainfo->queue.size<=0) + { + //callback call but when the queue is empty, so we just load a short empty sound. + buf = (uint8_t *) PyMem_Malloc((size_t)128); + memset(buf, 0, (size_t)128); + ainfo->current_frame_size=1; + len=128; + } + else if(!ainfo->ended && ainfo->queue.size>0) + { + //callback call, and convenienty enough, the queue has a buffer ready to go, so we copy it into buf + BufferNode *newNode; + queue_get(&ainfo->queue, &newNode); + if(!newNode) + { + return; + } + ainfo->current_frame_size=newNode->len; + pts=newNode->pts; + buf = (uint8_t *)newNode->buf; + ainfo->current_frame_size=newNode->len; + len=newNode->len; + PyMem_Free(newNode); + newNode=NULL; + } + + //we assume that if stopped is true, then + if(ainfo->ended && !buf) + { + //callback call but when the queue is empty, so we just load a short empty sound. + buf = (uint8_t *) PyMem_Malloc((size_t)1024); + memset(buf, 0, (size_t)1024); + ainfo->current_frame_size=1; + len=1024; + } + //regardless of 1st call, or a callback, we load the data from buf into a newly allocated block. + Mix_Chunk *mix; + mix= (Mix_Chunk *)PyMem_Malloc(sizeof(Mix_Chunk)); + mix->allocated=1; + mix->abuf = buf; + mix->alen = (Uint32 )len; + mix->volume = 127; + if(!ainfo->ended && len!=0) + { + int bytes_per_sec = ainfo->channels*ainfo->sample_rate*2; + ainfo->audio_clock+= (double) len/(double) bytes_per_sec; + } + ainfo->current_frame_size =len; + int chan = ainfo->channel; + + int ret = Mix_PlayChannel(chan, mix, 0); + ainfo->channel = ret; + return; +} + +int pauseBuffer(int channel) +{ + if(channel<=-1) + return 0; + int paused = Mix_Paused(channel); + if(paused) + { + ainfo->audio_clock=ainfo->old_clock; + ainfo->ended=0; + Mix_Resume(-1); + } + else + { + ainfo->old_clock = ainfo->audio_clock; + ainfo->ended=1; + Mix_Pause(-1); + } + return 0; +} + +int getPaused (int channel) +{ + if(channel<=-1) + return 0; + return Mix_Paused(channel); +} +int seekBuffer (double pts) +{ + /*we need to flush our buffer */ + queue_flush(&ainfo->queue); + if (pts != AV_NOPTS_VALUE) + { + ainfo->audio_clock = ainfo->time_base*pts; + } + //ainfo->ended=1; + return 1; +} + +int setCallback(void (*callback)(int channel)) +{ + Mix_ChannelFinished(callback); + return 1; +} + +double getAudioClock(void) +{ + int bytes_per_sec = ainfo->channels*ainfo->sample_rate*2; + double pts = ainfo->audio_clock; + pts -= (double) ainfo->current_frame_size/(double) bytes_per_sec; + return pts; +} + +int getBufferQueueSize(void) +{ + return ainfo->queue.size; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/_gsound.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,99 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + * _movie - movie support for pygame with ffmpeg + * Author: Tyler Laing + * + * This module allows for the loading of, playing, pausing, stopping, and so on + * of a video file. Any format supported by ffmpeg is supported by this + * video player. Any bugs, please email trinioler@gmail.com :) + */ + + +#ifndef _GSOUND_H_ +#define _GSOUND_H_ +#include <Python.h> +#include <SDL/SDL_mixer.h> +#include <SDL.h> +#include <SDL_thread.h> +#include <avformat.h> + + +/* Buffer Node for a simple FIFO queue of sound samples. */ +typedef struct BufferNode +{ + uint8_t *buf; + int len; + int64_t pts; + struct BufferNode + *next; +} +BufferNode; + +/* Queue Struct for handling sound samples. This enables one thread pushing + * samples onto the queue with minimal interruption of grabbing a sample off the queue + */ +typedef struct BufferQueue +{ + BufferNode *first, *last; + int size; + SDL_mutex *mutex; +} +BufferQueue; + +/* Audio Info Struct: holds various important info, like the clock, etc. */ +typedef struct AudioInfo +{ + double audio_clock; //keeps track of our PTS, in seconds + double old_clock; //for when the video is paused + int channels; //data for keeping track of the fraction of a second the current frame will take + int sample_rate; //'' + int current_frame_size; //'' + int pts; //current pts + int playing; //if we've started playing any buffers + int channel; //what channel the last buffer played on + int ended; //whether or not we've "ended", so we know to output silence. + int paused; + BufferQueue queue; //queue of our buffers + SDL_mutex *mutex; + //PyThreadState *_tstate; + int restart; + double time_base; +} +AudioInfo; + +/*Global pointer to audio info struct... means only one video at a time :/*/ +AudioInfo *ainfo; + +int soundInit (int freq, int size, int channels, int chunksize, double time_base); +int soundQuit (void); +int soundStart (void); +int soundEnd (void); +int playBuffer (uint8_t *buf, uint32_t len, int channel, int64_t pts); +int stopBuffer (int channel); +int pauseBuffer (int channel); +int getPaused (int channel); +double getAudioClock (void); +int getBufferQueueSize(void); +int seekBuffer (double pts); +int setCallback (void (*callback) (int channel)); +int resetAudioInfo(void); +void playBufferQueue(int channel); +#endif /*_GSOUND_H_*/
--- a/src/_numericsndarray.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/_numericsndarray.c Mon Nov 16 18:31:40 2009 +0000 @@ -21,7 +21,7 @@ */ #include "pygame.h" -#include "pygamedocs.h" +#include "doc/sndarray_doc.h" #include "mixer.h" #include "numeric_arrayobject.h" #include <SDL_byteorder.h>
--- a/src/_numericsurfarray.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/_numericsurfarray.c Mon Nov 16 18:31:40 2009 +0000 @@ -21,7 +21,7 @@ */ #include "pygame.h" -#include "pygamedocs.h" +#include "doc/surfarray_doc.h" #include "numeric_arrayobject.h" #include <SDL_byteorder.h>
--- a/src/base.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/base.c Mon Nov 16 18:31:40 2009 +0000 @@ -23,7 +23,7 @@ #define PYGAMEAPI_BASE_INTERNAL #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/pygame_doc.h" #include <signal.h>
--- a/src/bufferproxy.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/bufferproxy.c Mon Nov 16 18:31:40 2009 +0000 @@ -22,7 +22,6 @@ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" static PyObject* _bufferproxy_new (PyTypeObject *type, PyObject *args, PyObject *kwds);
--- a/src/camera.h Mon Nov 16 18:05:30 2009 +0000 +++ b/src/camera.h Mon Nov 16 18:31:40 2009 +0000 @@ -18,7 +18,7 @@ */ #include "pygame.h" -#include "pygamedocs.h" +#include "doc/camera_doc.h" #if defined(__unix__) #include <structmember.h> @@ -41,8 +41,22 @@ #include <linux/videodev.h> #include <linux/videodev2.h> +#elif defined(__APPLE__) + #include <QuickTime/QuickTime.h> + #include <QuickTime/Movies.h> + #include <QuickTime/ImageCompression.h> + #endif +/* some constants used which are not defined on non-v4l machines. */ +#ifndef V4L2_PIX_FMT_RGB24 + #define V4L2_PIX_FMT_RGB24 'RGB3' + #define V4L2_PIX_FMT_RGB444 'R444' + #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)) @@ -54,14 +68,13 @@ #define CAM_V4L 1 #define CAM_V4L2 2 -struct buffer -{ +struct buffer { void * start; size_t length; }; -typedef struct -{ +#if defined(__unix__) +typedef struct PyCameraObject { PyObject_HEAD char* device_name; int camera_type; @@ -77,6 +90,45 @@ int brightness; int fd; } PyCameraObject; +#elif defined(__APPLE__) +typedef struct PyCameraObject { + PyObject_HEAD + char* device_name; /* unieke name of the device */ + OSType pixelformat; + unsigned int color_out; + SeqGrabComponent component; /* A type used by the Sequence Grabber API */ + SGChannel channel; /* Channel of the Sequence Grabber */ + GWorldPtr gworld; /* Pointer to the struct that holds the data of the captured image */ + Rect boundsRect; /* bounds of the image frame */ + long size; /* size of the image in our buffer to draw */ + int hflip; + int vflip; + short depth; + struct buffer pixels; + //struct buffer tmp_pixels /* place where the flipped image in temporarly stored if hflip or vflip is true.*/ +} PyCameraObject; + +#else +/* generic definition. +*/ + +typedef struct PyCameraObject { + PyObject_HEAD + char* device_name; + int camera_type; + unsigned long pixelformat; + unsigned int color_out; + struct buffer* buffers; + unsigned int n_buffers; + int width; + int height; + int size; + int hflip; + int vflip; + int brightness; + int fd; +} PyCameraObject; +#endif /* internal functions for colorspace conversion */ void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace); @@ -88,9 +140,12 @@ unsigned long source, SDL_PixelFormat* format); void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format); void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format); -void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format); -void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format); -void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format); +void sbggr8_to_rgb (const void* src, void* dst, int width, int height, + SDL_PixelFormat* format); +void yuv420_to_rgb (const void* src, void* dst, int width, int height, + SDL_PixelFormat* format); +void yuv420_to_yuv (const void* src, void* dst, int width, int height, + SDL_PixelFormat* format); #if defined(__unix__) /* internal functions specific to v4l2 */ @@ -115,4 +170,24 @@ int v4l_open_device (PyCameraObject* self); int v4l_init_device(PyCameraObject* self); int v4l_start_capturing(PyCameraObject* self); +#elif defined(__APPLE__) +/* internal functions specific to mac */ +char** mac_list_cameras(int* num_devices); +int mac_open_device (PyCameraObject* self); +int mac_init_device(PyCameraObject* self); +int mac_close_device (PyCameraObject* self); +int mac_start_capturing(PyCameraObject* self); +int mac_stop_capturing (PyCameraObject* self); + +int mac_get_control(PyCameraObject* self, int id, int* value); +int mac_set_control(PyCameraObject* self, int id, int value); + +PyObject* mac_read_raw(PyCameraObject *self); +int mac_read_frame(PyCameraObject* self, SDL_Surface* surf); +int mac_camera_idle(PyCameraObject* self); +int mac_copy_gworld_to_surface(PyCameraObject* self, SDL_Surface* surf); + +void flip_image(const void* image, void* flipped_image, int width, int height, + short depth, int hflip, int vflip); + #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/camera_mac.m Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,414 @@ +// +// camera_mac.m +// +// Created by Werner Laurensse on 2009-05-28. +// Copyright (c) 2009 . All rights reserved. +// + +#import "camera.h" + + + +/* Flips the image array horizontally and/or vertically by reverse copying + * a 'depth' number of bytes to flipped_image.*/ +/* todo speed up... */ +void flip_image(const void* image, + void* flipped_image, + int width, int height, + short depth, + int hflip, int vflip) +{ + + if (!hflip && vflip) { + int i, j; + int width_size = width*depth; + const void* tmp_image = image; + + for(i=0; i<=height-1; i++) { + for(j=0; j<=width; j++) { + memcpy(flipped_image+width_size-j*depth-3, + tmp_image+j*depth, + depth); + } + tmp_image += width_size; + flipped_image += width_size; + } + } else if (hflip && !vflip) { + int i; + int width_size = width*depth; + void* tmp_image = flipped_image+width_size*height; + + for(i=0; i<height; i++) { + tmp_image -= width_size; + memcpy(tmp_image, image+i*width_size, width_size); + } + } else if (hflip && vflip) { + int i, j; + int width_size = width*depth; + void* tmp_image = flipped_image + width_size*height; + + for(i=0; i<=height-1; i++) { + for(j=0; j<=width; j++) { + memcpy(tmp_image-j*depth-3, + image+j*depth, + depth); + } + tmp_image -= width_size; + image += width_size; + } + } else { + memcpy(flipped_image, image, height*width*depth); + } +} + + + + + +/* + * return: an array of the available cameras ids. + * num_cameras: number of cameras in array. + */ +char** mac_list_cameras(int* num_cameras) { + char** cameras; + char* camera; + + // The ComponentDescription allows you to search for Components that can be used to capture + // images, and thus can be used as camera. + ComponentDescription cameraDescription; + memset(&cameraDescription, 0, sizeof(ComponentDescription)); + cameraDescription.componentType = SeqGrabComponentType; + + // Count the number of cameras on the system, and allocate an array for the cameras + *num_cameras = (int) CountComponents(&cameraDescription); + cameras = (char **) malloc(sizeof(char*) * *num_cameras); + + // Try to find a camera, and add the camera's 'number' as a string to the array of cameras + Component cameraComponent = FindNextComponent(0, &cameraDescription); + short num = 0; + while(cameraComponent != NULL) { + camera = malloc(sizeof(char) * 50); //TODO: find a better way to do this... + sprintf(camera, "%d", cameraComponent); + cameras[num] = camera; + cameraComponent = FindNextComponent(cameraComponent, &cameraDescription); + num++; + } + return cameras; +} + +/* Open a Camera component. */ +int mac_open_device (PyCameraObject* self) { + OSErr theErr; + + // Initialize movie toolbox + theErr = EnterMovies(); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot initializes the Movie Toolbox"); + return 0; + } + + // Open camera component + SeqGrabComponent component = OpenComponent((Component) atoi(self->device_name)); + if (component == NULL) { + PyErr_Format(PyExc_SystemError, + "Cannot open '%s'", self->device_name); + return 0; + } + self->component = component; + + return 1; +} + +/* Make the Camera object ready for capturing images. */ +int mac_init_device(PyCameraObject* self) { + OSErr theErr; + + if (self->color_out == YUV_OUT) { + self->pixelformat = kYUVSPixelFormat; + self->depth = 2; + } else { + self->pixelformat = k24RGBPixelFormat; + self->depth = 3; + } + + int rowlength = self->boundsRect.right * self->depth; + + theErr = SGInitialize(self->component); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot initialize sequence grabber component"); + return 0; + } + + + theErr = SGSetDataRef(self->component, 0, 0, seqGrabDontMakeMovie); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot set the sequence grabber destination data reference for a record operation"); + return 0; + } + + theErr = SGNewChannel(self->component, VideoMediaType, &self->channel); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot creates a sequence grabber channel and assigns a channel component to the channel"); + return 0; + } + + //theErr = SGSettingsDialog (self->component, self->channel, 0, NULL, 0, NULL, 0); + + theErr = SGSetChannelBounds(self->channel, &self->boundsRect); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot specifie a channel's display boundary rectangle"); + return 0; + } + + /* + theErr = SGSetFrameRate (vc, fps); + if(theErr != noErr){ + PyErr_Format(PyExc_SystemError, + "Cannot set the frame rate of the sequence grabber"); + return 0; + } + */ + + theErr = SGSetChannelUsage(self->channel, seqGrabPreview); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot specifie how a channel is to be used by the sequence grabber componen"); + return 0; + } + + theErr = SGSetChannelPlayFlags(self->channel, channelPlayAllData); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot adjust the speed and quality with which the sequence grabber displays data from a channel"); + return 0; + } + + self->pixels.length = self->boundsRect.right * self->boundsRect.bottom * self->depth; + self->pixels.start = (unsigned char*) malloc(self->pixels.length); + + theErr = QTNewGWorldFromPtr(&self->gworld, + self->pixelformat, + &self->boundsRect, + NULL, + NULL, + 0, + self->pixels.start, + rowlength); + + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot wrap a graphics world and pixel map structure around an existing block of memory containing an image, " + "failed to run QTNewGWorldFromPtr"); + free(self->pixels.start); + self->pixels.start = NULL; + self->pixels.length = 0; + return 0; + } + + if (self->gworld == NULL) { + PyErr_Format(PyExc_SystemError, + "Cannot wrap a graphics world and pixel map structure around an existing block of memory containing an image, " + "gworld is NULL"); + free(self->pixels.start); + self->pixels.start = NULL; + self->pixels.length = 0; + return 0; + } + + theErr = SGSetGWorld(self->component, (CGrafPtr)self->gworld, NULL); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot establishe the graphics port and device for a sequence grabber component"); + free(self->pixels.start); + self->pixels.start = NULL; + self->pixels.length = 0; + return 0; + } + + return 1; +} + +/* Start Capturing */ +int mac_start_capturing(PyCameraObject* self) { + OSErr theErr; + + theErr = SGPrepare(self->component, true, false); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot istruct a sequence grabber to get ready to begin a preview or record operation"); + free(self->pixels.start); + self->pixels.start = NULL; + self->pixels.length = 0; + return 0; + } + + theErr = SGStartPreview(self->component); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot instruct the sequence grabber to begin processing data from its channels"); + free(self->pixels.start); + self->pixels.start = NULL; + self->pixels.length = 0; + return 0; + } + + return 1; +} + +/* Close the camera component, and stop the image capturing if necessary. */ +int mac_close_device (PyCameraObject* self) { + ComponentResult theErr; + + // Stop recording + if (self->component) + SGStop(self->component); + + // Close sequence grabber component + if (self->component) { + theErr = CloseComponent(self->component); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Cannot close sequence grabber component"); + return 0; + } + self->component = NULL; + } + + // Dispose of GWorld + if (self->gworld) { + DisposeGWorld(self->gworld); + self->gworld = NULL; + } + // Dispose of pixels buffer + free(self->pixels.start); + self->pixels.start = NULL; + self->pixels.length = 0; + return 1; +} + +/* Stop capturing. */ +int mac_stop_capturing (PyCameraObject* self) { + OSErr theErr = SGStop(self->component); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, + "Could not stop the sequence grabber with previewing"); + return 0; + } + return 1; +} + +/* Read a frame, and put the raw data into a python string. */ +PyObject *mac_read_raw(PyCameraObject *self) { + if (self->gworld == NULL) { + PyErr_Format(PyExc_SystemError, + "Cannot set convert gworld to surface because gworls is 0"); + return 0; + } + + if (mac_camera_idle(self) == 0) { + return 0; + } + + PyObject *raw; + PixMapHandle pixmap_handle = GetGWorldPixMap(self->gworld); + LockPixels(pixmap_handle); + raw = PyString_FromStringAndSize(self->pixels.start, self->pixels.length); + UnlockPixels(pixmap_handle); + return raw; +} + +/* Read a frame from the camera and copy it to a surface. */ +int mac_read_frame(PyCameraObject* self, SDL_Surface* surf) { + if (mac_camera_idle(self) != 0) { + return mac_process_image(self, self->pixels.start, self->pixels.length, surf); + } else { + return 0; + } +} + +// TODO sometimes it is posible to directly grab the image in the desired pixel format, +// but this format needs to be known at the beginning of the initiation of the camera. +int mac_process_image(PyCameraObject* self, const void *image, unsigned int buffer_size, SDL_Surface* surf) { + if (!surf) + return 0; + + void* new_pixels; + if (self->hflip || self->vflip) { + new_pixels = malloc(self->pixels.length); + flip_image(self->pixels.start, + new_pixels, + self->boundsRect.right, + self->boundsRect.bottom, + self->depth, + self->hflip, + self->vflip); + } else { + new_pixels = image; + } + + SDL_LockSurface(surf); + + switch (self->pixelformat) { + case k24RGBPixelFormat: + if (buffer_size >= self->size * 3) { + switch (self->color_out) { + case RGB_OUT: + rgb24_to_rgb(new_pixels, surf->pixels, self->size, surf->format); + break; + case HSV_OUT: + rgb_to_hsv(new_pixels, surf->pixels, self->size, V4L2_PIX_FMT_RGB24, surf->format); + break; + case YUV_OUT: + rgb_to_yuv(new_pixels, surf->pixels, self->size, V4L2_PIX_FMT_RGB24, surf->format); + break; + } + } else { + SDL_UnlockSurface(surf); + free(new_pixels); + return 0; + } + break; + + case kYUVSPixelFormat: + if (buffer_size >= self->size * 2) { + switch (self->color_out) { + case YUV_OUT: + yuyv_to_yuv(new_pixels, surf->pixels, self->size, surf->format); + break; + case RGB_OUT: + yuyv_to_rgb(new_pixels, surf->pixels, self->size, surf->format); + break; + case HSV_OUT: + yuyv_to_rgb(new_pixels, surf->pixels, self->size, surf->format); + rgb_to_hsv(surf->pixels, surf->pixels, self->size, V4L2_PIX_FMT_YUYV, surf->format); + break; + } + } else { + SDL_UnlockSurface(surf); + free(new_pixels); + return 0; + } + break; + } + SDL_UnlockSurface(surf); + if (self->hflip || self->vflip) + free(new_pixels); + + return 1; +} + +/* Put the camera in idle mode. */ +int mac_camera_idle(PyCameraObject* self) { + OSErr theErr = SGIdle(self->component); + if (theErr != noErr) { + PyErr_Format(PyExc_SystemError, "SGIdle failed"); + return 0; + } + + return 1; +}
--- a/src/cdrom.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/cdrom.c Mon Nov 16 18:31:40 2009 +0000 @@ -23,7 +23,7 @@ #define PYGAMEAPI_CDROM_INTERNAL #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/cdrom_doc.h" #define CDROM_MAXDRIVES 32 static SDL_CD* cdrom_drivedata[CDROM_MAXDRIVES] = {NULL};
--- a/src/color.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/color.c Mon Nov 16 18:31:40 2009 +0000 @@ -19,7 +19,7 @@ */ #define PYGAMEAPI_COLOR_INTERNAL -#include "pygamedocs.h" +#include "doc/color_doc.h" #include "pygame.h" #include "pgcompat.h" #include <ctype.h>
--- a/src/display.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/display.c Mon Nov 16 18:31:40 2009 +0000 @@ -26,7 +26,7 @@ #define PYGAMEAPI_DISPLAY_INTERNAL #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/display_doc.h" #include <SDL_syswm.h>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/_movie_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,39 @@ +#ifndef _MOVIE_DOC_H_ +#define _MOVIE_DOC_H_ + +#define DOC_GMOVIE "pygame backend module that wraps the ffmpeg library to play video files" + +#define DOC_GMOVIEMOVIE "pygame._movie.Movie(filename, surface=None): returns Movie or None\nIf the optional surface argument is a surface, then the movie will output to that surface instead of using overlays." + +#define DOC_GMOVIEMOVIEPLAY "pygame._movie.Movie.play(loops=0): return None\nplays the video file loops+1 times." + +#define DOC_GMOVIEMOVIESTOP "pygame._movie.Movie.stop(): return None\nstops the video file and returns it to timestamp o." + +#define DOC_GMOVIEMOVIEPAUSE "pygame._movie.Movie.pause(): return None\npauses video file at that very moment or unpauses the video file." + +#define DOC_GMOVIEMOVIEREWIND "pygame._movie.Movie.rewind(): return None\nsame as stop()" + +#define DOC_GMOVIEMOVIERESIZE "pygame._movie.Movie.resize(width, height): return None\nresizes the video screen. If a surface has been provided, then resize will not work, to prevent image corruption issues.\nYou would need to provide a new surface to change the size." + +#define DOC_GMOVIEMOVIEPAUSED "pygame._movie.Movie.paused: return bool\nchecks if the movie file has been paused" + +#define DOC_GMOVIEMOVIEPLAYING "pygame._movie.Movie.playing: return bool\nchecks if the movie file is playing. True even when paused, but false when stop has been called." + +#define DOC_GMOVIEMOVIEWIDTH "pygame._movie.Movie.width: Gets or sets the width\nGet or set the width of the screen for the video playback" + +#define DOC_GMOVIEMOVIEHEIGHT "pygame._movie.Movie.height: Gets or sets the height\nGet or set the height of the screen for the video playback" + +#define DOC_GMOVIEMOVIESURFACE "pygame._movie.Movie.surface: Gets or sets the surface to which the video is displayed on." + +#define DOC_GMOVIEMOVIEFINISHED "pygame._movie.Movie.finished: Indicates when the video is played.\n If using multiple plays, this is not a reliable member to use, as when a video ends, regardless of if there are further plays, the finished member is triggered." + +#define DOC_GMOVIEMOVIEYTOP "pygame._movie.Movie.ytop: Gets or sets the ytop of the display rect\nThis sets the distance between the image and the top of the window. Increase it to move the image down, or decrease it to move the image up." + +#define DOC_GMOVIEMOVIEXLEFT "pygame._movie.Movie.xleft: Gets or sets the xleft of the display rect\nThis sets the distance between the image and the left of the window. Increase it to move the image right, or decrease it to move the image left." + +#define DOC_GMOVIEMOVIEEASY_SEEK "pygame._movie.Movie.easy_seek(second, minute, hour, reverse): return None\nThis is a non-relative seek, instead seeking to the h:mm:ss timestamp on the video as given. All arguments are needed." + +#define DOC_GMOVIEMOVIESHIFT "pygame._movie.Movie.shift(ytop, xleft): return None\nShift the video image up, left, right, or down. Default values are 0,0." + + +#endif /*_MOVIE_DOC_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/camera_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,105 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMECAMERA "pygame module for camera use" + +#define DOC_PYGAMECAMERACOLORSPACE "pygame.camera.colorspace(Surface, format, DestSurface = None): return Surface\nSurface colorspace conversion" + +#define DOC_PYGAMECAMERALISTCAMERAS "pygame.camera.list_cameras(): return [cameras]\nreturns a list of available cameras" + +#define DOC_PYGAMECAMERACAMERA "pygame.camera.Camera(device, (width, height), format): return Camera\nload a camera" + +#define DOC_CAMERASTART "Camera.start(): return None\nopens, initializes, and starts capturing" + +#define DOC_CAMERASTOP "Camera.stop(): return None\nstops, uninitializes, and closes the camera" + +#define DOC_CAMERAGETCONTROLS "Camera.get_controls(): return (hflip = bool, vflip = bool, brightness)\ngets current values of user controls" + +#define DOC_CAMERASETCONTROLS "Camera.set_controls(hflip = bool, vflip = bool, brightness): return (hflip = bool, vflip = bool, brightness)\nchanges camera settings if supported by the camera" + +#define DOC_CAMERAGETSIZE "Camera.get_size(): return (width, height)\nreturns the dimensions of the images being recorded" + +#define DOC_CAMERAQUERYIMAGE "Camera.query_image(): return bool\nchecks if a frame is ready" + +#define DOC_CAMERAGETIMAGE "Camera.get_image(Surface = None): return Surface\ncaptures an image as a Surface" + +#define DOC_CAMERAGETRAW "Camera.get_raw(): return string\nreturns an unmodified image as a string" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.camera + pygame module for camera use + + + +pygame.camera.colorspace + pygame.camera.colorspace(Surface, format, DestSurface = None): return Surface +Surface colorspace conversion + + + +pygame.camera.list_cameras + pygame.camera.list_cameras(): return [cameras] +returns a list of available cameras + + + +pygame.camera.Camera + pygame.camera.Camera(device, (width, height), format): return Camera +load a camera + + + +Camera.start + Camera.start(): return None +opens, initializes, and starts capturing + + + +Camera.stop + Camera.stop(): return None +stops, uninitializes, and closes the camera + + + +Camera.get_controls + Camera.get_controls(): return (hflip = bool, vflip = bool, brightness) +gets current values of user controls + + + +Camera.set_controls + Camera.set_controls(hflip = bool, vflip = bool, brightness): return (hflip = bool, vflip = bool, brightness) +changes camera settings if supported by the camera + + + +Camera.get_size + Camera.get_size(): return (width, height) +returns the dimensions of the images being recorded + + + +Camera.query_image + Camera.query_image(): return bool +checks if a frame is ready + + + +Camera.get_image + Camera.get_image(Surface = None): return Surface +captures an image as a Surface + + + +Camera.get_raw + Camera.get_raw(): return string +returns an unmodified image as a string + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/cdrom_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,209 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMECDROM "pygame module for audio cdrom control" + +#define DOC_PYGAMECDROMINIT "pygame.cdrom.init(): return None\ninitialize the cdrom module" + +#define DOC_PYGAMECDROMQUIT "pygame.cdrom.quit(): return None\nuninitialize the cdrom module" + +#define DOC_PYGAMECDROMGETINIT "pygame.cdrom.get_init(): return bool\ntrue if the cdrom module is initialized" + +#define DOC_PYGAMECDROMGETCOUNT "pygame.cdrom.get_count(): return count\nnumber of cd drives on the system" + +#define DOC_PYGAMECDROMCD "pygame.cdrom.CD(id): return CD\nclass to manage a cdrom drive" + +#define DOC_CDINIT "CD.init(): return None\ninitialize a cdrom drive for use" + +#define DOC_CDQUIT "CD.quit(): return None\nuninitialize a cdrom drive for use" + +#define DOC_CDGETINIT "CD.get_init(): return bool\ntrue if this cd device initialized" + +#define DOC_CDPLAY "CD.play(track, start=None, end=None): return None\nstart playing audio" + +#define DOC_CDSTOP "CD.stop(): return None\nstop audio playback" + +#define DOC_CDPAUSE "CD.pause(): return None\ntemporarily stop audio playback" + +#define DOC_CDRESUME "CD.resume(): return None\nunpause audio playback" + +#define DOC_CDEJECT "CD.eject(): return None\neject or open the cdrom drive" + +#define DOC_CDGETID "CD.get_id(): return id\nthe index of the cdrom drive" + +#define DOC_CDGETNAME "CD.get_name(): return name\nthe system name of the cdrom drive" + +#define DOC_CDGETBUSY "CD.get_busy(): return bool\ntrue if the drive is playing audio" + +#define DOC_CDGETPAUSED "CD.get_paused(): return bool\ntrue if the drive is paused" + +#define DOC_CDGETCURRENT "CD.get_current(): return track, seconds\nthe current audio playback position" + +#define DOC_CDGETEMPTY "CD.get_empty(): return bool\nFalse if a cdrom is in the drive" + +#define DOC_CDGETNUMTRACKS "CD.get_numtracks(): return count\nthe number of tracks on the cdrom" + +#define DOC_CDGETTRACKAUDIO "CD.get_track_audio(track): return bool\ntrue if the cdrom track has audio data" + +#define DOC_CDGETALL "CD.get_all(): return [(audio, start, end, lenth), ...]\nget all track information" + +#define DOC_CDGETTRACKSTART "CD.get_track_start(track): return seconds\nstart time of a cdrom track" + +#define DOC_CDGETTRACKLENGTH "CD.get_track_length(track): return seconds\nlength of a cdrom track" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.cdrom + pygame module for audio cdrom control + + + +pygame.cdrom.init + pygame.cdrom.init(): return None +initialize the cdrom module + + + +pygame.cdrom.quit + pygame.cdrom.quit(): return None +uninitialize the cdrom module + + + +pygame.cdrom.get_init + pygame.cdrom.get_init(): return bool +true if the cdrom module is initialized + + + +pygame.cdrom.get_count + pygame.cdrom.get_count(): return count +number of cd drives on the system + + + +pygame.cdrom.CD + pygame.cdrom.CD(id): return CD +class to manage a cdrom drive + + + +CD.init + CD.init(): return None +initialize a cdrom drive for use + + + +CD.quit + CD.quit(): return None +uninitialize a cdrom drive for use + + + +CD.get_init + CD.get_init(): return bool +true if this cd device initialized + + + +CD.play + CD.play(track, start=None, end=None): return None +start playing audio + + + +CD.stop + CD.stop(): return None +stop audio playback + + + +CD.pause + CD.pause(): return None +temporarily stop audio playback + + + +CD.resume + CD.resume(): return None +unpause audio playback + + + +CD.eject + CD.eject(): return None +eject or open the cdrom drive + + + +CD.get_id + CD.get_id(): return id +the index of the cdrom drive + + + +CD.get_name + CD.get_name(): return name +the system name of the cdrom drive + + + +CD.get_busy + CD.get_busy(): return bool +true if the drive is playing audio + + + +CD.get_paused + CD.get_paused(): return bool +true if the drive is paused + + + +CD.get_current + CD.get_current(): return track, seconds +the current audio playback position + + + +CD.get_empty + CD.get_empty(): return bool +False if a cdrom is in the drive + + + +CD.get_numtracks + CD.get_numtracks(): return count +the number of tracks on the cdrom + + + +CD.get_track_audio + CD.get_track_audio(track): return bool +true if the cdrom track has audio data + + + +CD.get_all + CD.get_all(): return [(audio, start, end, lenth), ...] +get all track information + + + +CD.get_track_start + CD.get_track_start(track): return seconds +start time of a cdrom track + + + +CD.get_track_length + CD.get_track_length(track): return seconds +length of a cdrom track + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/color_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,108 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMECOLOR "pygame.Color(name): Return Color\npygame.Color(r, g, b, a): Return Color\npygame.Color(rgbvalue): Return Color\npygame object for color representations" + +#define DOC_COLORR "Color.r: Return int\nGets or sets the red value of the Color." + +#define DOC_COLORG "Color.g: Return int\nGets or sets the green value of the Color." + +#define DOC_COLORB "Color.b: Return int\nGets or sets the blue value of the Color." + +#define DOC_COLORA "Color.a: Return int\nGets or sets the alpha value of the Color." + +#define DOC_COLORCMY "Color.cmy: Return tuple\nGets or sets the CMY representation of the Color." + +#define DOC_COLORHSVA "Color.hsva: Return tuple\nGets or sets the HSVA representation of the Color." + +#define DOC_COLORHSLA "Color.hsla: Return tuple\nGets or sets the HSLA representation of the Color." + +#define DOC_COLORI1I2I3 "Color.i1i2i3: Return tuple\nGets or sets the I1I2I3 representation of the Color." + +#define DOC_COLORNORMALIZE "Color.normalize(): Return tuple\nReturns the normalized RGBA values of the Color." + +#define DOC_COLORCORRECTGAMMA "Color.correct_gamma (gamma): Return Color\nApplies a certain gamma value to the Color." + +#define DOC_COLORSETLENGTH "Color.set_length(len)\nSet the number of elements in the Color to 1,2,3, or 4." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.Color + pygame.Color(name): Return Color +pygame.Color(r, g, b, a): Return Color +pygame.Color(rgbvalue): Return Color +pygame object for color representations + + + +Color.r + Color.r: Return int +Gets or sets the red value of the Color. + + + +Color.g + Color.g: Return int +Gets or sets the green value of the Color. + + + +Color.b + Color.b: Return int +Gets or sets the blue value of the Color. + + + +Color.a + Color.a: Return int +Gets or sets the alpha value of the Color. + + + +Color.cmy + Color.cmy: Return tuple +Gets or sets the CMY representation of the Color. + + + +Color.hsva + Color.hsva: Return tuple +Gets or sets the HSVA representation of the Color. + + + +Color.hsla + Color.hsla: Return tuple +Gets or sets the HSLA representation of the Color. + + + +Color.i1i2i3 + Color.i1i2i3: Return tuple +Gets or sets the I1I2I3 representation of the Color. + + + +Color.normalize + Color.normalize(): Return tuple +Returns the normalized RGBA values of the Color. + + + +Color.correct_gamma + Color.correct_gamma (gamma): Return Color +Applies a certain gamma value to the Color. + + + +Color.set_length + Color.set_length(len) +Set the number of elements in the Color to 1,2,3, or 4. + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/cursors_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,34 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMECURSORS "pygame module for cursor resources" + +#define DOC_PYGAMECURSORSCOMPILE "pygame.cursor.compile(strings, black='X', white='.', xor='o'): return data, mask\ncreate binary cursor data from simple strings" + +#define DOC_PYGAMECURSORSLOADXBM "pygame.cursors.load_xbm(cursorfile): return cursor_args\npygame.cursors.load_xbm(cursorfile, maskfile): return cursor_args\nload cursor data from an xbm file" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.cursors + pygame module for cursor resources + + + +pygame.cursors.compile + pygame.cursor.compile(strings, black='X', white='.', xor='o'): return data, mask +create binary cursor data from simple strings + + + +pygame.cursors.load_xbm + pygame.cursors.load_xbm(cursorfile): return cursor_args +pygame.cursors.load_xbm(cursorfile, maskfile): return cursor_args +load cursor data from an xbm file + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/display_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,203 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEDISPLAY "pygame module to control the display window and screen" + +#define DOC_PYGAMEDISPLAYINIT "pygame.display.init(): return None\ninitialize the display module" + +#define DOC_PYGAMEDISPLAYQUIT "pygame.display.quit(): return None\nuninitialize the display module" + +#define DOC_PYGAMEDISPLAYGETINIT "pygame.display.get_init(): return bool\ntrue if the display module is initialized" + +#define DOC_PYGAMEDISPLAYSETMODE "pygame.display.set_mode(resolution=(0,0), flags=0, depth=0): return Surface\ninitialize a window or screen for display" + +#define DOC_PYGAMEDISPLAYGETSURFACE "pygame.display.get_surface(): return Surface\nget a reference to the currently set display surface" + +#define DOC_PYGAMEDISPLAYFLIP "pygame.display.flip(): return None\nupdate the full display Surface to the screen" + +#define DOC_PYGAMEDISPLAYUPDATE "pygame.display.update(rectangle=None): return None\npygame.display.update(rectangle_list): return None\nupdate portions of the screen for software displays" + +#define DOC_PYGAMEDISPLAYGETDRIVER "pygame.display.get_driver(): return name\nget the name of the pygame display backend" + +#define DOC_PYGAMEDISPLAYINFO "pygame.display.Info(): return VideoInfo\nCreate a video display information object" + +#define DOC_PYGAMEDISPLAYGETWMINFO "pygame.display.get_wm_info(): return dict\nGet information about the current windowing system" + +#define DOC_PYGAMEDISPLAYLISTMODES "pygame.display.list_modes(depth=0, flags=pygame.FULLSCREEN): return list\nget list of available fullscreen modes" + +#define DOC_PYGAMEDISPLAYMODEOK "pygame.display.mode_ok(size, flags=0, depth=0): return depth\npick the best color depth for a display mode" + +#define DOC_PYGAMEDISPLAYGLGETATTRIBUTE "pygame.display.gl_get_attribute(flag): return value\nget the value for an opengl flag for the current display" + +#define DOC_PYGAMEDISPLAYGLSETATTRIBUTE "pygame.display.gl_set_attribute(flag, value): return None\nrequest an opengl display attribute for the display mode" + +#define DOC_PYGAMEDISPLAYGETACTIVE "pygame.display.get_active(): return bool\ntrue when the display is active on the display" + +#define DOC_PYGAMEDISPLAYICONIFY "pygame.display.iconify(): return bool\niconify the display surface" + +#define DOC_PYGAMEDISPLAYTOGGLEFULLSCREEN "pygame.display.toggle_fullscreen(): return bool\nswitch between fullscreen and windowed displays" + +#define DOC_PYGAMEDISPLAYSETGAMMA "pygame.display.set_gamma(red, green=None, blue=None): return bool\nchange the hardware gamma ramps" + +#define DOC_PYGAMEDISPLAYSETGAMMARAMP "change the hardware gamma ramps with a custom lookup\npygame.display.set_gamma_ramp(red, green, blue): return bool\nset_gamma_ramp(red, green, blue): return bool" + +#define DOC_PYGAMEDISPLAYSETICON "pygame.display.set_icon(Surface): return None\nchange the system image for the display window" + +#define DOC_PYGAMEDISPLAYSETCAPTION "pygame.display.set_caption(title, icontitle=None): return None\nset the current window caption" + +#define DOC_PYGAMEDISPLAYGETCAPTION "pygame.display.get_caption(): return (title, icontitle)\nget the current window caption" + +#define DOC_PYGAMEDISPLAYSETPALETTE "pygame.display.set_palette(palette=None): return None\nset the display color palette for indexed displays" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.display + pygame module to control the display window and screen + + + +pygame.display.init + pygame.display.init(): return None +initialize the display module + + + +pygame.display.quit + pygame.display.quit(): return None +uninitialize the display module + + + +pygame.display.get_init + pygame.display.get_init(): return bool +true if the display module is initialized + + + +pygame.display.set_mode + pygame.display.set_mode(resolution=(0,0), flags=0, depth=0): return Surface +initialize a window or screen for display + + + +pygame.display.get_surface + pygame.display.get_surface(): return Surface +get a reference to the currently set display surface + + + +pygame.display.flip + pygame.display.flip(): return None +update the full display Surface to the screen + + + +pygame.display.update + pygame.display.update(rectangle=None): return None +pygame.display.update(rectangle_list): return None +update portions of the screen for software displays + + + +pygame.display.get_driver + pygame.display.get_driver(): return name +get the name of the pygame display backend + + + +pygame.display.Info + pygame.display.Info(): return VideoInfo +Create a video display information object + + + +pygame.display.get_wm_info + pygame.display.get_wm_info(): return dict +Get information about the current windowing system + + + +pygame.display.list_modes + pygame.display.list_modes(depth=0, flags=pygame.FULLSCREEN): return list +get list of available fullscreen modes + + + +pygame.display.mode_ok + pygame.display.mode_ok(size, flags=0, depth=0): return depth +pick the best color depth for a display mode + + + +pygame.display.gl_get_attribute + pygame.display.gl_get_attribute(flag): return value +get the value for an opengl flag for the current display + + + +pygame.display.gl_set_attribute + pygame.display.gl_set_attribute(flag, value): return None +request an opengl display attribute for the display mode + + + +pygame.display.get_active + pygame.display.get_active(): return bool +true when the display is active on the display + + + +pygame.display.iconify + pygame.display.iconify(): return bool +iconify the display surface + + + +pygame.display.toggle_fullscreen + pygame.display.toggle_fullscreen(): return bool +switch between fullscreen and windowed displays + + + +pygame.display.set_gamma + pygame.display.set_gamma(red, green=None, blue=None): return bool +change the hardware gamma ramps + + + +pygame.display.set_gamma_ramp + change the hardware gamma ramps with a custom lookup +pygame.display.set_gamma_ramp(red, green, blue): return bool +set_gamma_ramp(red, green, blue): return bool + + + +pygame.display.set_icon + pygame.display.set_icon(Surface): return None +change the system image for the display window + + + +pygame.display.set_caption + pygame.display.set_caption(title, icontitle=None): return None +set the current window caption + + + +pygame.display.get_caption + pygame.display.get_caption(): return (title, icontitle) +get the current window caption + + + +pygame.display.set_palette + pygame.display.set_palette(palette=None): return None +set the display color palette for indexed displays + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/draw_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,88 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEDRAW "pygame module for drawing shapes" + +#define DOC_PYGAMEDRAWRECT "pygame.draw.rect(Surface, color, Rect, width=0): return Rect\ndraw a rectangle shape" + +#define DOC_PYGAMEDRAWPOLYGON "pygame.draw.polygon(Surface, color, pointlist, width=0): return Rect\ndraw a shape with any number of sides" + +#define DOC_PYGAMEDRAWCIRCLE "pygame.draw.circle(Surface, color, pos, radius, width=0): return Rect\ndraw a circle around a point" + +#define DOC_PYGAMEDRAWELLIPSE "pygame.draw.ellipse(Surface, color, Rect, width=0): return Rect\ndraw a round shape inside a rectangle" + +#define DOC_PYGAMEDRAWARC "pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1): return Rect\ndraw a partial section of an ellipse" + +#define DOC_PYGAMEDRAWLINE "pygame.draw.line(Surface, color, start_pos, end_pos, width=1): return Rect\ndraw a straight line segment" + +#define DOC_PYGAMEDRAWLINES "pygame.draw.lines(Surface, color, closed, pointlist, width=1): return Rect\ndraw multiple contiguous line segments" + +#define DOC_PYGAMEDRAWAALINE "pygame.draw.aaline(Surface, color, startpos, endpos, blend=1): return Rect\ndraw fine antialiased lines" + +#define DOC_PYGAMEDRAWAALINES "pygame.draw.aalines(Surface, color, closed, pointlist, blend=1): return Rect" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.draw + pygame module for drawing shapes + + + +pygame.draw.rect + pygame.draw.rect(Surface, color, Rect, width=0): return Rect +draw a rectangle shape + + + +pygame.draw.polygon + pygame.draw.polygon(Surface, color, pointlist, width=0): return Rect +draw a shape with any number of sides + + + +pygame.draw.circle + pygame.draw.circle(Surface, color, pos, radius, width=0): return Rect +draw a circle around a point + + + +pygame.draw.ellipse + pygame.draw.ellipse(Surface, color, Rect, width=0): return Rect +draw a round shape inside a rectangle + + + +pygame.draw.arc + pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1): return Rect +draw a partial section of an ellipse + + + +pygame.draw.line + pygame.draw.line(Surface, color, start_pos, end_pos, width=1): return Rect +draw a straight line segment + + + +pygame.draw.lines + pygame.draw.lines(Surface, color, closed, pointlist, width=1): return Rect +draw multiple contiguous line segments + + + +pygame.draw.aaline + pygame.draw.aaline(Surface, color, startpos, endpos, blend=1): return Rect +draw fine antialiased lines + + + +pygame.draw.aalines + pygame.draw.aalines(Surface, color, closed, pointlist, blend=1): return Rect + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/event_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,139 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEEVENT "pygame module for interacting with events and queues" + +#define DOC_PYGAMEEVENTPUMP "pygame.event.pump(): return None\ninternally process pygame event handlers" + +#define DOC_PYGAMEEVENTGET "pygame.event.get(): return Eventlist\npygame.event.get(type): return Eventlist\npygame.event.get(typelist): return Eventlist\nget events from the queue" + +#define DOC_PYGAMEEVENTPOLL "pygame.event.poll(): return Event\nget a single event from the queue" + +#define DOC_PYGAMEEVENTWAIT "pygame.event.wait(): return Event\nwait for a single event from the queue" + +#define DOC_PYGAMEEVENTPEEK "pygame.event.peek(type): return bool\npygame.event.peek(typelist): return bool\ntest if event types are waiting on the queue" + +#define DOC_PYGAMEEVENTCLEAR "pygame.event.clear(): return None\npygame.event.clear(type): return None\npygame.event.clear(typelist): return None\nremove all events from the queue" + +#define DOC_PYGAMEEVENTEVENTNAME "pygame.event.event_name(type): return string\nget the string name from and event id" + +#define DOC_PYGAMEEVENTSETBLOCKED "pygame.event.set_blocked(type): return None\npygame.event.set_blocked(typelist): return None\npygame.event.set_blocked(None): return None\ncontrol which events are allowed on the queue" + +#define DOC_PYGAMEEVENTSETALLOWED "pygame.event.set_allowed(type): return None\npygame.event.set_allowed(typelist): return None\npygame.event.set_allowed(None): return None\ncontrol which events are allowed on the queue" + +#define DOC_PYGAMEEVENTGETBLOCKED "pygame.event.get_blocked(type): return bool\ntest if a type of event is blocked from the queue" + +#define DOC_PYGAMEEVENTSETGRAB "pygame.event.set_grab(bool): return None\ncontrol the sharing of input devices with other applications" + +#define DOC_PYGAMEEVENTGETGRAB "pygame.event.get_grab(): return bool\ntest if the program is sharing input devices" + +#define DOC_PYGAMEEVENTPOST "pygame.event.post(Event): return None\nplace a new event on the queue" + +#define DOC_PYGAMEEVENTEVENT "pygame.event.Event(type, dict): return Event\npygame.event.Event(type, **attributes): return Event\ncreate a new event object" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.event + pygame module for interacting with events and queues + + + +pygame.event.pump + pygame.event.pump(): return None +internally process pygame event handlers + + + +pygame.event.get + pygame.event.get(): return Eventlist +pygame.event.get(type): return Eventlist +pygame.event.get(typelist): return Eventlist +get events from the queue + + + +pygame.event.poll + pygame.event.poll(): return Event +get a single event from the queue + + + +pygame.event.wait + pygame.event.wait(): return Event +wait for a single event from the queue + + + +pygame.event.peek + pygame.event.peek(type): return bool +pygame.event.peek(typelist): return bool +test if event types are waiting on the queue + + + +pygame.event.clear + pygame.event.clear(): return None +pygame.event.clear(type): return None +pygame.event.clear(typelist): return None +remove all events from the queue + + + +pygame.event.event_name + pygame.event.event_name(type): return string +get the string name from and event id + + + +pygame.event.set_blocked + pygame.event.set_blocked(type): return None +pygame.event.set_blocked(typelist): return None +pygame.event.set_blocked(None): return None +control which events are allowed on the queue + + + +pygame.event.set_allowed + pygame.event.set_allowed(type): return None +pygame.event.set_allowed(typelist): return None +pygame.event.set_allowed(None): return None +control which events are allowed on the queue + + + +pygame.event.get_blocked + pygame.event.get_blocked(type): return bool +test if a type of event is blocked from the queue + + + +pygame.event.set_grab + pygame.event.set_grab(bool): return None +control the sharing of input devices with other applications + + + +pygame.event.get_grab + pygame.event.get_grab(): return bool +test if the program is sharing input devices + + + +pygame.event.post + pygame.event.post(Event): return None +place a new event on the queue + + + +pygame.event.Event + pygame.event.Event(type, dict): return Event +pygame.event.Event(type, **attributes): return Event +create a new event object + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/examples_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,225 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEEXAMPLES "module of example programs" + +#define DOC_PYGAMEEXAMPLESALIENSMAIN "pygame.aliens.main(): return None\nplay the full aliens example" + +#define DOC_PYGAMEEXAMPLESOLDALIENMAIN "pygame.examples.oldalien.main(): return None\nplay the original aliens example" + +#define DOC_PYGAMEEXAMPLESSTARSMAIN "pygame.examples.stars.main(): return None\nrun a simple starfield example" + +#define DOC_PYGAMEEXAMPLESCHIMPMAIN "pygame.examples.chimp.main(): return None\nhit the moving chimp" + +#define DOC_PYGAMEEXAMPLESMOVEITMAIN "pygame.examples.moveit.main(): return None\ndisplay animated objects on the screen" + +#define DOC_PYGAMEEXAMPLESFONTYMAIN "pygame.examples.fonty.main(): return None\nrun a font rendering example" + +#define DOC_PYGAMEEXAMPLESVGRADEMAIN "pygame.examples.vgrade.main(): return None\ndisplay a vertical gradient" + +#define DOC_PYGAMEEXAMPLESEVENTLISTMAIN "pygame.examples.eventlist.main(): return None\ndisplay pygame events" + +#define DOC_PYGAMEEXAMPLESARRAYDEMOMAIN "pygame.examples.arraydemo.main(arraytype=None): return None\nshow various surfarray effects" + +#define DOC_PYGAMEEXAMPLESSOUNDMAIN "pygame.examples.sound.main(file_path=None): return None\nload and play a sound" + +#define DOC_PYGAMEEXAMPLESSOUNDARRAYDEMOSMAIN "pygame.examples.sound_array_demos.main(arraytype=None): return None\nplay various sndarray effects" + +#define DOC_PYGAMEEXAMPLESLIQUIDMAIN "pygame.examples.liquid.main(): return None\ndisplay an animated liquid effect" + +#define DOC_PYGAMEEXAMPLESGLCUBEMAIN "pygame.examples.glcube.main(): return None\ndisplay an animated 3D cube using OpenGL" + +#define DOC_PYGAMEEXAMPLESSCRAPCLIPBOARDMAIN "pygame.examples.scrap_clipboard.main(): return None\naccess the clipboard" + +#define DOC_PYGAMEEXAMPLESMASKMAIN "pygame.examples.mask.main(*args): return None\ndisplay multiple images bounce off each other using collision detection" + +#define DOC_PYGAMEEXAMPLESTESTSPRITEMAIN "pygame.examples.testsprite.main(update_rects = True, use_static = False, use_FastRenderGroup = False, screen_dims = [640, 480], use_alpha = False, flags = 0): return None\nshow lots of sprites moving around" + +#define DOC_PYGAMEEXAMPLESHEADLESSNOWINDOWSNEEDEDMAIN "pygame.examples.headless_no_windows_needed.main(fin, fout, w, h): return None\nwrite an image file that is smoothscaled copy of an input file" + +#define DOC_PYGAMEEXAMPLESFASTEVENTSMAIN "pygame.examples.fastevents.main(): return None\nstress test the fastevents module" + +#define DOC_PYGAMEEXAMPLESOVERLAYMAIN "pygame.examples.overlay.main(fname): return None\nplay a .pgm video using overlays" + +#define DOC_PYGAMEEXAMPLESBLENDFILLMAIN "pygame.examples.blend_fill.main(): return None\ndemonstrate the various surface.fill method blend options" + +#define DOC_PYGAMEEXAMPLESCURSORSMAIN "pygame.examples.cursors.main(): return None\ndisplay two different custom cursors" + +#define DOC_PYGAMEEXAMPLESPIXELARRAYMAIN "pygame.examples.pixelarray.main(): return None\ndisplay various pixelarray generated effects" + +#define DOC_PYGAMEEXAMPLESSCALETESTMAIN "pygame.examples.scaletest.main(imagefile, convert_alpha=False, run_speed_test=True): return None\ninteractively scale an image using smoothscale" + +#define DOC_PYGAMEEXAMPLESMIDIMAIN "pygame.examples.midi.main(mode='output', device_id=None): return None\nrun a midi example" + +#define DOC_PYGAMEEXAMPLESSCROLLMAIN "pygame.examples.scroll.main(image_file=None): return None\nrun a Surface.scroll example that shows a magnified image" + +#define DOC_PYGAMEEXAMPLESMOVIEPLAYERMAIN "pygame.examples.moveplayer.main(filepath): return None\nplay an MPEG movie" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.examples + module of example programs + + + +pygame.examples.aliens.main + pygame.aliens.main(): return None +play the full aliens example + + + +pygame.examples.oldalien.main + pygame.examples.oldalien.main(): return None +play the original aliens example + + + +pygame.examples.stars.main + pygame.examples.stars.main(): return None +run a simple starfield example + + + +pygame.examples.chimp.main + pygame.examples.chimp.main(): return None +hit the moving chimp + + + +pygame.examples.moveit.main + pygame.examples.moveit.main(): return None +display animated objects on the screen + + + +pygame.examples.fonty.main + pygame.examples.fonty.main(): return None +run a font rendering example + + + +pygame.examples.vgrade.main + pygame.examples.vgrade.main(): return None +display a vertical gradient + + + +pygame.examples.eventlist.main + pygame.examples.eventlist.main(): return None +display pygame events + + + +pygame.examples.arraydemo.main + pygame.examples.arraydemo.main(arraytype=None): return None +show various surfarray effects + + + +pygame.examples.sound.main + pygame.examples.sound.main(file_path=None): return None +load and play a sound + + + +pygame.examples.sound_array_demos.main + pygame.examples.sound_array_demos.main(arraytype=None): return None +play various sndarray effects + + + +pygame.examples.liquid.main + pygame.examples.liquid.main(): return None +display an animated liquid effect + + + +pygame.examples.glcube.main + pygame.examples.glcube.main(): return None +display an animated 3D cube using OpenGL + + + +pygame.examples.scrap_clipboard.main + pygame.examples.scrap_clipboard.main(): return None +access the clipboard + + + +pygame.examples.mask.main + pygame.examples.mask.main(*args): return None +display multiple images bounce off each other using collision detection + + + +pygame.examples.testsprite.main + pygame.examples.testsprite.main(update_rects = True, use_static = False, use_FastRenderGroup = False, screen_dims = [640, 480], use_alpha = False, flags = 0): return None +show lots of sprites moving around + + + +pygame.examples.headless_no_windows_needed.main + pygame.examples.headless_no_windows_needed.main(fin, fout, w, h): return None +write an image file that is smoothscaled copy of an input file + + + +pygame.examples.fastevents.main + pygame.examples.fastevents.main(): return None +stress test the fastevents module + + + +pygame.examples.overlay.main + pygame.examples.overlay.main(fname): return None +play a .pgm video using overlays + + + +pygame.examples.blend_fill.main + pygame.examples.blend_fill.main(): return None +demonstrate the various surface.fill method blend options + + + +pygame.examples.cursors.main + pygame.examples.cursors.main(): return None +display two different custom cursors + + + +pygame.examples.pixelarray.main + pygame.examples.pixelarray.main(): return None +display various pixelarray generated effects + + + +pygame.examples.scaletest.main + pygame.examples.scaletest.main(imagefile, convert_alpha=False, run_speed_test=True): return None +interactively scale an image using smoothscale + + + +pygame.examples.midi.main + pygame.examples.midi.main(mode='output', device_id=None): return None +run a midi example + + + +pygame.examples.scroll.main + pygame.examples.scroll.main(image_file=None): return None +run a Surface.scroll example that shows a magnified image + + + +pygame.examples.movieplayer.main + pygame.examples.moveplayer.main(filepath): return None +play an MPEG movie + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/font_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,186 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEFONT "pygame module for loading and rendering fonts" + +#define DOC_PYGAMEFONTINIT "pygame.font.init(): return None\ninitialize the font module" + +#define DOC_PYGAMEFONTQUIT "pygame.font.quit(): return None\nuninitialize the font module" + +#define DOC_PYGAMEFONTGETINIT "pygame.font.get_init(): return bool\ntrue if the font module is initialized" + +#define DOC_PYGAMEFONTGETDEFAULTFONT "pygame.font.get_default_font(): return string\nget the filename of the default font" + +#define DOC_PYGAMEFONTGETFONTS "pygame.font.get_fonts(): return list of strings\nget all available fonts" + +#define DOC_PYGAMEFONTMATCHFONT "pygame.font.match_font(name, bold=False, italic=False): return path\nfind a specific font on the system" + +#define DOC_PYGAMEFONTSYSFONT "pygame.font.SysFont(name, size, bold=False, italic=False): return Font\ncreate a Font object from the system fonts" + +#define DOC_PYGAMEFONTFONT "pygame.font.Font(filename, size): return Font\npygame.font.Font(object, size): return Font\ncreate a new Font object from a file" + +#define DOC_FONTRENDER "Font.render(text, antialias, color, background=None): return Surface\ndraw text on a new Surface" + +#define DOC_FONTSIZE "Font.size(text): return (width, height)\ndetermine the amount of space needed to render text" + +#define DOC_FONTSETUNDERLINE "Font.set_underline(bool): return None\ncontrol if text is rendered with an underline" + +#define DOC_FONTGETUNDERLINE "Font.get_underline(): return bool\ncheck if text will be rendered with an underline" + +#define DOC_FONTSETBOLD "Font.set_bold(bool): return None\nenable fake rendering of bold text" + +#define DOC_FONTGETBOLD "Font.get_bold(): return bool\ncheck if text will be rendered bold" + +#define DOC_FONTSETITALIC "Font.set_bold(bool): return None\nenable fake rendering of italic text" + +#define DOC_FONTMETRICS "Font.metrics(text): return list\nGets the metrics for each character in the pased string." + +#define DOC_FONTGETITALIC "Font.get_italic(): return bool\ncheck if the text will be rendered italic" + +#define DOC_FONTGETLINESIZE "Font.get_linesize(): return int\nget the line space of the font text" + +#define DOC_FONTGETHEIGHT "Font.get_height(): return int\nget the height of the font" + +#define DOC_FONTGETASCENT "Font.get_ascent(): return int\nget the ascent of the font" + +#define DOC_FONTGETDESCENT "Font.get_descent(): return int\nget the descent of the font" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.font + pygame module for loading and rendering fonts + + + +pygame.font.init + pygame.font.init(): return None +initialize the font module + + + +pygame.font.quit + pygame.font.quit(): return None +uninitialize the font module + + + +pygame.font.get_init + pygame.font.get_init(): return bool +true if the font module is initialized + + + +pygame.font.get_default_font + pygame.font.get_default_font(): return string +get the filename of the default font + + + +pygame.font.get_fonts + pygame.font.get_fonts(): return list of strings +get all available fonts + + + +pygame.font.match_font + pygame.font.match_font(name, bold=False, italic=False): return path +find a specific font on the system + + + +pygame.font.SysFont + pygame.font.SysFont(name, size, bold=False, italic=False): return Font +create a Font object from the system fonts + + + +pygame.font.Font + pygame.font.Font(filename, size): return Font +pygame.font.Font(object, size): return Font +create a new Font object from a file + + + +Font.render + Font.render(text, antialias, color, background=None): return Surface +draw text on a new Surface + + + +Font.size + Font.size(text): return (width, height) +determine the amount of space needed to render text + + + +Font.set_underline + Font.set_underline(bool): return None +control if text is rendered with an underline + + + +Font.get_underline + Font.get_underline(): return bool +check if text will be rendered with an underline + + + +Font.set_bold + Font.set_bold(bool): return None +enable fake rendering of bold text + + + +Font.get_bold + Font.get_bold(): return bool +check if text will be rendered bold + + + +Font.set_italic + Font.set_bold(bool): return None +enable fake rendering of italic text + + + +Font.metrics + Font.metrics(text): return list +Gets the metrics for each character in the pased string. + + + +Font.get_italic + Font.get_italic(): return bool +check if the text will be rendered italic + + + +Font.get_linesize + Font.get_linesize(): return int +get the line space of the font text + + + +Font.get_height + Font.get_height(): return int +get the height of the font + + + +Font.get_ascent + Font.get_ascent(): return int +get the ascent of the font + + + +Font.get_descent + Font.get_descent(): return int +get the descent of the font + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/freetype_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,168 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEFREETYPE "Enhanced Pygame module for loading and rendering fonts" + +#define DOC_PYGAMEFREETYPEGETERROR "pygame.freetype.get_error(): return str\nGet the latest error" + +#define DOC_PYGAMEFREETYPEGETVERSION "pygame.freetype.get_version(): return (int, int, int)\nGet the FreeType version" + +#define DOC_PYGAMEFREETYPEINIT "pygame.freetype.init(default_cache_size=64): return None\nInitialize the underlying FreeType 2 library." + +#define DOC_PYGAMEFREETYPEQUIT "pygame.freetype.quit(): return None\nShuts down the underlying FreeType 2 library." + +#define DOC_PYGAMEFREETYPEWASINIT "pygame.freetype.quit(): return bool\nReturns whether the the FreeType 2 library is initialized." + +#define DOC_PYGAMEFREETYPEFONT "pygame.freetype.Font(file, style=STYLE_NONE, ptsize=-1, face_index=0): return Font\nCreates a new Font from a supported font file." + +#define DOC_FONTNAME "Font.name: return string\nGets the name of the font face." + +#define DOC_FONTGETSIZE "Font.get_size(text, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (int, int)\nGets the size of rendered text" + +#define DOC_FONTGETMETRICS "Font.get_metrics(text, bbmode=BBOX_PIXEL_GRIDFIT, ptsize=default): return [(...), ...]\nGets glyph metrics for the font's characters" + +#define DOC_FONTHEIGHT "Font.height: return int\nGets the height of the Font" + +#define DOC_FONTRENDER "Font.render(dest, text, fgcolor, bgcolor=None, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (Surface, int, int)\nRenders text on a surface" + +#define DOC_FONTSTYLE "Font.style: return int\nGets or sets the font's style" + +#define DOC_FONTUNDERLINE "Font.underline: return bool\nGets or sets the font's underline style" + +#define DOC_FONTBOLD "Font.bold: return bool\nGets or sets the font's bold style" + +#define DOC_FONTITALIC "Font.italic: return bool\nGets or sets the font's italic style" + +#define DOC_FONTFIXEDWIDTH "Font.fixed_width: return bool\nGets whether the font is fixed-width" + +#define DOC_FONTANTIALIASED "Font.antialiased: return bool\nFont antialiasing mode" + +#define DOC_FONTVERTICAL "Font.vertical: return bool\nFont vertical mode" + +#define DOC_ "" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.freetype + Enhanced Pygame module for loading and rendering fonts + + + +pygame.freetype.get_error + pygame.freetype.get_error(): return str +Get the latest error + + + +pygame.freetype.get_version + pygame.freetype.get_version(): return (int, int, int) +Get the FreeType version + + + +pygame.freetype.init + pygame.freetype.init(default_cache_size=64): return None +Initialize the underlying FreeType 2 library. + + + +pygame.freetype.quit + pygame.freetype.quit(): return None +Shuts down the underlying FreeType 2 library. + + + +pygame.freetype.was_init + pygame.freetype.quit(): return bool +Returns whether the the FreeType 2 library is initialized. + + + +pygame.freetype.Font + pygame.freetype.Font(file, style=STYLE_NONE, ptsize=-1, face_index=0): return Font +Creates a new Font from a supported font file. + + + +Font.name + Font.name: return string +Gets the name of the font face. + + + +Font.get_size + Font.get_size(text, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (int, int) +Gets the size of rendered text + + + +Font.get_metrics + Font.get_metrics(text, bbmode=BBOX_PIXEL_GRIDFIT, ptsize=default): return [(...), ...] +Gets glyph metrics for the font's characters + + + +Font.height + Font.height: return int +Gets the height of the Font + + + +Font.render + Font.render(dest, text, fgcolor, bgcolor=None, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (Surface, int, int) +Renders text on a surface + + + +Font.style + Font.style: return int +Gets or sets the font's style + + + +Font.underline + Font.underline: return bool +Gets or sets the font's underline style + + + +Font.bold + Font.bold: return bool +Gets or sets the font's bold style + + + +Font.italic + Font.italic: return bool +Gets or sets the font's italic style + + + +Font.fixed_width + Font.fixed_width: return bool +Gets whether the font is fixed-width + + + +Font.antialiased + Font.antialiased: return bool +Font antialiasing mode + + + +Font.vertical + Font.vertical: return bool +Font vertical mode + + + + + + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/gfxdraw_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,193 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEGFXDRAW "pygame module for drawing shapes" + +#define DOC_PYGAMEGFXDRAWPIXEL "pygame.gfxdraw.pixel(surface, x, y, color): return None\nplace a pixel" + +#define DOC_PYGAMEGFXDRAWHLINE "pygame.gfxdraw.hline(surface, x1, x2, y, color): return None\ndraw a horizontal line" + +#define DOC_PYGAMEGFXDRAWVLINE "pgyame.gfxdraw.vline(surface, x, y1, y2, color): return None\ndraw a vertical line" + +#define DOC_PYGAMEGFXDRAWRECTANGLE "pgyame.gfxdraw.rectangle(surface, rect, color): return None\ndraw a rectangle" + +#define DOC_PYGAMEGFXDRAWBOX "pgyame.gfxdraw.box(surface, rect, color): return None\ndraw a box" + +#define DOC_PYGAMEGFXDRAWLINE "pgyame.gfxdraw.line(surface, x1, y1, x2, y2, color): return None\ndraw a line" + +#define DOC_PYGAMEGFXDRAWCIRCLE "pgyame.gfxdraw.circle(surface, x, y, r, color): return None\ndraw a circle" + +#define DOC_PYGAMEGFXDRAWARC "pgyame.gfxdraw.arc(surface, x, y, r, start, end, color): return None\ndraw an arc" + +#define DOC_PYGAMEGFXDRAWAACIRCLE "pgyame.gfxdraw.aacircle(surface, x, y, r, color): return None\ndraw an anti-aliased circle" + +#define DOC_PYGAMEGFXDRAWFILLEDCIRCLE "pgyame.gfxdraw.filled_circle(surface, x, y, r, color): return None\ndraw a filled circle" + +#define DOC_PYGAMEGFXDRAWELLIPSE "pgyame.gfxdraw.ellipse(surface, x, y, rx, ry, color): return None\ndraw an ellipse" + +#define DOC_PYGAMEGFXDRAWAAELLIPSE "pgyame.gfxdraw.aaellipse(surface, x, y, rx, ry, color): return None\ndraw an anti-aliased ellipse" + +#define DOC_PYGAMEGFXDRAWFILLEDELLIPSE "pgyame.gfxdraw.filled_ellipse(surface, x, y, rx, ry, color): return None\ndraw a filled ellipse" + +#define DOC_PYGAMEGFXDRAWPIE "pgyame.gfxdraw.pie(surface, x, y, r, start, end, color): return None\ndraw a pie" + +#define DOC_PYGAMEGFXDRAWTRIGON "pgyame.gfxdraw.trigon(surface, x1, y1, x2, y2, x3, y3, color): return None\ndraw a triangle" + +#define DOC_PYGAMEGFXDRAWAATRIGON "pgyame.gfxdraw.aatrigon(surface, x1, y1, x2, y2, x3, y3, color): return None\ndraw an anti-aliased triangle" + +#define DOC_PYGAMEGFXDRAWFILLEDTRIGON "pgyame.gfxdraw.filled_trigon(surface, x1, y1, x3, y2, x3, y3, color): return None\ndraw a filled trigon" + +#define DOC_PYGAMEGFXDRAWPOLYGON "pgyame.gfxdraw.polygon(surface, points, color): return None\ndraw a polygon" + +#define DOC_PYGAMEGFXDRAWAAPOLYGON "pgyame.gfxdraw.aapolygon(surface, points, color): return None\ndraw an anti-aliased polygon" + +#define DOC_PYGAMEGFXDRAWFILLEDPOLYGON "pgyame.gfxdraw.filled_polygon(surface, points, color): return None\ndraw a filled polygon" + +#define DOC_PYGAMEGFXDRAWTEXTUREDPOLYGON "pgyame.gfxdraw.textured_polygon(surface, points, texture, tx, ty): return None\ndraw a textured polygon" + +#define DOC_PYGAMEGFXDRAWBEZIER "pgyame.gfxdraw.bezier(surface, points, steps, color): return None\ndraw a bezier curve" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.gfxdraw + pygame module for drawing shapes + + + +pygame.gfxdraw.pixel + pygame.gfxdraw.pixel(surface, x, y, color): return None +place a pixel + + + +pygame.gfxdraw.hline + pygame.gfxdraw.hline(surface, x1, x2, y, color): return None +draw a horizontal line + + + +pygame.gfxdraw.vline + pgyame.gfxdraw.vline(surface, x, y1, y2, color): return None +draw a vertical line + + + +pygame.gfxdraw.rectangle + pgyame.gfxdraw.rectangle(surface, rect, color): return None +draw a rectangle + + + +pygame.gfxdraw.box + pgyame.gfxdraw.box(surface, rect, color): return None +draw a box + + + +pygame.gfxdraw.line + pgyame.gfxdraw.line(surface, x1, y1, x2, y2, color): return None +draw a line + + + +pygame.gfxdraw.circle + pgyame.gfxdraw.circle(surface, x, y, r, color): return None +draw a circle + + + +pygame.gfxdraw.arc + pgyame.gfxdraw.arc(surface, x, y, r, start, end, color): return None +draw an arc + + + +pygame.gfxdraw.aacircle + pgyame.gfxdraw.aacircle(surface, x, y, r, color): return None +draw an anti-aliased circle + + + +pygame.gfxdraw.filled_circle + pgyame.gfxdraw.filled_circle(surface, x, y, r, color): return None +draw a filled circle + + + +pygame.gfxdraw.ellipse + pgyame.gfxdraw.ellipse(surface, x, y, rx, ry, color): return None +draw an ellipse + + + +pygame.gfxdraw.aaellipse + pgyame.gfxdraw.aaellipse(surface, x, y, rx, ry, color): return None +draw an anti-aliased ellipse + + + +pygame.gfxdraw.filled_ellipse + pgyame.gfxdraw.filled_ellipse(surface, x, y, rx, ry, color): return None +draw a filled ellipse + + + +pygame.gfxdraw.pie + pgyame.gfxdraw.pie(surface, x, y, r, start, end, color): return None +draw a pie + + + +pygame.gfxdraw.trigon + pgyame.gfxdraw.trigon(surface, x1, y1, x2, y2, x3, y3, color): return None +draw a triangle + + + +pygame.gfxdraw.aatrigon + pgyame.gfxdraw.aatrigon(surface, x1, y1, x2, y2, x3, y3, color): return None +draw an anti-aliased triangle + + + +pygame.gfxdraw.filled_trigon + pgyame.gfxdraw.filled_trigon(surface, x1, y1, x3, y2, x3, y3, color): return None +draw a filled trigon + + + +pygame.gfxdraw.polygon + pgyame.gfxdraw.polygon(surface, points, color): return None +draw a polygon + + + +pygame.gfxdraw.aapolygon + pgyame.gfxdraw.aapolygon(surface, points, color): return None +draw an anti-aliased polygon + + + +pygame.gfxdraw.filled_polygon + pgyame.gfxdraw.filled_polygon(surface, points, color): return None +draw a filled polygon + + + +pygame.gfxdraw.textured_polygon + pgyame.gfxdraw.textured_polygon(surface, points, texture, tx, ty): return None +draw a textured polygon + + + +pygame.gfxdraw.bezier + pgyame.gfxdraw.bezier(surface, points, steps, color): return None +draw a bezier curve + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/image_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,66 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEIMAGE "pygame module for image transfer" + +#define DOC_PYGAMEIMAGELOAD "pygame.image.load(filename): return Surface\npygame.image.load(fileobj, namehint=""): return Surface\nload new image from a file" + +#define DOC_PYGAMEIMAGESAVE "pygame.image.save(Surface, filename): return None\nsave an image to disk" + +#define DOC_PYGAMEIMAGEGETEXTENDED "pygame.image.get_extended(): return bool\ntest if extended image formats can be loaded" + +#define DOC_PYGAMEIMAGETOSTRING "pygame.image.tostring(Surface, format, flipped=False): return string\ntransfer image to string buffer" + +#define DOC_PYGAMEIMAGEFROMSTRING "pygame.image.fromstring(string, size, format, flipped=False): return Surface\ncreate new Surface from a string buffer" + +#define DOC_PYGAMEIMAGEFROMBUFFER "pygame.image.frombuffer(string, size, format): return Surface\ncreate a new Surface that shares data inside a string buffer" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.image + pygame module for image transfer + + + +pygame.image.load + pygame.image.load(filename): return Surface +pygame.image.load(fileobj, namehint=""): return Surface +load new image from a file + + + +pygame.image.save + pygame.image.save(Surface, filename): return None +save an image to disk + + + +pygame.image.get_extended + pygame.image.get_extended(): return bool +test if extended image formats can be loaded + + + +pygame.image.tostring + pygame.image.tostring(Surface, format, flipped=False): return string +transfer image to string buffer + + + +pygame.image.fromstring + pygame.image.fromstring(string, size, format, flipped=False): return Surface +create new Surface from a string buffer + + + +pygame.image.frombuffer + pygame.image.frombuffer(string, size, format): return Surface +create a new Surface that shares data inside a string buffer + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/joystick_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,161 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEJOYSTICK "pygame module for interacting with joystick devices" + +#define DOC_PYGAMEJOYSTICKINIT "pygame.joystick.init(): return None\ninitialize the joystick module" + +#define DOC_PYGAMEJOYSTICKQUIT "pygame.joystick.quit(): return None\nuninitialize the joystick module" + +#define DOC_PYGAMEJOYSTICKGETINIT "pygame.joystick.get_init(): return bool\ntrue if the joystick module is initialized" + +#define DOC_PYGAMEJOYSTICKGETCOUNT "pygame.joystick.get_count(): return count\nnumber of joysticks on the system" + +#define DOC_PYGAMEJOYSTICKJOYSTICK "pygame.joystick.Joystick(id): return Joystick\ncreate a new Joystick object" + +#define DOC_JOYSTICKINIT "Joystick.init(): return None\ninitialize the Joystick" + +#define DOC_JOYSTICKQUIT "Joystick.quit(): return None\nuninitialize the Joystick" + +#define DOC_JOYSTICKGETINIT "Joystick.get_init(): return bool\ncheck if the Joystick is initialized" + +#define DOC_JOYSTICKGETID "Joystick.get_id(): return int\nget the Joystick ID" + +#define DOC_JOYSTICKGETNAME "Joystick.get_name(): return string\nget the Joystick system name" + +#define DOC_JOYSTICKGETNUMAXES "Joystick.get_numaxes(): return int\nget the number of axes on a Joystick" + +#define DOC_JOYSTICKGETAXIS "Joystick.get_axis(axis_number): return float\nget the current position of an axis" + +#define DOC_JOYSTICKGETNUMBALLS "Joystick.get_numballs(): return int\nget the number of trackballs on a Joystick" + +#define DOC_JOYSTICKGETBALL "Joystick.get_ball(ball_number): return x, y\nget the relative position of a trackball" + +#define DOC_JOYSTICKGETNUMBUTTONS "Joystick.get_numbuttons(): return int\nget the number of buttons on a Joystick" + +#define DOC_JOYSTICKGETBUTTON "Joystick.get_button(button): return bool\nget the current button state" + +#define DOC_JOYSTICKGETNUMHATS "Joystick.get_numhats(): return int\nget the number of hat controls on a Joystick" + +#define DOC_JOYSTICKGETHAT "Joystick.get_hat(hat_number): return x, y\nget the position of a joystick hat" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.joystick + pygame module for interacting with joystick devices + + + +pygame.joystick.init + pygame.joystick.init(): return None +initialize the joystick module + + + +pygame.joystick.quit + pygame.joystick.quit(): return None +uninitialize the joystick module + + + +pygame.joystick.get_init + pygame.joystick.get_init(): return bool +true if the joystick module is initialized + + + +pygame.joystick.get_count + pygame.joystick.get_count(): return count +number of joysticks on the system + + + +pygame.joystick.Joystick + pygame.joystick.Joystick(id): return Joystick +create a new Joystick object + + + +Joystick.init + Joystick.init(): return None +initialize the Joystick + + + +Joystick.quit + Joystick.quit(): return None +uninitialize the Joystick + + + +Joystick.get_init + Joystick.get_init(): return bool +check if the Joystick is initialized + + + +Joystick.get_id + Joystick.get_id(): return int +get the Joystick ID + + + +Joystick.get_name + Joystick.get_name(): return string +get the Joystick system name + + + +Joystick.get_numaxes + Joystick.get_numaxes(): return int +get the number of axes on a Joystick + + + +Joystick.get_axis + Joystick.get_axis(axis_number): return float +get the current position of an axis + + + +Joystick.get_numballs + Joystick.get_numballs(): return int +get the number of trackballs on a Joystick + + + +Joystick.get_ball + Joystick.get_ball(ball_number): return x, y +get the relative position of a trackball + + + +Joystick.get_numbuttons + Joystick.get_numbuttons(): return int +get the number of buttons on a Joystick + + + +Joystick.get_button + Joystick.get_button(button): return bool +get the current button state + + + +Joystick.get_numhats + Joystick.get_numhats(): return int +get the number of hat controls on a Joystick + + + +Joystick.get_hat + Joystick.get_hat(hat_number): return x, y +get the position of a joystick hat + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/key_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,74 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEKEY "pygame module to work with the keyboard" + +#define DOC_PYGAMEKEYGETFOCUSED "pygame.key.get_focused(): return bool\ntrue if the display is receiving keyboard input from the system" + +#define DOC_PYGAMEKEYGETPRESSED "pygame.key.get_pressed(): return bools\nget the state of all keyboard buttons" + +#define DOC_PYGAMEKEYGETMODS "pygame.key.get_mods(): return int\ndetermine which modifier keys are being held" + +#define DOC_PYGAMEKEYSETMODS "pygame.key.set_mods(int): return None\ntemporarily set which modifier keys are pressed" + +#define DOC_PYGAMEKEYSETREPEAT "pygame.key.set_repeat(): return None\npygame.key.set_repeat(delay, interval): return None\ncontrol how held keys are repeated" + +#define DOC_PYGAMEKEYGETREPEAT "pygame.key.get_repeat(): return (delay, interval)\nsee how held keys are repeated" + +#define DOC_PYGAMEKEYNAME "pygame.key.name(key): return string\nget the name of a key identifier" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.key + pygame module to work with the keyboard + + + +pygame.key.get_focused + pygame.key.get_focused(): return bool +true if the display is receiving keyboard input from the system + + + +pygame.key.get_pressed + pygame.key.get_pressed(): return bools +get the state of all keyboard buttons + + + +pygame.key.get_mods + pygame.key.get_mods(): return int +determine which modifier keys are being held + + + +pygame.key.set_mods + pygame.key.set_mods(int): return None +temporarily set which modifier keys are pressed + + + +pygame.key.set_repeat + pygame.key.set_repeat(): return None +pygame.key.set_repeat(delay, interval): return None +control how held keys are repeated + + + +pygame.key.get_repeat + pygame.key.get_repeat(): return (delay, interval) +see how held keys are repeated + + + +pygame.key.name + pygame.key.name(key): return string +get the name of a key identifier + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/locals_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,17 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMELOCALS "pygame constants" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.locals + pygame constants + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/mask_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,201 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEMASK "pygame module for image masks." + +#define DOC_PYGAMEMASKFROMSURFACE "pygame.mask.from_surface(Surface, threshold = 127) -> Mask\nReturns a Mask from the given surface." + +#define DOC_PYGAMEMASKFROMTHRESHOLD "pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None, palette_colors = 1) -> Mask\nCreates a mask by thresholding Surfaces" + +#define DOC_PYGAMEMASKMASK "pygame.Mask((width, height)): return Mask\npygame object for representing 2d bitmasks" + +#define DOC_MASKGETSIZE "Mask.get_size() -> width,height\nReturns the size of the mask." + +#define DOC_MASKGETAT "Mask.get_at((x,y)) -> int\nReturns nonzero if the bit at (x,y) is set." + +#define DOC_MASKSETAT "Mask.set_at((x,y),value)\nSets the position in the mask given by x and y." + +#define DOC_MASKOVERLAP "Mask.overlap(othermask, offset) -> x,y\nReturns the point of intersection if the masks overlap with the given offset - or None if it does not overlap." + +#define DOC_MASKOVERLAPAREA "Mask.overlap_area(othermask, offset) -> numpixels\nReturns the number of overlapping 'pixels'." + +#define DOC_MASKOVERLAPMASK "Mask.overlap_mask(othermask, offset) -> Mask\nReturns a mask of the overlapping pixels" + +#define DOC_MASKFILL "Mask.fill()\nSets all bits to 1" + +#define DOC_MASKCLEAR "Mask.clear()\nSets all bits to 0" + +#define DOC_MASKINVERT "Mask.invert()\nFlips the bits in a Mask" + +#define DOC_MASKSCALE "Mask.scale((x, y)) -> Mask\nResizes a mask" + +#define DOC_MASKDRAW "Mask.draw(othermask, offset)\nDraws a mask onto another" + +#define DOC_MASKERASE "Mask.erase(othermask, offset)\nErases a mask from another" + +#define DOC_MASKCOUNT "Mask.count() -> pixels\nReturns the number of set pixels" + +#define DOC_MASKCENTROID "Mask.centroid() -> (x, y)\nReturns the centroid of the pixels in a Mask" + +#define DOC_MASKANGLE "Mask.angle() -> theta\nReturns the orientation of the pixels" + +#define DOC_MASKOUTLINE "Mask.outline(every = 1) -> [(x,y), (x,y) ...]\nlist of points outlining an object" + +#define DOC_MASKCONVOLVE "Mask.convolve(othermask, outputmask = None, offset = (0,0)) -> Mask\nReturn the convolution of self with another mask." + +#define DOC_MASKCONNECTEDCOMPONENT "Mask.connected_component((x,y) = None) -> Mask\nReturns a mask of a connected region of pixels." + +#define DOC_MASKCONNECTEDCOMPONENTS "Mask.connected_components(min = 0) -> [Masks]\nReturns a list of masks of connected regions of pixels." + +#define DOC_MASKGETBOUNDINGRECTS "Mask.get_bounding_rects() -> Rects\nReturns a list of bounding rects of regions of set pixels." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.mask + pygame module for image masks. + + + +pygame.mask.from_surface + pygame.mask.from_surface(Surface, threshold = 127) -> Mask +Returns a Mask from the given surface. + + + +pygame.mask.from_threshold + pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None, palette_colors = 1) -> Mask +Creates a mask by thresholding Surfaces + + + +pygame.mask.Mask + pygame.Mask((width, height)): return Mask +pygame object for representing 2d bitmasks + + + +Mask.get_size + Mask.get_size() -> width,height +Returns the size of the mask. + + + +Mask.get_at + Mask.get_at((x,y)) -> int +Returns nonzero if the bit at (x,y) is set. + + + +Mask.set_at + Mask.set_at((x,y),value) +Sets the position in the mask given by x and y. + + + +Mask.overlap + Mask.overlap(othermask, offset) -> x,y +Returns the point of intersection if the masks overlap with the given offset - or None if it does not overlap. + + + +Mask.overlap_area + Mask.overlap_area(othermask, offset) -> numpixels +Returns the number of overlapping 'pixels'. + + + +Mask.overlap_mask + Mask.overlap_mask(othermask, offset) -> Mask +Returns a mask of the overlapping pixels + + + +Mask.fill + Mask.fill() +Sets all bits to 1 + + + +Mask.clear + Mask.clear() +Sets all bits to 0 + + + +Mask.invert + Mask.invert() +Flips the bits in a Mask + + + +Mask.scale + Mask.scale((x, y)) -> Mask +Resizes a mask + + + +Mask.draw + Mask.draw(othermask, offset) +Draws a mask onto another + + + +Mask.erase + Mask.erase(othermask, offset) +Erases a mask from another + + + +Mask.count + Mask.count() -> pixels +Returns the number of set pixels + + + +Mask.centroid + Mask.centroid() -> (x, y) +Returns the centroid of the pixels in a Mask + + + +Mask.angle + Mask.angle() -> theta +Returns the orientation of the pixels + + + +Mask.outline + Mask.outline(every = 1) -> [(x,y), (x,y) ...] +list of points outlining an object + + + +Mask.convolve + Mask.convolve(othermask, outputmask = None, offset = (0,0)) -> Mask +Return the convolution of self with another mask. + + + +Mask.connected_component + Mask.connected_component((x,y) = None) -> Mask +Returns a mask of a connected region of pixels. + + + +Mask.connected_components + Mask.connected_components(min = 0) -> [Masks] +Returns a list of masks of connected regions of pixels. + + + +Mask.get_bounding_rects + Mask.get_bounding_rects() -> Rects +Returns a list of bounding rects of regions of set pixels. + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/midi_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,198 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEMIDI "pygame module for interacting with midi input and output." + +#define DOC_PYGAMEMIDIINPUT "Input(device_id)\nInput(device_id, buffer_size)\nInput is used to get midi input from midi devices." + +#define DOC_INPUTCLOSE "Input.close(): return None\n closes a midi stream, flushing any pending buffers." + +#define DOC_INPUTPOLL "Input.poll(): return Bool\nreturns true if there's data, or false if not." + +#define DOC_INPUTREAD "Input.read(num_events): return midi_event_list\nreads num_events midi events from the buffer." + +#define DOC_PYGAMEMIDIMIDIEXCEPTION "MidiException(errno)\nexception that pygame.midi functions and classes can raise" + +#define DOC_PYGAMEMIDIOUTPUT "Output(device_id)\nOutput(device_id, latency = 0)\nOutput(device_id, buffer_size = 4096)\nOutput(device_id, latency, buffer_size)\nOutput is used to send midi to an output device" + +#define DOC_OUTPUTABORT "Output.abort(): return None\n terminates outgoing messages immediately" + +#define DOC_OUTPUTCLOSE "Output.close(): return None\n closes a midi stream, flushing any pending buffers." + +#define DOC_OUTPUTNOTEOFF "Output.note_off(note, velocity=None, channel = 0)\nturns a midi note off. Note must be on." + +#define DOC_OUTPUTNOTEON "Output.note_on(note, velocity=None, channel = 0)\nturns a midi note on. Note must be off." + +#define DOC_OUTPUTSETINSTRUMENT "Output.set_instrument(instrument_id, channel = 0)\nselect an instrument, with a value between 0 and 127" + +#define DOC_OUTPUTWRITE "Output.write(data)\nwrites a list of midi data to the Output" + +#define DOC_OUTPUTWRITESHORT "Output.write_short(status)\nOutput.write_short(status, data1 = 0, data2 = 0)\nwrite_short(status <, data1><, data2>)" + +#define DOC_OUTPUTWRITESYSEX "Output.write_sys_ex(when, msg)\nwrites a timestamped system-exclusive midi message." + +#define DOC_PYGAMEMIDIGETCOUNT "pygame.midi.get_count(): return num_devices\ngets the number of devices." + +#define DOC_PYGAMEMIDIGETDEFAULTINPUTID "pygame.midi.get_default_input_id(): return default_id\ngets default input device number" + +#define DOC_PYGAMEMIDIGETDEFAULTOUTPUTID "pygame.midi.get_default_output_id(): return default_id\ngets default output device number" + +#define DOC_PYGAMEMIDIGETDEVICEINFO "pygame.midi.get_device_info(an_id): return (interf, name, input, output, opened)\n returns information about a midi device" + +#define DOC_PYGAMEMIDIINIT "pygame.midi.init(): return None\ninitialize the midi module" + +#define DOC_PYGAMEMIDIMIDIS2EVENTS "pygame.midi.midis2events(midis, device_id): return [Event, ...]\nconverts midi events to pygame events" + +#define DOC_PYGAMEMIDIQUIT "pygame.midi.quit(): return None\nuninitialize the midi module" + +#define DOC_PYGAMEMIDITIME "pygame.midi.time(): return time\nreturns the current time in ms of the PortMidi timer" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.midi + pygame module for interacting with midi input and output. + + + +pygame.midi.Input + Input(device_id) +Input(device_id, buffer_size) +Input is used to get midi input from midi devices. + + + +Input.close + Input.close(): return None + closes a midi stream, flushing any pending buffers. + + + +Input.poll + Input.poll(): return Bool +returns true if there's data, or false if not. + + + +Input.read + Input.read(num_events): return midi_event_list +reads num_events midi events from the buffer. + + + +pygame.midi.MidiException + MidiException(errno) +exception that pygame.midi functions and classes can raise + + + +pygame.midi.Output + Output(device_id) +Output(device_id, latency = 0) +Output(device_id, buffer_size = 4096) +Output(device_id, latency, buffer_size) +Output is used to send midi to an output device + + + +Output.abort + Output.abort(): return None + terminates outgoing messages immediately + + + +Output.close + Output.close(): return None + closes a midi stream, flushing any pending buffers. + + + +Output.note_off + Output.note_off(note, velocity=None, channel = 0) +turns a midi note off. Note must be on. + + + +Output.note_on + Output.note_on(note, velocity=None, channel = 0) +turns a midi note on. Note must be off. + + + +Output.set_instrument + Output.set_instrument(instrument_id, channel = 0) +select an instrument, with a value between 0 and 127 + + + +Output.write + Output.write(data) +writes a list of midi data to the Output + + + +Output.write_short + Output.write_short(status) +Output.write_short(status, data1 = 0, data2 = 0) +write_short(status <, data1><, data2>) + + + +Output.write_sys_ex + Output.write_sys_ex(when, msg) +writes a timestamped system-exclusive midi message. + + + +pygame.midi.get_count + pygame.midi.get_count(): return num_devices +gets the number of devices. + + + +pygame.midi.get_default_input_id + pygame.midi.get_default_input_id(): return default_id +gets default input device number + + + +pygame.midi.get_default_output_id + pygame.midi.get_default_output_id(): return default_id +gets default output device number + + + +pygame.midi.get_device_info + pygame.midi.get_device_info(an_id): return (interf, name, input, output, opened) + returns information about a midi device + + + +pygame.midi.init + pygame.midi.init(): return None +initialize the midi module + + + +pygame.midi.midis2events + pygame.midi.midis2events(midis, device_id): return [Event, ...] +converts midi events to pygame events + + + +pygame.midi.quit + pygame.midi.quit(): return None +uninitialize the midi module + + + +pygame.midi.time + pygame.midi.time(): return time +returns the current time in ms of the PortMidi timer + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/mixer_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,308 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEMIXER "pygame module for loading and playing sounds" + +#define DOC_PYGAMEMIXERINIT "pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096): return None\ninitialize the mixer module" + +#define DOC_PYGAMEMIXERPREINIT "pygame.mixer.pre_init(frequency=22050, size=-16, channels=2, buffersize=4096): return None\npreset the mixer init arguments" + +#define DOC_PYGAMEMIXERQUIT "pygame.mixer.quit(): return None\nuninitialize the mixer" + +#define DOC_PYGAMEMIXERGETINIT "pygame.mixer.get_init(): return (frequency, format, channels)\ntest if the mixer is initialized" + +#define DOC_PYGAMEMIXERSTOP "pygame.mixer.stop(): return None\nstop playback of all sound channels" + +#define DOC_PYGAMEMIXERPAUSE "pygame.mixer.pause(): return None\ntemporarily stop playback of all sound channels" + +#define DOC_PYGAMEMIXERUNPAUSE "pygame.mixer.unpause(): return None\nresume paused playback of sound channels" + +#define DOC_PYGAMEMIXERFADEOUT "pygame.mixer.fadeout(time): return None\nfade out the volume on all sounds before stopping" + +#define DOC_PYGAMEMIXERSETNUMCHANNELS "pygame.mixer.set_num_channels(count): return None\nset the total number of playback channels" + +#define DOC_PYGAMEMIXERGETNUMCHANNELS "get the total number of playback channels" + +#define DOC_PYGAMEMIXERSETRESERVED "pygame.mixer.set_reserved(count): return None\nreserve channels from being automatically used" + +#define DOC_PYGAMEMIXERFINDCHANNEL "pygame.mixer.find_channel(force=False): return Channel\nfind an unused channel" + +#define DOC_PYGAMEMIXERGETBUSY "pygame.mixer.get_busy(): return bool\ntest if any sound is being mixed" + +#define DOC_PYGAMEMIXERSOUND "pygame.mixer.Sound(filename): return Sound\npygame.mixer.Sound(buffer): return Sound\npygame.mixer.Sound(object): return Sound\nCreate a new Sound object from a file" + +#define DOC_SOUNDPLAY "Sound.play(loops=0, maxtime=0, fade_ms=0): return Channel\nbegin sound playback" + +#define DOC_SOUNDSTOP "Sound.stop(): return None\nstop sound playback" + +#define DOC_SOUNDFADEOUT "Sound.fadeout(time): return None\nstop sound playback after fading out" + +#define DOC_SOUNDSETVOLUME "Sound.set_volume(value): return None\nset the playback volume for this Sound" + +#define DOC_SOUNDGETVOLUME "Sound.get_volume(): return value\nget the playback volume" + +#define DOC_SOUNDGETNUMCHANNELS "Sound.get_num_channels(): return count\ncount how many times this Sound is playing" + +#define DOC_SOUNDGETLENGTH "Sound.get_length(): return seconds\nget the length of the Sound" + +#define DOC_SOUNDGETBUFFER "Sound.get_buffer(): return BufferProxy\nacquires a buffer object for the sameples of the Sound." + +#define DOC_PYGAMEMIXERCHANNEL "pygame.mixer.Channel(id): return Channel\nCreate a Channel object for controlling playback" + +#define DOC_CHANNELPLAY "Channel.play(Sound, loops=0, maxtime=0, fade_ms=0): return None\nplay a Sound on a specific Channel" + +#define DOC_CHANNELSTOP "Channel.stop(): return None\nstop playback on a Channel" + +#define DOC_CHANNELPAUSE "Channel.pause(): return None\ntemporarily stop playback of a channel" + +#define DOC_CHANNELUNPAUSE "Channel.unpause(): return None\nresume pause playback of a channel" + +#define DOC_CHANNELFADEOUT "Channel.fadeout(time): return None\nstop playback after fading channel out" + +#define DOC_CHANNELSETVOLUME "Channel.set_volume(value): return None\nChannel.set_volume(left, right): return None\nset the volume of a playing channel" + +#define DOC_CHANNELGETVOLUME "Channel.get_volume(): return value\nget the volume of the playing channel" + +#define DOC_CHANNELGETBUSY "Channel.get_busy(): return bool\ncheck if the channel is active" + +#define DOC_CHANNELGETSOUND "Channel.get_sound(): return Sound\nget the currently playing Sound" + +#define DOC_CHANNELQUEUE "Channel.queue(Sound): return None\nqueue a Sound object to follow the current" + +#define DOC_CHANNELGETQUEUE "Channel.get_queue(): return Sound\nreturn any Sound that is queued" + +#define DOC_CHANNELSETENDEVENT "Channel.set_endevent(): return None\nChannel.set_endevent(type): return None\nhave the channel send an event when playback stops" + +#define DOC_CHANNELGETENDEVENT "Channel.get_endevent(): return type\nget the event a channel sends when playback stops" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.mixer + pygame module for loading and playing sounds + + + +pygame.mixer.init + pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096): return None +initialize the mixer module + + + +pygame.mixer.pre_init + pygame.mixer.pre_init(frequency=22050, size=-16, channels=2, buffersize=4096): return None +preset the mixer init arguments + + + +pygame.mixer.quit + pygame.mixer.quit(): return None +uninitialize the mixer + + + +pygame.mixer.get_init + pygame.mixer.get_init(): return (frequency, format, channels) +test if the mixer is initialized + + + +pygame.mixer.stop + pygame.mixer.stop(): return None +stop playback of all sound channels + + + +pygame.mixer.pause + pygame.mixer.pause(): return None +temporarily stop playback of all sound channels + + + +pygame.mixer.unpause + pygame.mixer.unpause(): return None +resume paused playback of sound channels + + + +pygame.mixer.fadeout + pygame.mixer.fadeout(time): return None +fade out the volume on all sounds before stopping + + + +pygame.mixer.set_num_channels + pygame.mixer.set_num_channels(count): return None +set the total number of playback channels + + + +pygame.mixer.get_num_channels + get the total number of playback channels + + + +pygame.mixer.set_reserved + pygame.mixer.set_reserved(count): return None +reserve channels from being automatically used + + + +pygame.mixer.find_channel + pygame.mixer.find_channel(force=False): return Channel +find an unused channel + + + +pygame.mixer.get_busy + pygame.mixer.get_busy(): return bool +test if any sound is being mixed + + + +pygame.mixer.Sound + pygame.mixer.Sound(filename): return Sound +pygame.mixer.Sound(buffer): return Sound +pygame.mixer.Sound(object): return Sound +Create a new Sound object from a file + + + +Sound.play + Sound.play(loops=0, maxtime=0, fade_ms=0): return Channel +begin sound playback + + + +Sound.stop + Sound.stop(): return None +stop sound playback + + + +Sound.fadeout + Sound.fadeout(time): return None +stop sound playback after fading out + + + +Sound.set_volume + Sound.set_volume(value): return None +set the playback volume for this Sound + + + +Sound.get_volume + Sound.get_volume(): return value +get the playback volume + + + +Sound.get_num_channels + Sound.get_num_channels(): return count +count how many times this Sound is playing + + + +Sound.get_length + Sound.get_length(): return seconds +get the length of the Sound + + + +Sound.get_buffer + Sound.get_buffer(): return BufferProxy +acquires a buffer object for the sameples of the Sound. + + + +pygame.mixer.Channel + pygame.mixer.Channel(id): return Channel +Create a Channel object for controlling playback + + + +Channel.play + Channel.play(Sound, loops=0, maxtime=0, fade_ms=0): return None +play a Sound on a specific Channel + + + +Channel.stop + Channel.stop(): return None +stop playback on a Channel + + + +Channel.pause + Channel.pause(): return None +temporarily stop playback of a channel + + + +Channel.unpause + Channel.unpause(): return None +resume pause playback of a channel + + + +Channel.fadeout + Channel.fadeout(time): return None +stop playback after fading channel out + + + +Channel.set_volume + Channel.set_volume(value): return None +Channel.set_volume(left, right): return None +set the volume of a playing channel + + + +Channel.get_volume + Channel.get_volume(): return value +get the volume of the playing channel + + + +Channel.get_busy + Channel.get_busy(): return bool +check if the channel is active + + + +Channel.get_sound + Channel.get_sound(): return Sound +get the currently playing Sound + + + +Channel.queue + Channel.queue(Sound): return None +queue a Sound object to follow the current + + + +Channel.get_queue + Channel.get_queue(): return Sound +return any Sound that is queued + + + +Channel.set_endevent + Channel.set_endevent(): return None +Channel.set_endevent(type): return None +have the channel send an event when playback stops + + + +Channel.get_endevent + Channel.get_endevent(): return type +get the event a channel sends when playback stops + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/mouse_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,81 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEMOUSE "pygame module to work with the mouse" + +#define DOC_PYGAMEMOUSEGETPRESSED "pygame.moouse.get_pressed(): return (button1, button2, button3)\nget the state of the mouse buttons" + +#define DOC_PYGAMEMOUSEGETPOS "pygame.mouse.get_pos(): return (x, y)\nget the mouse cursor position" + +#define DOC_PYGAMEMOUSEGETREL "pygame.mouse.get_rel(): return (x, y)\nget the amount of mouse movement" + +#define DOC_PYGAMEMOUSESETPOS "pygame.mouse.set_pos([x, y]): return None\nset the mouse cursor position" + +#define DOC_PYGAMEMOUSESETVISIBLE "pygame.mouse.set_visible(bool): return bool\nhide or show the mouse cursor" + +#define DOC_PYGAMEMOUSEGETFOCUSED "pygame.mouse.get_focused(): return bool\ncheck if the display is receiving mouse input" + +#define DOC_PYGAMEMOUSESETCURSOR "pygame.mouse.set_cursor(size, hotspot, xormasks, andmasks): return None\nset the image for the system mouse cursor" + +#define DOC_PYGAMEMOUSEGETCURSOR "pygame.mouse.get_cursor(): return (size, hotspot, xormasks, andmasks)\nget the image for the system mouse cursor" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.mouse + pygame module to work with the mouse + + + +pygame.mouse.get_pressed + pygame.moouse.get_pressed(): return (button1, button2, button3) +get the state of the mouse buttons + + + +pygame.mouse.get_pos + pygame.mouse.get_pos(): return (x, y) +get the mouse cursor position + + + +pygame.mouse.get_rel + pygame.mouse.get_rel(): return (x, y) +get the amount of mouse movement + + + +pygame.mouse.set_pos + pygame.mouse.set_pos([x, y]): return None +set the mouse cursor position + + + +pygame.mouse.set_visible + pygame.mouse.set_visible(bool): return bool +hide or show the mouse cursor + + + +pygame.mouse.get_focused + pygame.mouse.get_focused(): return bool +check if the display is receiving mouse input + + + +pygame.mouse.set_cursor + pygame.mouse.set_cursor(size, hotspot, xormasks, andmasks): return None +set the image for the system mouse cursor + + + +pygame.mouse.get_cursor + pygame.mouse.get_cursor(): return (size, hotspot, xormasks, andmasks) +get the image for the system mouse cursor + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/movie_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,146 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEMOVIE "pygame module for playback of mpeg video" + +#define DOC_PYGAMEMOVIEMOVIE "pygame.movie.Movie(filename): return Movie\npygame.movie.Movie(object): return Movie\nload an mpeg movie file" + +#define DOC_MOVIEPLAY "Movie.play(loops=0): return None\nstart playback of a movie" + +#define DOC_MOVIESTOP "Movie.stop(): return None\nstop movie playback" + +#define DOC_MOVIEPAUSE "Movie.pause(): return None\ntemporarily stop and resume playback" + +#define DOC_MOVIESKIP "Movie.skip(seconds): return None\nadvance the movie playback position" + +#define DOC_MOVIEREWIND "Movie.rewind(): return None\nrestart the movie playback" + +#define DOC_MOVIERENDERFRAME "Movie.render_frame(frame_number): return frame_number\nset the current video frame" + +#define DOC_MOVIEGETFRAME "Movie.get_frame(): return frame_number\nget the current video frame" + +#define DOC_MOVIEGETTIME "Movie.get_time(): return seconds\nget the current vide playback time" + +#define DOC_MOVIEGETBUSY "Movie.get_busy(): return bool\ncheck if the movie is currently playing" + +#define DOC_MOVIEGETLENGTH "Movie.get_length(): return seconds\nthe total length of the movie in seconds" + +#define DOC_MOVIEGETSIZE "Movie.get_size(): return (width, height)\nget the resolution of the video" + +#define DOC_MOVIEHASVIDEO "Movie.get_video(): return bool\ncheck if the movie file contains video" + +#define DOC_MOVIEHASAUDIO "Movie.get_audio(): return bool\ncheck if the movie file contains audio" + +#define DOC_MOVIESETVOLUME "Movie.set_volume(value): return None\nset the audio playback volume" + +#define DOC_MOVIESETDISPLAY "Movie.set_display(Surface, rect=None): return None\nset the video target Surface" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.movie + pygame module for playback of mpeg video + + + +pygame.movie.Movie + pygame.movie.Movie(filename): return Movie +pygame.movie.Movie(object): return Movie +load an mpeg movie file + + + +Movie.play + Movie.play(loops=0): return None +start playback of a movie + + + +Movie.stop + Movie.stop(): return None +stop movie playback + + + +Movie.pause + Movie.pause(): return None +temporarily stop and resume playback + + + +Movie.skip + Movie.skip(seconds): return None +advance the movie playback position + + + +Movie.rewind + Movie.rewind(): return None +restart the movie playback + + + +Movie.render_frame + Movie.render_frame(frame_number): return frame_number +set the current video frame + + + +Movie.get_frame + Movie.get_frame(): return frame_number +get the current video frame + + + +Movie.get_time + Movie.get_time(): return seconds +get the current vide playback time + + + +Movie.get_busy + Movie.get_busy(): return bool +check if the movie is currently playing + + + +Movie.get_length + Movie.get_length(): return seconds +the total length of the movie in seconds + + + +Movie.get_size + Movie.get_size(): return (width, height) +get the resolution of the video + + + +Movie.has_video + Movie.get_video(): return bool +check if the movie file contains video + + + +Movie.has_audio + Movie.get_audio(): return bool +check if the movie file contains audio + + + +Movie.set_volume + Movie.set_volume(value): return None +set the audio playback volume + + + +Movie.set_display + Movie.set_display(Surface, rect=None): return None +set the video target Surface + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/music_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,131 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEMIXERMUSIC "pygame module for controlling streamed audio" + +#define DOC_PYGAMEMIXERMUSICLOAD "pygame.mixer.music.load(filename): return None\npygame.mixer.music.load(object): return None\nLoad a music file for playback" + +#define DOC_PYGAMEMIXERMUSICPLAY "pygame.mixer.music.play(loops=0, start=0.0): return None\nStart the playback of the music stream" + +#define DOC_PYGAMEMIXERMUSICREWIND "pygame.mixer.music.rewind(): return None\nrestart music" + +#define DOC_PYGAMEMIXERMUSICSTOP "pygame.mixer.music.stop(): return None\nstop the music playback" + +#define DOC_PYGAMEMIXERMUSICPAUSE "pygame.mixer.music.pause(): return None\ntemporarily stop music playback" + +#define DOC_PYGAMEMIXERMUSICUNPAUSE "pygame.mixer.music.unpause(): return None\nresume paused music" + +#define DOC_PYGAMEMIXERMUSICFADEOUT "pygame.mixer.music.fadeout(time): return None\nstop music playback after fading out" + +#define DOC_PYGAMEMIXERMUSICSETVOLUME "pygame.mixer.music.set_volume(value): return None\nset the music volume" + +#define DOC_PYGAMEMIXERMUSICGETVOLUME "pygame.mixer.music.get_volume(): return value\nget the music volume" + +#define DOC_PYGAMEMIXERMUSICGETBUSY "pygame.mixer.music.get_busy(): return bool\ncheck if the music stream is playing" + +#define DOC_PYGAMEMIXERMUSICGETPOS "pygame.mixer.music.get_pos(): return time\nget the music play time" + +#define DOC_PYGAMEMIXERMUSICQUEUE "pygame.mixer.music.queue(filename): return None\nqueue a music file to follow the current" + +#define DOC_PYGAMEMIXERMUSICSETENDEVENT "pygame.mixer.music.set_endevent(): return None\npygame.mixer.music.set_endevent(type): return None\nhave the music send an event when playback stops" + +#define DOC_PYGAMEMIXERMUSICGETENDEVENT "pygame.mixer.music.get_endevent(): return type\nget the event a channel sends when playback stops" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.mixer.music + pygame module for controlling streamed audio + + + +pygame.mixer.music.load + pygame.mixer.music.load(filename): return None +pygame.mixer.music.load(object): return None +Load a music file for playback + + + +pygame.mixer.music.play + pygame.mixer.music.play(loops=0, start=0.0): return None +Start the playback of the music stream + + + +pygame.mixer.music.rewind + pygame.mixer.music.rewind(): return None +restart music + + + +pygame.mixer.music.stop + pygame.mixer.music.stop(): return None +stop the music playback + + + +pygame.mixer.music.pause + pygame.mixer.music.pause(): return None +temporarily stop music playback + + + +pygame.mixer.music.unpause + pygame.mixer.music.unpause(): return None +resume paused music + + + +pygame.mixer.music.fadeout + pygame.mixer.music.fadeout(time): return None +stop music playback after fading out + + + +pygame.mixer.music.set_volume + pygame.mixer.music.set_volume(value): return None +set the music volume + + + +pygame.mixer.music.get_volume + pygame.mixer.music.get_volume(): return value +get the music volume + + + +pygame.mixer.music.get_busy + pygame.mixer.music.get_busy(): return bool +check if the music stream is playing + + + +pygame.mixer.music.get_pos + pygame.mixer.music.get_pos(): return time +get the music play time + + + +pygame.mixer.music.queue + pygame.mixer.music.queue(filename): return None +queue a music file to follow the current + + + +pygame.mixer.music.set_endevent + pygame.mixer.music.set_endevent(): return None +pygame.mixer.music.set_endevent(type): return None +have the music send an event when playback stops + + + +pygame.mixer.music.get_endevent + pygame.mixer.music.get_endevent(): return type +get the event a channel sends when playback stops + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/overlay_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,43 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEOVERLAY "pygame.Overlay(format, (width, height)): return Overlay\npygame object for video overlay graphics" + +#define DOC_OVERLAYDISPLAY "Overlay.display((y, u, v)): return None\nOverlay.display(): return None\nset the overlay pixel data" + +#define DOC_OVERLAYSETLOCATION "Overlay.set_location(rect): return None\ncontrol where the overlay is displayed" + +#define DOC_OVERLAYGETHARDWARE "Overlay.get_hardware(rect): return int\ntest if the Overlay is hardware accelerated" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.Overlay + pygame.Overlay(format, (width, height)): return Overlay +pygame object for video overlay graphics + + + +Overlay.display + Overlay.display((y, u, v)): return None +Overlay.display(): return None +set the overlay pixel data + + + +Overlay.set_location + Overlay.set_location(rect): return None +control where the overlay is displayed + + + +Overlay.get_hardware + Overlay.get_hardware(rect): return int +test if the Overlay is hardware accelerated + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/pixelarray_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,58 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMEPIXELARRAY "pygame.PixelArray(Surface): return PixelArray\npygame object for direct pixel access of surfaces" + +#define DOC_PIXELARRAYSURFACE "PixelArray.surface: Return Surface\nGets the Surface the PixelArray uses." + +#define DOC_PIXELARRAYMAKESURFACE "PixelArray.make_surface (): Return Surface\nCreates a new Surface from the current PixelArray." + +#define DOC_PIXELARRAYREPLACE "PixelArray.replace (color, repcolor, distance=0, weights=(0.299, 0.587, 0.114)): Return None\nReplaces the passed color in the PixelArray with another one." + +#define DOC_PIXELARRAYEXTRACT "PixelArray.extract (color, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray\nExtracts the passed color from the PixelArray." + +#define DOC_PIXELARRAYCOMPARE "PixelArray.compare (array, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray\nCompares the PixelArray with another one." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.PixelArray + pygame.PixelArray(Surface): return PixelArray +pygame object for direct pixel access of surfaces + + + +PixelArray.surface + PixelArray.surface: Return Surface +Gets the Surface the PixelArray uses. + + + +PixelArray.make_surface + PixelArray.make_surface (): Return Surface +Creates a new Surface from the current PixelArray. + + + +PixelArray.replace + PixelArray.replace (color, repcolor, distance=0, weights=(0.299, 0.587, 0.114)): Return None +Replaces the passed color in the PixelArray with another one. + + + +PixelArray.extract + PixelArray.extract (color, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray +Extracts the passed color from the PixelArray. + + + +PixelArray.compare + PixelArray.compare (array, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray +Compares the PixelArray with another one. + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/pygame_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,105 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAME "the top level pygame package" + +#define DOC_PYGAMEINIT "pygame.init(): return (numpass, numfail)\ninitialize all imported pygame modules" + +#define DOC_PYGAMEQUIT "pygame.quit(): return None\nuninitialize all pygame modules" + +#define DOC_PYGAMEERROR "raise pygame.error, message\nstandard pygame exception" + +#define DOC_PYGAMEGETERROR "pygame.get_error(): return errorstr\nget the current error message" + +#define DOC_PYGAMESETERROR "pygame.set_error(error_msg): return None\nset the current error message" + +#define DOC_PYGAMEGETSDLVERSION "pygame.get_sdl_version(): return major, minor, patch\nget the version number of SDL" + +#define DOC_PYGAMEGETSDLBYTEORDER "pygame.get_sdl_byteorder(): return int\nget the byte order of SDL" + +#define DOC_PYGAMEREGISTERQUIT "register_quit(callable): return None\nregister a function to be called when pygame quits" + +#define DOC_PYGAMEVERSION "module pygame.version\nsmall module containing version information" + +#define DOC_PYGAMEVERSIONVER "pygame.version.ver = '1.2'\nversion number as a string" + +#define DOC_PYGAMEVERSIONVERNUM "pygame.version.vernum = (1, 5, 3)\ntupled integers of the version" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame + the top level pygame package + + + +pygame.init + pygame.init(): return (numpass, numfail) +initialize all imported pygame modules + + + +pygame.quit + pygame.quit(): return None +uninitialize all pygame modules + + + +pygame.error + raise pygame.error, message +standard pygame exception + + + +pygame.get_error + pygame.get_error(): return errorstr +get the current error message + + + +pygame.set_error + pygame.set_error(error_msg): return None +set the current error message + + + +pygame.get_sdl_version + pygame.get_sdl_version(): return major, minor, patch +get the version number of SDL + + + +pygame.get_sdl_byteorder + pygame.get_sdl_byteorder(): return int +get the byte order of SDL + + + +pygame.register_quit + register_quit(callable): return None +register a function to be called when pygame quits + + + +pygame.version + module pygame.version +small module containing version information + + + +pygame.version.ver + pygame.version.ver = '1.2' +version number as a string + + + +pygame.version.vernum + pygame.version.vernum = (1, 5, 3) +tupled integers of the version + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/rect_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,189 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMERECT "pygame.Rect(left, top, width, height): return Rect\npygame.Rect((left, top), (width, height)): return Rect\npygame.Rect(object): return Rect\npygame object for storing rectangular coordinates" + +#define DOC_RECTCOPY "Rect.copy(): return Rect\ncopy the rectangle" + +#define DOC_RECTMOVE "Rect.move(x, y): return Rect\nmoves the rectangle" + +#define DOC_RECTMOVEIP "Rect.move_ip(x, y): return None\nmoves the rectangle, in place" + +#define DOC_RECTINFLATE "Rect.inflate(x, y): return Rect\ngrow or shrink the rectangle size" + +#define DOC_RECTINFLATEIP "Rect.inflate_ip(x, y): return None\ngrow or shrink the rectangle size, in place" + +#define DOC_RECTCLAMP "Rect.clamp(Rect): return Rect\nmoves the rectangle inside another" + +#define DOC_RECTCLAMPIP "Rect.clamp_ip(Rect): return None\nmoves the rectangle inside another, in place" + +#define DOC_RECTCLIP "Rect.clip(Rect): return Rect\ncrops a rectangle inside another" + +#define DOC_RECTUNION "Rect.union(Rect): return Rect\njoins two rectangles into one" + +#define DOC_RECTUNIONIP "Rect.union_ip(Rect): return None\njoins two rectangles into one, in place" + +#define DOC_RECTUNIONALL "Rect.unionall(Rect_sequence): return Rect\nthe union of many rectangles" + +#define DOC_RECTUNIONALLIP "Rect.unionall_ip(Rect_sequence): return None\nthe union of many rectangles, in place" + +#define DOC_RECTFIT "Rect.fit(Rect): return Rect\nresize and move a rectangle with aspect ratio" + +#define DOC_RECTNORMALIZE "Rect.normalize(): return None\ncorrect negative sizes" + +#define DOC_RECTCONTAINS "Rect.contains(Rect): return bool\ntest if one rectangle is inside another" + +#define DOC_RECTCOLLIDEPOINT "Rect.collidepoint(x, y): return bool\nRect.collidepoint((x,y)): return bool\ntest if a point is inside a rectangle" + +#define DOC_RECTCOLLIDERECT "Rect.colliderect(Rect): return bool\ntest if two rectangles overlap" + +#define DOC_RECTCOLLIDELIST "Rect.collidelist(list): return index\ntest if one rectangle in a list intersects" + +#define DOC_RECTCOLLIDELISTALL "Rect.collidelistall(list): return indices\ntest if all rectangles in a list intersect" + +#define DOC_RECTCOLLIDEDICT "Rect.collidedict(dict): return (key, value)\ntest if one rectangle in a dictionary intersects" + +#define DOC_RECTCOLLIDEDICTALL "Rect.collidedictall(dict): return [(key, value), ...]\ntest if all rectangles in a dictionary intersect" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.Rect + pygame.Rect(left, top, width, height): return Rect +pygame.Rect((left, top), (width, height)): return Rect +pygame.Rect(object): return Rect +pygame object for storing rectangular coordinates + + + +Rect.copy + Rect.copy(): return Rect +copy the rectangle + + + +Rect.move + Rect.move(x, y): return Rect +moves the rectangle + + + +Rect.move_ip + Rect.move_ip(x, y): return None +moves the rectangle, in place + + + +Rect.inflate + Rect.inflate(x, y): return Rect +grow or shrink the rectangle size + + + +Rect.inflate_ip + Rect.inflate_ip(x, y): return None +grow or shrink the rectangle size, in place + + + +Rect.clamp + Rect.clamp(Rect): return Rect +moves the rectangle inside another + + + +Rect.clamp_ip + Rect.clamp_ip(Rect): return None +moves the rectangle inside another, in place + + + +Rect.clip + Rect.clip(Rect): return Rect +crops a rectangle inside another + + + +Rect.union + Rect.union(Rect): return Rect +joins two rectangles into one + + + +Rect.union_ip + Rect.union_ip(Rect): return None +joins two rectangles into one, in place + + + +Rect.unionall + Rect.unionall(Rect_sequence): return Rect +the union of many rectangles + + + +Rect.unionall_ip + Rect.unionall_ip(Rect_sequence): return None +the union of many rectangles, in place + + + +Rect.fit + Rect.fit(Rect): return Rect +resize and move a rectangle with aspect ratio + + + +Rect.normalize + Rect.normalize(): return None +correct negative sizes + + + +Rect.contains + Rect.contains(Rect): return bool +test if one rectangle is inside another + + + +Rect.collidepoint + Rect.collidepoint(x, y): return bool +Rect.collidepoint((x,y)): return bool +test if a point is inside a rectangle + + + +Rect.colliderect + Rect.colliderect(Rect): return bool +test if two rectangles overlap + + + +Rect.collidelist + Rect.collidelist(list): return index +test if one rectangle in a list intersects + + + +Rect.collidelistall + Rect.collidelistall(list): return indices +test if all rectangles in a list intersect + + + +Rect.collidedict + Rect.collidedict(dict): return (key, value) +test if one rectangle in a dictionary intersects + + + +Rect.collidedictall + Rect.collidedictall(dict): return [(key, value), ...] +test if all rectangles in a dictionary intersect + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/scrap_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,73 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMESCRAP "pygame module for clipboard support." + +#define DOC_PYGAMESCRAPINIT "scrap.init () -> None\nInitializes the scrap module." + +#define DOC_PYGAMESCRAPGET "scrap.get (type) -> string\nGets the data for the specified type from the clipboard." + +#define DOC_PYGAMESCRAPGETTYPES "scrap.get_types () -> list\nGets a list of the available clipboard types." + +#define DOC_PYGAMESCRAPPUT "scrap.put(type, data) -> None\nPlaces data into the clipboard." + +#define DOC_PYGAMESCRAPCONTAINS "scrap.contains (type) -> bool\nChecks, whether a certain type is available in the clipboard." + +#define DOC_PYGAMESCRAPLOST "scrap.lost() -> bool\nChecks whether the clipboard is currently owned by the application." + +#define DOC_PYGAMESCRAPSETMODE "scrap.set_mode(mode) -> None\nSets the clipboard access mode." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.scrap + pygame module for clipboard support. + + + +pygame.scrap.init + scrap.init () -> None +Initializes the scrap module. + + + +pygame.scrap.get + scrap.get (type) -> string +Gets the data for the specified type from the clipboard. + + + +pygame.scrap.get_types + scrap.get_types () -> list +Gets a list of the available clipboard types. + + + +pygame.scrap.put + scrap.put(type, data) -> None +Places data into the clipboard. + + + +pygame.scrap.contains + scrap.contains (type) -> bool +Checks, whether a certain type is available in the clipboard. + + + +pygame.scrap.lost + scrap.lost() -> bool +Checks whether the clipboard is currently owned by the application. + + + +pygame.scrap.set_mode + scrap.set_mode(mode) -> None +Sets the clipboard access mode. + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/sndarray_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,65 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMESNDARRAY "pygame module for accessing sound sample data" + +#define DOC_PYGAMESNDARRAYARRAY "pygame.sndarray.array(Sound): return array\ncopy Sound samples into an array" + +#define DOC_PYGAMESNDARRAYSAMPLES "pygame.sndarray.samples(Sound): return array\nreference Sound samples into an array" + +#define DOC_PYGAMESNDARRAYMAKESOUND "pygame.sndarray.make_sound(array): return Sound\nconvert an array into a Sound object" + +#define DOC_PYGAMESNDARRAYUSEARRAYTYPE "pygame.sndarray.use_arraytype (arraytype): return None\nSets the array system to be used for sound arrays" + +#define DOC_PYGAMESNDARRAYGETARRAYTYPE "pygame.sndarray.get_arraytype (): return str\nGets the currently active array type." + +#define DOC_PYGAMESNDARRAYGETARRAYTYPES "pygame.sndarray.get_arraytypes (): return tuple\nGets the array system types currently supported." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.sndarray + pygame module for accessing sound sample data + + + +pygame.sndarray.array + pygame.sndarray.array(Sound): return array +copy Sound samples into an array + + + +pygame.sndarray.samples + pygame.sndarray.samples(Sound): return array +reference Sound samples into an array + + + +pygame.sndarray.make_sound + pygame.sndarray.make_sound(array): return Sound +convert an array into a Sound object + + + +pygame.sndarray.use_arraytype + pygame.sndarray.use_arraytype (arraytype): return None +Sets the array system to be used for sound arrays + + + +pygame.sndarray.get_arraytype + pygame.sndarray.get_arraytype (): return str +Gets the currently active array type. + + + +pygame.sndarray.get_arraytypes + pygame.sndarray.get_arraytypes (): return tuple +Gets the array system types currently supported. + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/sprite_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,471 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMESPRITE "pygame module with basic game object classes" + +#define DOC_PYGAMESPRITESPRITE "pygame.sprite.Sprite(*groups): return Sprite\nsimple base class for visible game objects" + +#define DOC_SPRITEUPDATE "Sprite.update(*args):\nmethod to control sprite behavior" + +#define DOC_SPRITEADD "Sprite.add(*groups): return None\nadd the sprite to groups" + +#define DOC_SPRITEREMOVE "Sprite.remove(*groups): return None\nremove the sprite from groups" + +#define DOC_SPRITEKILL "Sprite.kill(): return None\nremove the Sprite from all Groups" + +#define DOC_SPRITEALIVE "Sprite.alive(): return bool\ndoes the sprite belong to any groups" + +#define DOC_SPRITEGROUPS "Sprite.groups(): return group_list\nlist of Groups that contain this Sprite" + +#define DOC_PYGAMESPRITEDIRTYSPRITE "pygame.sprite.DirtySprite(*groups): return DirtySprite\na more featureful subclass of Sprite with more attributes" + +#define DOC_ "" + +#define DOC_PYGAMESPRITEGROUP "pygame.sprite.Group(*sprites): return Group\ncontainer class for many Sprites" + +#define DOC_GROUPSPRITES "Group.sprites(): return sprite_list\nlist of the Sprites this Group contains" + +#define DOC_GROUPCOPY "Group.copy(): return Group\nduplicate the Group" + +#define DOC_GROUPADD "Group.add(*sprites): return None\nadd Sprites to this Group" + +#define DOC_GROUPREMOVE "Group.remove(*sprites): return None\nremove Sprites from the Group" + +#define DOC_GROUPHAS "Group.has(*sprites): return None\ntest if a Group contains Sprites" + +#define DOC_GROUPUPDATE "Group.update(*args): return None\ncall the update method on contained Sprites" + +#define DOC_GROUPDRAW "Group.draw(Surface): return None\nblit the Sprite images" + +#define DOC_GROUPCLEAR "Group.clear(Surface_dest, background): return None\ndraw a background over the Sprites" + +#define DOC_GROUPEMPTY "Group.empty(): return None\nremove all Sprites" + +#define DOC_PYGAMESPRITERENDERUPDATES "pygame.sprite.RenderUpdates(*sprites): return RenderUpdates\nGroup class that tracks dirty updates" + +#define DOC_RENDERUPDATESDRAW "RenderUpdates.draw(surface): return Rect_list\nblit the Sprite images and track changed areas" + +#define DOC_PYGAMESPRITEORDEREDUPDATES "pygame.sprite.OrderedUpdates(*spites): return OrderedUpdates\nRenderUpdates class that draws Sprites in order of addition" + +#define DOC_PYGAMESPRITELAYEREDUPDATES "pygame.sprite.LayeredUpdates(*spites, **kwargs): return LayeredUpdates\nLayeredUpdates Group handles layers, that draws like OrderedUpdates." + +#define DOC_LAYEREDUPDATESADD "LayeredUpdates.add(*sprites, **kwargs): return None\nadd a sprite or sequence of sprites to a group" + +#define DOC_LAYEREDUPDATESSPRITES "LayeredUpdates.sprites(): return sprites\nreturns a ordered list of sprites (first back, last top)." + +#define DOC_LAYEREDUPDATESDRAW "LayeredUpdates.draw(surface): return Rect_list\ndraw all sprites in the right order onto the passed surface." + +#define DOC_LAYEREDUPDATESGETSPRITESAT "LayeredUpdates.get_sprites_at(pos): return colliding_sprites\nreturns a list with all sprites at that position." + +#define DOC_LAYEREDUPDATESGETSPRITE "LayeredUpdates.get_sprite(idx): return sprite\nreturns the sprite at the index idx from the groups sprites" + +#define DOC_LAYEREDUPDATESREMOVESPRITESOFLAYER "LayeredUpdates.remove_sprites_of_layer(layer_nr): return sprites\nremoves all sprites from a layer and returns them as a list." + +#define DOC_LAYEREDUPDATESLAYERS "LayeredUpdates.layers(): return layers\nreturns a list of layers defined (unique), sorted from botton up." + +#define DOC_LAYEREDUPDATESCHANGELAYER "LayeredUpdates.change_layer(sprite, new_layer): return None\nchanges the layer of the sprite" + +#define DOC_LAYEREDUPDATESGETLAYEROFSPRITE "LayeredUpdates.get_layer_of_sprite(sprite): return layer\nreturns the layer that sprite is currently in." + +#define DOC_LAYEREDUPDATESGETTOPLAYER "LayeredUpdates.get_top_layer(): return layer\nreturns the top layer" + +#define DOC_LAYEREDUPDATESGETBOTTOMLAYER "LayeredUpdates.get_bottom_layer(): return layer\nreturns the bottom layer" + +#define DOC_LAYEREDUPDATESMOVETOFRONT "LayeredUpdates.move_to_front(sprite): return None\nbrings the sprite to front layer" + +#define DOC_LAYEREDUPDATESMOVETOBACK "LayeredUpdates.move_to_back(sprite): return None\nmoves the sprite to the bottom layer" + +#define DOC_LAYEREDUPDATESGETTOPSPRITE "LayeredUpdates.get_top_sprite(): return Sprite\nreturns the topmost sprite" + +#define DOC_LAYEREDUPDATESGETSPRITESFROMLAYER "LayeredUpdates.get_sprites_from_layer(layer): return sprites\nreturns all sprites from a layer, ordered by how they where added" + +#define DOC_LAYEREDUPDATESSWITCHLAYER "LayeredUpdates.switch_layer(layer1_nr, layer2_nr): return None\nswitches the sprites from layer1 to layer2" + +#define DOC_PYGAMESPRITELAYEREDDIRTY "pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty\nLayeredDirty Group is for DirtySprites. Subclasses LayeredUpdates." + +#define DOC_LAYEREDDIRTYDRAW "LayeredDirty.draw(surface, bgd=None): return Rect_list\ndraw all sprites in the right order onto the passed surface." + +#define DOC_LAYEREDDIRTYCLEAR "LayeredDirty.clear(surface, bgd): return None\nused to set background" + +#define DOC_LAYEREDDIRTYREPAINTRECT "LayeredDirty.repaint_rect(screen_rect): return None\nrepaints the given area" + +#define DOC_LAYEREDDIRTYSETCLIP "LayeredDirty.set_clip(screen_rect=None): return None\nclip the area where to draw. Just pass None (default) to reset the clip" + +#define DOC_LAYEREDDIRTYGETCLIP "LayeredDirty.get_clip(): return Rect\nclip the area where to draw. Just pass None (default) to reset the clip" + +#define DOC_LAYEREDDIRTYCHANGELAYER "change_layer(sprite, new_layer): return None\nchanges the layer of the sprite" + +#define DOC_LAYEREDDIRTYSETTIMINGTRESHOLD "set_timing_treshold(time_ms): return None\nsets the treshold in milliseconds" + +#define DOC_PYGAMESPRITEGROUPSINGLE "pygame.sprite.GroupSingle(sprite=None): return GroupSingle\nGroup container that holds a single Sprite" + +#define DOC_PYGAMESPRITESPRITECOLLIDE "pygame.sprite.spritecollide(sprite, group, dokill, collided = None): return Sprite_list\nfind Sprites in a Group that intersect another Sprite" + +#define DOC_PYGAMESPRITECOLLIDERECT "pygame.sprite.collide_rect(left, right): return bool\ncollision detection between two sprites, using rects." + +#define DOC_PYGAMESPRITECOLLIDERECTRATIO "pygame.sprite.collide_rect_ratio(ratio): return collided_callable\ncollision detection between two sprites, using rects scaled to a ratio." + +#define DOC_PYGAMESPRITECOLLIDECIRCLE "pygame.sprite.collide_circle(left, right): return bool\ncollision detection between two sprites, using circles." + +#define DOC_PYGAMESPRITECOLLIDECIRCLERATIO "pygame.sprite.collide_circle_ratio(ratio): return collided_callable\ncollision detection between two sprites, using circles scaled to a ratio." + +#define DOC_PYGAMESPRITECOLLIDEMASK "pygame.sprite.collide_mask(SpriteLeft, SpriteRight): return bool\ncollision detection between two sprites, using masks." + +#define DOC_PYGAMESPRITEGROUPCOLLIDE "pygame.sprite.groupcollide(group1, group2, dokill1, dokill2): return Sprite_dict\nfind all Sprites that collide between two Groups" + +#define DOC_PYGAMESPRITESPRITECOLLIDEANY "pygame.sprite.spritecollideany(sprite, group): return bool\nsimple test if a Sprite intersects anything in a Group" + +#define DOC_ "" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.sprite + pygame module with basic game object classes + + + +pygame.sprite.Sprite + pygame.sprite.Sprite(*groups): return Sprite +simple base class for visible game objects + + + +Sprite.update + Sprite.update(*args): +method to control sprite behavior + + + +Sprite.add + Sprite.add(*groups): return None +add the sprite to groups + + + +Sprite.remove + Sprite.remove(*groups): return None +remove the sprite from groups + + + +Sprite.kill + Sprite.kill(): return None +remove the Sprite from all Groups + + + +Sprite.alive + Sprite.alive(): return bool +does the sprite belong to any groups + + + +Sprite.groups + Sprite.groups(): return group_list +list of Groups that contain this Sprite + + + +pygame.sprite.DirtySprite + pygame.sprite.DirtySprite(*groups): return DirtySprite +a more featureful subclass of Sprite with more attributes + + + + + + + + +pygame.sprite.Group + pygame.sprite.Group(*sprites): return Group +container class for many Sprites + + + +Group.sprites + Group.sprites(): return sprite_list +list of the Sprites this Group contains + + + +Group.copy + Group.copy(): return Group +duplicate the Group + + + +Group.add + Group.add(*sprites): return None +add Sprites to this Group + + + +Group.remove + Group.remove(*sprites): return None +remove Sprites from the Group + + + +Group.has + Group.has(*sprites): return None +test if a Group contains Sprites + + + +Group.update + Group.update(*args): return None +call the update method on contained Sprites + + + +Group.draw + Group.draw(Surface): return None +blit the Sprite images + + + +Group.clear + Group.clear(Surface_dest, background): return None +draw a background over the Sprites + + + +Group.empty + Group.empty(): return None +remove all Sprites + + + +pygame.sprite.RenderUpdates + pygame.sprite.RenderUpdates(*sprites): return RenderUpdates +Group class that tracks dirty updates + + + +RenderUpdates.draw + RenderUpdates.draw(surface): return Rect_list +blit the Sprite images and track changed areas + + + +pygame.sprite.OrderedUpdates + pygame.sprite.OrderedUpdates(*spites): return OrderedUpdates +RenderUpdates class that draws Sprites in order of addition + + + +pygame.sprite.LayeredUpdates + pygame.sprite.LayeredUpdates(*spites, **kwargs): return LayeredUpdates +LayeredUpdates Group handles layers, that draws like OrderedUpdates. + + + +LayeredUpdates.add + LayeredUpdates.add(*sprites, **kwargs): return None +add a sprite or sequence of sprites to a group + + + +LayeredUpdates.sprites + LayeredUpdates.sprites(): return sprites +returns a ordered list of sprites (first back, last top). + + + +LayeredUpdates.draw + LayeredUpdates.draw(surface): return Rect_list +draw all sprites in the right order onto the passed surface. + + + +LayeredUpdates.get_sprites_at + LayeredUpdates.get_sprites_at(pos): return colliding_sprites +returns a list with all sprites at that position. + + + +LayeredUpdates.get_sprite + LayeredUpdates.get_sprite(idx): return sprite +returns the sprite at the index idx from the groups sprites + + + +LayeredUpdates.remove_sprites_of_layer + LayeredUpdates.remove_sprites_of_layer(layer_nr): return sprites +removes all sprites from a layer and returns them as a list. + + + +LayeredUpdates.layers + LayeredUpdates.layers(): return layers +returns a list of layers defined (unique), sorted from botton up. + + + +LayeredUpdates.change_layer + LayeredUpdates.change_layer(sprite, new_layer): return None +changes the layer of the sprite + + + +LayeredUpdates.get_layer_of_sprite + LayeredUpdates.get_layer_of_sprite(sprite): return layer +returns the layer that sprite is currently in. + + + +LayeredUpdates.get_top_layer + LayeredUpdates.get_top_layer(): return layer +returns the top layer + + + +LayeredUpdates.get_bottom_layer + LayeredUpdates.get_bottom_layer(): return layer +returns the bottom layer + + + +LayeredUpdates.move_to_front + LayeredUpdates.move_to_front(sprite): return None +brings the sprite to front layer + + + +LayeredUpdates.move_to_back + LayeredUpdates.move_to_back(sprite): return None +moves the sprite to the bottom layer + + + +LayeredUpdates.get_top_sprite + LayeredUpdates.get_top_sprite(): return Sprite +returns the topmost sprite + + + +LayeredUpdates.get_sprites_from_layer + LayeredUpdates.get_sprites_from_layer(layer): return sprites +returns all sprites from a layer, ordered by how they where added + + + +LayeredUpdates.switch_layer + LayeredUpdates.switch_layer(layer1_nr, layer2_nr): return None +switches the sprites from layer1 to layer2 + + + +pygame.sprite.LayeredDirty + pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty +LayeredDirty Group is for DirtySprites. Subclasses LayeredUpdates. + + + +LayeredDirty.draw + LayeredDirty.draw(surface, bgd=None): return Rect_list +draw all sprites in the right order onto the passed surface. + + + +LayeredDirty.clear + LayeredDirty.clear(surface, bgd): return None +used to set background + + + +LayeredDirty.repaint_rect + LayeredDirty.repaint_rect(screen_rect): return None +repaints the given area + + + +LayeredDirty.set_clip + LayeredDirty.set_clip(screen_rect=None): return None +clip the area where to draw. Just pass None (default) to reset the clip + + + +LayeredDirty.get_clip + LayeredDirty.get_clip(): return Rect +clip the area where to draw. Just pass None (default) to reset the clip + + + +LayeredDirty.change_layer + change_layer(sprite, new_layer): return None +changes the layer of the sprite + + + +LayeredDirty.set_timing_treshold + set_timing_treshold(time_ms): return None +sets the treshold in milliseconds + + + +pygame.sprite.GroupSingle + pygame.sprite.GroupSingle(sprite=None): return GroupSingle +Group container that holds a single Sprite + + + +pygame.sprite.spritecollide + pygame.sprite.spritecollide(sprite, group, dokill, collided = None): return Sprite_list +find Sprites in a Group that intersect another Sprite + + + +pygame.sprite.collide_rect + pygame.sprite.collide_rect(left, right): return bool +collision detection between two sprites, using rects. + + + +pygame.sprite.collide_rect_ratio + pygame.sprite.collide_rect_ratio(ratio): return collided_callable +collision detection between two sprites, using rects scaled to a ratio. + + + +pygame.sprite.collide_circle + pygame.sprite.collide_circle(left, right): return bool +collision detection between two sprites, using circles. + + + +pygame.sprite.collide_circle_ratio + pygame.sprite.collide_circle_ratio(ratio): return collided_callable +collision detection between two sprites, using circles scaled to a ratio. + + + +pygame.sprite.collide_mask + pygame.sprite.collide_mask(SpriteLeft, SpriteRight): return bool +collision detection between two sprites, using masks. + + + +pygame.sprite.groupcollide + pygame.sprite.groupcollide(group1, group2, dokill1, dokill2): return Sprite_dict +find all Sprites that collide between two Groups + + + +pygame.sprite.spritecollideany + pygame.sprite.spritecollideany(sprite, group): return bool +simple test if a Sprite intersects anything in a Group + + + + + + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/surface_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,386 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMESURFACE "pygame.Surface((width, height), flags=0, depth=0, masks=None): return Surface\npygame.Surface((width, height), flags=0, Surface): return Surface\npygame object for representing images" + +#define DOC_SURFACEBLIT "Surface.blit(source, dest, area=None, special_flags = 0): return Rect\ndraw one image onto another" + +#define DOC_SURFACECONVERT "Surface.convert(Surface): return Surface\nSurface.convert(depth, flags=0): return Surface\nSurface.convert(masks, flags=0): return Surface\nSurface.convert(): return Surface\nchange the pixel format of an image" + +#define DOC_SURFACECONVERTALPHA "Surface.convert_alpha(Surface): return Surface\nSurface.convert_alpha(): return Surface\nchange the pixel format of an image including per pixel alphas" + +#define DOC_SURFACECOPY "Surface.copy(): return Surface\ncreate a new copy of a Surface" + +#define DOC_SURFACEFILL "Surface.fill(color, rect=None, special_flags=0): return Rect\nfill Surface with a solid color" + +#define DOC_SURFACESCROLL "Surface.scroll(dx=0, dy=0): return None\nShift the surface image in place" + +#define DOC_SURFACESETCOLORKEY "Surface.set_colorkey(Color, flags=0): return None\nSurface.set_colorkey(None): return None\nSet the transparent colorkey" + +#define DOC_SURFACEGETCOLORKEY "Surface.get_colorkey(): return RGB or None\nGet the current transparent colorkey" + +#define DOC_SURFACESETALPHA "Surface.set_alpha(value, flags=0): return None\nSurface.set_alpha(None): return None\nset the alpha value for the full Surface image" + +#define DOC_SURFACEGETALPHA "Surface.get_alpha(): return int_value or None\nget the current Surface transparency value" + +#define DOC_SURFACELOCK "Surface.lock(): return None\nlock the Surface memory for pixel access" + +#define DOC_SURFACEUNLOCK "Surface.unlock(): return None\nunlock the Surface memory from pixel access" + +#define DOC_SURFACEMUSTLOCK "Surface.mustlock(): return bool\ntest if the Surface requires locking" + +#define DOC_SURFACEGETLOCKED "Surface.get_locked(): return bool\ntest if the Surface is current locked" + +#define DOC_SURFACEGETLOCKS "Surface.get_locks(): return tuple\nGets the locks for the Surface" + +#define DOC_SURFACEGETAT "Surface.get_at((x, y)): return Color\nget the color value at a single pixel" + +#define DOC_SURFACESETAT "Surface.set_at((x, y), Color): return None\nset the color value for a single pixel" + +#define DOC_SURFACEGETPALETTE "Surface.get_palette(): return [RGB, RGB, RGB, ...]\nget the color index palette for an 8bit Surface" + +#define DOC_SURFACEGETPALETTEAT "Surface.get_palette_at(index): return RGB\nget the color for a single entry in a palette" + +#define DOC_SURFACESETPALETTE "Surface.set_palette([RGB, RGB, RGB, ...]): return None\nset the color palette for an 8bit Surface" + +#define DOC_SURFACESETPALETTEAT "Surface.set_at(index, RGB): return None\nset the color for a single index in an 8bit Surface palette" + +#define DOC_SURFACEMAPRGB "Surface.map_rgb(Color): return mapped_int\nconvert a color into a mapped color value" + +#define DOC_SURFACEUNMAPRGB "Surface.map_rgb(mapped_int): return Color\nconvert a mapped integer color value into a Color" + +#define DOC_SURFACESETCLIP "Surface.set_clip(rect): return None\nSurface.set_clip(None): return None\nset the current clipping area of the Surface" + +#define DOC_SURFACEGETCLIP "Surface.get_clip(): return Rect\nget the current clipping area of the Surface" + +#define DOC_SURFACESUBSURFACE "Surface.subsurface(Rect): return Surface\ncreate a new surface that references its parent" + +#define DOC_SURFACEGETPARENT "Surface.get_parent(): return Surface\nfind the parent of a subsurface" + +#define DOC_SURFACEGETABSPARENT "Surface.get_abs_parent(): return Surface\nfind the top level parent of a subsurface" + +#define DOC_SURFACEGETOFFSET "Surface.get_offset(): return (x, y)\nfind the position of a child subsurface inside a parent" + +#define DOC_SURFACEGETABSOFFSET "Surface.get_abs_offset(): return (x, y)\nfind the absolute position of a child subsurface inside its top level parent" + +#define DOC_SURFACEGETSIZE "Surface.get_size(): return (width, height)\nget the dimensions of the Surface" + +#define DOC_SURFACEGETWIDTH "Surface.get_width(): return width\nget the width of the Surface" + +#define DOC_SURFACEGETHEIGHT "Surface.get_height(): return height\nget the height of the Surface" + +#define DOC_SURFACEGETRECT "Surface.get_rect(**kwargs): return Rect\nget the rectangular area of the Surface" + +#define DOC_SURFACEGETBITSIZE "Surface.get_bitsize(): return int\nget the bit depth of the Surface pixel format" + +#define DOC_SURFACEGETBYTESIZE "Surface.get_bytesize(): return int\nget the bytes used per Surface pixel" + +#define DOC_SURFACEGETFLAGS "Surface.get_flags(): return int\nget the additional flags used for the Surface" + +#define DOC_SURFACEGETPITCH "Surface.get_pitch(): return int\nget the number of bytes used per Surface row" + +#define DOC_SURFACEGETMASKS "Surface.get_masks(): return (R, G, B, A)\nthe bitmasks needed to convert between a color and a mapped integer" + +#define DOC_SURFACESETMASKS "Surface.set_masks((r,g,b,a)): return None\nset the bitmasks needed to convert between a color and a mapped integer" + +#define DOC_SURFACEGETSHIFTS "Surface.get_shifts(): return (R, G, B, A)\nthe bit shifts needed to convert between a color and a mapped integer" + +#define DOC_SURFACESETSHIFTS "Surface.get_shifts((r,g,b,a)): return None\nsets the bit shifts needed to convert between a color and a mapped integer" + +#define DOC_SURFACEGETLOSSES "Surface.get_losses(): return (R, G, B, A)\nthe significant bits used to convert between a color and a mapped integer" + +#define DOC_SURFACEGETBOUNDINGRECT "Surface.get_bounding_rect(min_alpha = 1): return Rect\nfind the smallest rect containing data" + +#define DOC_SURFACEGETBUFFER "Surface.get_buffer(): return BufferProxy\nacquires a buffer object for the pixels of the Surface." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.Surface + pygame.Surface((width, height), flags=0, depth=0, masks=None): return Surface +pygame.Surface((width, height), flags=0, Surface): return Surface +pygame object for representing images + + + +Surface.blit + Surface.blit(source, dest, area=None, special_flags = 0): return Rect +draw one image onto another + + + +Surface.convert + Surface.convert(Surface): return Surface +Surface.convert(depth, flags=0): return Surface +Surface.convert(masks, flags=0): return Surface +Surface.convert(): return Surface +change the pixel format of an image + + + +Surface.convert_alpha + Surface.convert_alpha(Surface): return Surface +Surface.convert_alpha(): return Surface +change the pixel format of an image including per pixel alphas + + + +Surface.copy + Surface.copy(): return Surface +create a new copy of a Surface + + + +Surface.fill + Surface.fill(color, rect=None, special_flags=0): return Rect +fill Surface with a solid color + + + +Surface.scroll + Surface.scroll(dx=0, dy=0): return None +Shift the surface image in place + + + +Surface.set_colorkey + Surface.set_colorkey(Color, flags=0): return None +Surface.set_colorkey(None): return None +Set the transparent colorkey + + + +Surface.get_colorkey + Surface.get_colorkey(): return RGB or None +Get the current transparent colorkey + + + +Surface.set_alpha + Surface.set_alpha(value, flags=0): return None +Surface.set_alpha(None): return None +set the alpha value for the full Surface image + + + +Surface.get_alpha + Surface.get_alpha(): return int_value or None +get the current Surface transparency value + + + +Surface.lock + Surface.lock(): return None +lock the Surface memory for pixel access + + + +Surface.unlock + Surface.unlock(): return None +unlock the Surface memory from pixel access + + + +Surface.mustlock + Surface.mustlock(): return bool +test if the Surface requires locking + + + +Surface.get_locked + Surface.get_locked(): return bool +test if the Surface is current locked + + + +Surface.get_locks + Surface.get_locks(): return tuple +Gets the locks for the Surface + + + +Surface.get_at + Surface.get_at((x, y)): return Color +get the color value at a single pixel + + + +Surface.set_at + Surface.set_at((x, y), Color): return None +set the color value for a single pixel + + + +Surface.get_palette + Surface.get_palette(): return [RGB, RGB, RGB, ...] +get the color index palette for an 8bit Surface + + + +Surface.get_palette_at + Surface.get_palette_at(index): return RGB +get the color for a single entry in a palette + + + +Surface.set_palette + Surface.set_palette([RGB, RGB, RGB, ...]): return None +set the color palette for an 8bit Surface + + + +Surface.set_palette_at + Surface.set_at(index, RGB): return None +set the color for a single index in an 8bit Surface palette + + + +Surface.map_rgb + Surface.map_rgb(Color): return mapped_int +convert a color into a mapped color value + + + +Surface.unmap_rgb + Surface.map_rgb(mapped_int): return Color +convert a mapped integer color value into a Color + + + +Surface.set_clip + Surface.set_clip(rect): return None +Surface.set_clip(None): return None +set the current clipping area of the Surface + + + +Surface.get_clip + Surface.get_clip(): return Rect +get the current clipping area of the Surface + + + +Surface.subsurface + Surface.subsurface(Rect): return Surface +create a new surface that references its parent + + + +Surface.get_parent + Surface.get_parent(): return Surface +find the parent of a subsurface + + + +Surface.get_abs_parent + Surface.get_abs_parent(): return Surface +find the top level parent of a subsurface + + + +Surface.get_offset + Surface.get_offset(): return (x, y) +find the position of a child subsurface inside a parent + + + +Surface.get_abs_offset + Surface.get_abs_offset(): return (x, y) +find the absolute position of a child subsurface inside its top level parent + + + +Surface.get_size + Surface.get_size(): return (width, height) +get the dimensions of the Surface + + + +Surface.get_width + Surface.get_width(): return width +get the width of the Surface + + + +Surface.get_height + Surface.get_height(): return height +get the height of the Surface + + + +Surface.get_rect + Surface.get_rect(**kwargs): return Rect +get the rectangular area of the Surface + + + +Surface.get_bitsize + Surface.get_bitsize(): return int +get the bit depth of the Surface pixel format + + + +Surface.get_bytesize + Surface.get_bytesize(): return int +get the bytes used per Surface pixel + + + +Surface.get_flags + Surface.get_flags(): return int +get the additional flags used for the Surface + + + +Surface.get_pitch + Surface.get_pitch(): return int +get the number of bytes used per Surface row + + + +Surface.get_masks + Surface.get_masks(): return (R, G, B, A) +the bitmasks needed to convert between a color and a mapped integer + + + +Surface.set_masks + Surface.set_masks((r,g,b,a)): return None +set the bitmasks needed to convert between a color and a mapped integer + + + +Surface.get_shifts + Surface.get_shifts(): return (R, G, B, A) +the bit shifts needed to convert between a color and a mapped integer + + + +Surface.set_shifts + Surface.get_shifts((r,g,b,a)): return None +sets the bit shifts needed to convert between a color and a mapped integer + + + +Surface.get_losses + Surface.get_losses(): return (R, G, B, A) +the significant bits used to convert between a color and a mapped integer + + + +Surface.get_bounding_rect + Surface.get_bounding_rect(min_alpha = 1): return Rect +find the smallest rect containing data + + + +Surface.get_buffer + Surface.get_buffer(): return BufferProxy +acquires a buffer object for the pixels of the Surface. + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/surfarray_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,121 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMESURFARRAY "pygame module for accessing surface pixel data using array interfaces" + +#define DOC_PYGAMESURFARRAYARRAY2D "pygame.surfarray.array2d(Surface): return array\nCopy pixels into a 2d array" + +#define DOC_PYGAMESURFARRAYPIXELS2D "pygame.surfarray.pixels2d(Surface): return array\nReference pixels into a 2d array" + +#define DOC_PYGAMESURFARRAYARRAY3D "pygame.surfarray.array3d(Surface): return array\nCopy pixels into a 3d array" + +#define DOC_PYGAMESURFARRAYPIXELS3D "pygame.surfarray.pixels3d(Surface): return array\nReference pixels into a 3d array" + +#define DOC_PYGAMESURFARRAYARRAYALPHA "pygame.surfarray.array_alpha(Surface): return array\nCopy pixel alphas into a 2d array" + +#define DOC_PYGAMESURFARRAYPIXELSALPHA "pygame.surfarray.pixels_alpha(Surface): return array\nReference pixel alphas into a 2d array" + +#define DOC_PYGAMESURFARRAYARRAYCOLORKEY "pygame.surfarray.array_colorkey(Surface): return array\nCopy the colorkey values into a 2d array" + +#define DOC_PYGAMESURFARRAYMAKESURFACE "pygame.surfarray.make_surface(array): return Surface\nCopy an array to a new surface" + +#define DOC_PYGAMESURFARRAYBLITARRAY "pygame.surfarray.blit_array(Surface, array): return None\nBlit directly from a array values" + +#define DOC_PYGAMESURFARRAYMAPARRAY "pygame.surfarray.map_array(Surface, array3d): return array2d\nMap a 3d array into a 2d array" + +#define DOC_PYGAMESURFARRAYUSEARRAYTYPE "pygame.surfarray.use_arraytype (arraytype): return None\nSets the array system to be used for surface arrays" + +#define DOC_PYGAMESURFARRAYGETARRAYTYPE "pygame.surfarray.get_arraytype (): return str\nGets the currently active array type." + +#define DOC_PYGAMESURFARRAYGETARRAYTYPES "pygame.surfarray.get_arraytypes (): return tuple\nGets the array system types currently supported." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.surfarray + pygame module for accessing surface pixel data using array interfaces + + + +pygame.surfarray.array2d + pygame.surfarray.array2d(Surface): return array +Copy pixels into a 2d array + + + +pygame.surfarray.pixels2d + pygame.surfarray.pixels2d(Surface): return array +Reference pixels into a 2d array + + + +pygame.surfarray.array3d + pygame.surfarray.array3d(Surface): return array +Copy pixels into a 3d array + + + +pygame.surfarray.pixels3d + pygame.surfarray.pixels3d(Surface): return array +Reference pixels into a 3d array + + + +pygame.surfarray.array_alpha + pygame.surfarray.array_alpha(Surface): return array +Copy pixel alphas into a 2d array + + + +pygame.surfarray.pixels_alpha + pygame.surfarray.pixels_alpha(Surface): return array +Reference pixel alphas into a 2d array + + + +pygame.surfarray.array_colorkey + pygame.surfarray.array_colorkey(Surface): return array +Copy the colorkey values into a 2d array + + + +pygame.surfarray.make_surface + pygame.surfarray.make_surface(array): return Surface +Copy an array to a new surface + + + +pygame.surfarray.blit_array + pygame.surfarray.blit_array(Surface, array): return None +Blit directly from a array values + + + +pygame.surfarray.map_array + pygame.surfarray.map_array(Surface, array3d): return array2d +Map a 3d array into a 2d array + + + +pygame.surfarray.use_arraytype + pygame.surfarray.use_arraytype (arraytype): return None +Sets the array system to be used for surface arrays + + + +pygame.surfarray.get_arraytype + pygame.surfarray.get_arraytype (): return str +Gets the currently active array type. + + + +pygame.surfarray.get_arraytypes + pygame.surfarray.get_arraytypes (): return tuple +Gets the array system types currently supported. + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/tests_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,25 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMETESTS "Pygame unit test suite package" + +#define DOC_PYGAMETESTSRUN "pygame.tests.run(*args, **kwds): return tuple\nRun the Pygame unit test suite" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.tests + Pygame unit test suite package + + + +pygame.tests.run + pygame.tests.run(*args, **kwds): return tuple +Run the Pygame unit test suite + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/time_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,99 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMETIME "pygame module for monitoring time" + +#define DOC_PYGAMETIMEGETTICKS "pygame.time.get_ticks(): return milliseconds\nget the time in milliseconds" + +#define DOC_PYGAMETIMEWAIT "pygame.time.wait(milliseconds): return time\npause the program for an amount of time" + +#define DOC_PYGAMETIMEDELAY "pygame.time.delay(milliseconds): return time\npause the program for an amount of time" + +#define DOC_PYGAMETIMESETTIMER "pygame.time.set_timer(eventid, milliseconds): return None\nrepeatedly create an event on the event queue" + +#define DOC_PYGAMETIMECLOCK "pygame.time.Clock(): return Clock\ncreate an object to help track time" + +#define DOC_CLOCKTICK "Clock.tick(framerate=0): return milliseconds\ncontrol timer events\nupdate the clock" + +#define DOC_CLOCKTICKBUSYLOOP "Clock.tick_busy_loop(framerate=0): return milliseconds\ncontrol timer events\nupdate the clock" + +#define DOC_CLOCKGETTIME "Clock.get_time(): return milliseconds\ntime used in the previous tick" + +#define DOC_CLOCKGETRAWTIME "Clock.get_rawtime(): return milliseconds\nactual time used in the previous tick" + +#define DOC_CLOCKGETFPS "Clock.get_fps(): return float\ncompute the clock framerate" + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.time + pygame module for monitoring time + + + +pygame.time.get_ticks + pygame.time.get_ticks(): return milliseconds +get the time in milliseconds + + + +pygame.time.wait + pygame.time.wait(milliseconds): return time +pause the program for an amount of time + + + +pygame.time.delay + pygame.time.delay(milliseconds): return time +pause the program for an amount of time + + + +pygame.time.set_timer + pygame.time.set_timer(eventid, milliseconds): return None +repeatedly create an event on the event queue + + + +pygame.time.Clock + pygame.time.Clock(): return Clock +create an object to help track time + + + +Clock.tick + Clock.tick(framerate=0): return milliseconds +control timer events +update the clock + + + +Clock.tick_busy_loop + Clock.tick_busy_loop(framerate=0): return milliseconds +control timer events +update the clock + + + +Clock.get_time + Clock.get_time(): return milliseconds +time used in the previous tick + + + +Clock.get_rawtime + Clock.get_rawtime(): return milliseconds +actual time used in the previous tick + + + +Clock.get_fps + Clock.get_fps(): return float +compute the clock framerate + + + +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doc/transform_doc.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,121 @@ +/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */ +#define DOC_PYGAMETRANSFORM "pygame module to transform surfaces" + +#define DOC_PYGAMETRANSFORMFLIP "pygame.transform.flip(Surface, xbool, ybool): return Surface\nflip vertically and horizontally" + +#define DOC_PYGAMETRANSFORMSCALE "pygame.transform.scale(Surface, (width, height), DestSurface = None): return Surface\nresize to new resolution" + +#define DOC_PYGAMETRANSFORMROTATE "pygame.transform.rotate(Surface, angle): return Surface\nrotate an image" + +#define DOC_PYGAMETRANSFORMROTOZOOM "pygame.transform.rotozoom(Surface, angle, scale): return Surface\nfiltered scale and rotation" + +#define DOC_PYGAMETRANSFORMSCALE2X "pygame.transform.scale2x(Surface, DestSurface = None): Surface\nspecialized image doubler" + +#define DOC_PYGAMETRANSFORMSMOOTHSCALE "pygame.transform.smoothscale(Surface, (width, height), DestSurface = None): return Surface\nscale a surface to an arbitrary size smoothly" + +#define DOC_PYGAMETRANSFORMGETSMOOTHSCALEBACKEND "pygame.transform.get_smoothscale_backend(): return String\nreturn smoothscale filter version in use: 'GENERIC', 'MMX', or 'SSE'" + +#define DOC_PYGAMETRANSFORMSETSMOOTHSCALEBACKEND "pygame.transform.get_smoothscale_backend(type): return None\nset smoothscale filter version to one of: 'GENERIC', 'MMX', or 'SSE'" + +#define DOC_PYGAMETRANSFORMCHOP "pygame.transform.chop(Surface, rect): return Surface\ngets a copy of an image with an interior area removed" + +#define DOC_PYGAMETRANSFORMLAPLACIAN "pygame.transform.laplacian(Surface, DestSurface = None): return Surface\nfind edges in a surface" + +#define DOC_PYGAMETRANSFORMAVERAGESURFACES "pygame.transform.average_surfaces(Surfaces, DestSurface = None, palette_colors = 1): return Surface\nfind the average surface from many surfaces." + +#define DOC_PYGAMETRANSFORMAVERAGECOLOR "pygame.transform.average_color(Surface, Rect = None): return Color\nfinds the average color of a surface" + +#define DOC_PYGAMETRANSFORMTHRESHOLD "pygame.transform.threshold(DestSurface, Surface, color, threshold = (0,0,0,0), diff_color = (0,0,0,0), change_return = 1, Surface = None, inverse = False): return num_threshold_pixels\nfinds which, and how many pixels in a surface are within a threshold of a color." + + + +/* Docs in a comments... slightly easier to read. */ + + +/* + +pygame.transform + pygame module to transform surfaces + + + +pygame.transform.flip + pygame.transform.flip(Surface, xbool, ybool): return Surface +flip vertically and horizontally + + + +pygame.transform.scale + pygame.transform.scale(Surface, (width, height), DestSurface = None): return Surface +resize to new resolution + + + +pygame.transform.rotate + pygame.transform.rotate(Surface, angle): return Surface +rotate an image + + + +pygame.transform.rotozoom + pygame.transform.rotozoom(Surface, angle, scale): return Surface +filtered scale and rotation + + + +pygame.transform.scale2x + pygame.transform.scale2x(Surface, DestSurface = None): Surface +specialized image doubler + + + +pygame.transform.smoothscale + pygame.transform.smoothscale(Surface, (width, height), DestSurface = None): return Surface +scale a surface to an arbitrary size smoothly + + + +pygame.transform.get_smoothscale_backend + pygame.transform.get_smoothscale_backend(): return String +return smoothscale filter version in use: 'GENERIC', 'MMX', or 'SSE' + + + +pygame.transform.set_smoothscale_backend + pygame.transform.get_smoothscale_backend(type): return None +set smoothscale filter version to one of: 'GENERIC', 'MMX', or 'SSE' + + + +pygame.transform.chop + pygame.transform.chop(Surface, rect): return Surface +gets a copy of an image with an interior area removed + + + +pygame.transform.laplacian + pygame.transform.laplacian(Surface, DestSurface = None): return Surface +find edges in a surface + + + +pygame.transform.average_surfaces + pygame.transform.average_surfaces(Surfaces, DestSurface = None, palette_colors = 1): return Surface +find the average surface from many surfaces. + + + +pygame.transform.average_color + pygame.transform.average_color(Surface, Rect = None): return Color +finds the average color of a surface + + + +pygame.transform.threshold + pygame.transform.threshold(DestSurface, Surface, color, threshold = (0,0,0,0), diff_color = (0,0,0,0), change_return = 1, Surface = None, inverse = False): return num_threshold_pixels +finds which, and how many pixels in a surface are within a threshold of a color. + + + +*/ +
--- a/src/draw.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/draw.c Mon Nov 16 18:31:40 2009 +0000 @@ -25,7 +25,7 @@ */ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/draw_doc.h" #include <math.h> /* Many C libraries seem to lack the trunc call (added in C99) */
--- a/src/event.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/event.c Mon Nov 16 18:31:40 2009 +0000 @@ -26,7 +26,7 @@ #define PYGAMEAPI_EVENT_INTERNAL #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/event_doc.h" // FIXME: The system message code is only tested on windows, so only // include it there for now.
--- a/src/font.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/font.c Mon Nov 16 18:31:40 2009 +0000 @@ -30,7 +30,7 @@ #include <string.h> #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/font_doc.h" #include "structmember.h" static PyTypeObject PyFont_Type;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,1258 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#define PYGAME_FREETYPE_INTERNAL +#define PYGAME_FREETYPE_FONT_INTERNAL + +#include "freetype.h" +#include "freetype/ft_wrap.h" +#include "doc/freetype_doc.h" + +/* + * Auxiliar defines + */ +#define PGFT_CHECK_BOOL(_pyobj, _var) \ + if (_pyobj) \ + { \ + if (!PyBool_Check(_pyobj)) \ + { \ + PyErr_SetString(PyExc_TypeError, \ + #_var " must be a boolean value"); \ + return NULL; \ + } \ + \ + _var = PyObject_IsTrue(_pyobj); \ + } + +#define DEFAULT_FONT_NAME "freesansbold.ttf" +#define PKGDATA_MODULE_NAME "pygame.pkgdata" +#define RESOURCE_FUNC_NAME "getResource" + +static PyObject* +load_font_res(const char *filename) +{ + PyObject *load_basicfunc = NULL; + PyObject *pkgdatamodule = NULL; + PyObject *resourcefunc = NULL; + PyObject *result = NULL; + PyObject *tmp; + + pkgdatamodule = PyImport_ImportModule(PKGDATA_MODULE_NAME); + if (!pkgdatamodule) + goto font_resource_end; + + resourcefunc = PyObject_GetAttrString(pkgdatamodule, RESOURCE_FUNC_NAME); + if (!resourcefunc) + goto font_resource_end; + + result = PyObject_CallFunction(resourcefunc, "s", filename); + if (!result) + goto font_resource_end; + +#if PY3 + tmp = PyObject_GetAttrString(result, "name"); + if (tmp != NULL) + { + Py_DECREF(result); + result = tmp; + } + else + { + PyErr_Clear(); + } +#else + if (PyFile_Check(result)) + { + tmp = PyFile_Name(result); + Py_INCREF(tmp); + Py_DECREF(result); + result = tmp; + } +#endif + +font_resource_end: + Py_XDECREF(pkgdatamodule); + Py_XDECREF(resourcefunc); + Py_XDECREF(load_basicfunc); + return result; +} + +/* + * FreeType module declarations + */ +static int _ft_traverse (PyObject *mod, visitproc visit, void *arg); +static int _ft_clear (PyObject *mod); + +static PyObject *_ft_quit(PyObject *self); +static PyObject *_ft_init(PyObject *self, PyObject *args); +static PyObject *_ft_get_version(PyObject *self); +static PyObject *_ft_get_error(PyObject *self); +static PyObject *_ft_was_init(PyObject *self); +static PyObject* _ft_autoinit(PyObject* self); +static void _ft_autoquit(void); + +/* + * Constructor/init/destructor + */ +static void _ftfont_dealloc(PyFreeTypeFont *self); +static PyObject *_ftfont_repr(PyObject *self); +static int _ftfont_init(PyObject *self, PyObject *args, PyObject *kwds); + +/* + * Main methods + */ +static PyObject* _ftfont_getsize(PyObject *self, PyObject* args, PyObject *kwds); +static PyObject* _ftfont_getmetrics(PyObject *self, PyObject* args, PyObject *kwds); +static PyObject* _ftfont_render(PyObject *self, PyObject* args, PyObject *kwds); +static PyObject* _ftfont_render_raw(PyObject *self, PyObject* args, PyObject *kwds); + +/* static PyObject* _ftfont_copy(PyObject *self); */ + +/* + * Getters/setters + */ +static PyObject* _ftfont_getstyle(PyObject *self, void *closure); +static int _ftfont_setstyle(PyObject *self, PyObject *value, void *closure); +static PyObject* _ftfont_getheight(PyObject *self, void *closure); +static PyObject* _ftfont_getname(PyObject *self, void *closure); +static PyObject* _ftfont_getfixedwidth(PyObject *self, void *closure); + +static PyObject* _ftfont_getvertical(PyObject *self, void *closure); +static int _ftfont_setvertical(PyObject *self, PyObject *value, void *closure); +static PyObject* _ftfont_getantialias(PyObject *self, void *closure); +static int _ftfont_setantialias(PyObject *self, PyObject *value, void *closure); + +static PyObject* _ftfont_getstyle_flag(PyObject *self, void *closure); +static int _ftfont_setstyle_flag(PyObject *self, PyObject *value, void *closure); + +/* + * FREETYPE MODULE METHODS TABLE + */ +static PyMethodDef _ft_methods[] = +{ + + { + "__PYGAMEinit__", + (PyCFunction) _ft_autoinit, + METH_NOARGS, + "auto initialize function for font" + }, + { + "init", + (PyCFunction) _ft_init, + METH_VARARGS, + DOC_PYGAMEFREETYPEINIT + }, + { + "quit", + (PyCFunction) _ft_quit, + METH_NOARGS, + DOC_PYGAMEFREETYPEQUIT + }, + { + "was_init", + (PyCFunction) _ft_was_init, + METH_NOARGS, + DOC_PYGAMEFREETYPEWASINIT + }, + { + "get_error", + (PyCFunction) _ft_get_error, + METH_NOARGS, + DOC_PYGAMEFREETYPEGETERROR + }, + { + "get_version", + (PyCFunction) _ft_get_version, + METH_NOARGS, + DOC_PYGAMEFREETYPEGETVERSION + }, + { NULL, NULL, 0, NULL }, +}; + + +/* + * FREETYPE FONT METHODS TABLE + */ +static PyMethodDef _ftfont_methods[] = +{ + { + "get_size", + (PyCFunction) _ftfont_getsize, + METH_VARARGS | METH_KEYWORDS, + DOC_FONTGETSIZE + }, + { + "get_metrics", + (PyCFunction) _ftfont_getmetrics, + METH_VARARGS | METH_KEYWORDS, + DOC_FONTGETMETRICS + }, + { + "render", + (PyCFunction)_ftfont_render, + METH_VARARGS | METH_KEYWORDS, + DOC_FONTRENDER + }, +/* { + "render_raw", + (PyCFunction)_ftfont_render_raw, + METH_VARARGS | METH_KEYWORDS, + DOC_PYGAMEFREETYPEFONTRENDERRAW + }, */ + { NULL, NULL, 0, NULL } +}; + +/* + * FREETYPE FONT GETTERS/SETTERS TABLE + */ +static PyGetSetDef _ftfont_getsets[] = +{ + { + "style", + _ftfont_getstyle, + _ftfont_setstyle, + DOC_FONTSTYLE, + NULL + }, + { + "height", + _ftfont_getheight, + NULL, + DOC_FONTHEIGHT, + NULL + }, + { + "name", + _ftfont_getname, + NULL, + DOC_FONTNAME, + NULL + }, + { + "fixed_width", + _ftfont_getfixedwidth, + NULL, + DOC_FONTFIXEDWIDTH, + NULL + }, + { + "antialiased", + _ftfont_getantialias, + _ftfont_setantialias, + DOC_FONTANTIALIASED, + NULL + }, + { + "vertical", + _ftfont_getvertical, + _ftfont_setvertical, + DOC_FONTVERTICAL, + NULL + }, + { + "italic", + _ftfont_getstyle_flag, + _ftfont_setstyle_flag, + DOC_FONTITALIC, + (void *)FT_STYLE_ITALIC + }, + { + "bold", + _ftfont_getstyle_flag, + _ftfont_setstyle_flag, + DOC_FONTBOLD, + (void *)FT_STYLE_BOLD + }, + { + "underline", + _ftfont_getstyle_flag, + _ftfont_setstyle_flag, + DOC_FONTUNDERLINE, + (void *)FT_STYLE_UNDERLINE + }, + { NULL, NULL, NULL, NULL, NULL } +}; + +/* + * FREETYPE FONT BASE TYPE TABLE + */ +PyTypeObject PyFreeTypeFont_Type = +{ + TYPE_HEAD(NULL,0) + "freetype.Font", /* tp_name */ + sizeof (PyFreeTypeFont), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)_ftfont_dealloc,/* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc)_ftfont_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + DOC_PYGAMEFREETYPEFONT, /* docstring */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + _ftfont_methods, /* tp_methods */ + 0, /* tp_members */ + _ftfont_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) _ftfont_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ +#if PY_VERSION_HEX >= 0x02060000 + 0 /* tp_version_tag */ +#endif +}; + + + +/**************************************************** + * CONSTRUCTOR/INIT/DESTRUCTOR + ****************************************************/ +static void +_ftfont_dealloc(PyFreeTypeFont *self) +{ + /* Always try to unload the font even if we cannot grab + * a freetype instance. */ + PGFT_UnloadFont(FREETYPE_STATE->freetype, self); + + ((PyObject*)self)->ob_type->tp_free((PyObject *)self); +} + +static int +_ftfont_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = + { + "font", "ptsize", "style", "face_index", NULL + }; + + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + + PyObject *file, *original_file; + int face_index = 0; + int ptsize = -1; + int font_style = FT_STYLE_NORMAL; + + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, -1); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iii", kwlist, + &file, &ptsize, &font_style, &face_index)) + return -1; + + original_file = file; + + if (face_index < 0) + { + PyErr_SetString(PyExc_ValueError, "Face index cannot be negative"); + goto end; + } + + /* TODO: Check style? Ask for vertical? */ + + font->ptsize = (FT_Int16)((ptsize <= 0) ? -1 : ptsize); + font->style = (FT_Byte)font_style; + font->antialias = 1; + font->vertical = 0; + + if (file == Py_None) + { + file = load_font_res(DEFAULT_FONT_NAME); + + if (file == NULL) + { + PyErr_SetString(PyExc_RuntimeError, "Failed to find default font"); + goto end; + } + } + + if (PyUnicode_Check(file)) + { + file = PyUnicode_AsASCIIString(file); + + if (file == NULL) + { + PyErr_SetString(PyExc_ValueError, "Failed to decode filename"); + goto end; + } + } + + if (Bytes_Check(file)) + { + char *filename; + filename = Bytes_AsString(file); + + if (filename == NULL) + { + PyErr_SetString(PyExc_ValueError, "Failed to decode filename"); + goto end; + } + + if (PGFT_TryLoadFont_Filename(ft, font, filename, face_index) != 0) + { + PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft)); + goto end; + } + } + else + { + SDL_RWops *source; + source = RWopsFromPython(file); + + if (source == NULL) + { + PyErr_SetString(PyExc_ValueError, + "Invalid 'file' parameter (must be a File object or a file name)"); + goto end; + } + + if (PGFT_TryLoadFont_RWops(ft, font, source, face_index) != 0); + { + PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft)); + goto end; + } + + Py_INCREF(file); + Py_INCREF(file); + Py_INCREF(file); + Py_INCREF(file); + return 0; + } + +end: + + if (file != original_file) + { + Py_XDECREF(file); + } + + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject* +_ftfont_repr(PyObject *self) +{ + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + return Text_FromFormat("Font('%s')", font->id.open_args.pathname); +} + + +/**************************************************** + * GETTERS/SETTERS + ****************************************************/ + +/** Vertical attribute */ +static PyObject* +_ftfont_getvertical(PyObject *self, void *closure) +{ + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + return PyBool_FromLong(font->vertical); +} + +static int +_ftfont_setvertical(PyObject *self, PyObject *value, void *closure) +{ + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + if (!PyBool_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "Expecting 'bool' type"); + return -1; + } + font->vertical = (FT_Byte)PyObject_IsTrue(value); + return 0; +} + + +/** Antialias attribute */ +static PyObject* +_ftfont_getantialias(PyObject *self, void *closure) +{ + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + return PyBool_FromLong(font->antialias); +} + +static int +_ftfont_setantialias(PyObject *self, PyObject *value, void *closure) +{ + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + if (!PyBool_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "Expecting 'bool' type"); + return -1; + } + font->antialias = (FT_Byte)PyObject_IsTrue(value); + return 0; +} + + +/** Generic style attributes */ +static PyObject* +_ftfont_getstyle_flag(PyObject *self, void *closure) +{ + const int style_flag = (int)closure; + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + + return PyBool_FromLong(font->style & style_flag); +} + +static int +_ftfont_setstyle_flag(PyObject *self, PyObject *value, void *closure) +{ + const int style_flag = (int)closure; + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + + if (!PyBool_Check(value)) + { + PyErr_SetString(PyExc_TypeError, + "The style value must be a boolean"); + return -1; + } + + if (PyObject_IsTrue(value)) + { + font->style |= (FT_Byte)style_flag; + } + else + { + font->style &= (FT_Byte)(~style_flag); + } + + return 0; +} + + +/** Style attribute */ +static PyObject* +_ftfont_getstyle (PyObject *self, void *closure) +{ + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + + return PyInt_FromLong(font->style); +} + +static int +_ftfont_setstyle(PyObject *self, PyObject *value, void *closure) +{ + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + FT_UInt32 style; + + if (!PyInt_Check(value)) + { + PyErr_SetString(PyExc_TypeError, + "The style value must be an integer" + " from the FT constants module"); + return -1; + } + + style = (FT_UInt32)PyInt_AsLong(value); + + if (PGFT_CheckStyle(style) != 0) + { + PyErr_SetString(PyExc_ValueError, "Invalid style value"); + return -1; + } + + font->style = (FT_Byte)style; + return 0; +} + +static PyObject* +_ftfont_getheight(PyObject *self, void *closure) +{ + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + return PyInt_FromLong(PGFT_Face_GetHeight(ft, (PyFreeTypeFont *)self)); +} + +static PyObject* +_ftfont_getname(PyObject *self, void *closure) +{ + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + return Text_FromUTF8(PGFT_Face_GetName(ft, (PyFreeTypeFont *)self)); +} + +static PyObject* +_ftfont_getfixedwidth(PyObject *self, void *closure) +{ + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + return PyBool_FromLong(PGFT_Face_IsFixedWidth(ft, (PyFreeTypeFont *)self)); +} + + + +/**************************************************** + * MAIN METHODS + ****************************************************/ +static PyObject* +_ftfont_getsize(PyObject *self, PyObject* args, PyObject *kwds) +{ + /* keyword list */ + static char *kwlist[] = + { + "text", "style", "rotation", "ptsize", NULL + }; + + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + PyObject *text, *rtuple = NULL; + FT_Error error; + int ptsize = -1; + int width, height; + + FontRenderMode render; + int rotation = 0; + int style = 0; + + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iii", kwlist, + &text, &style, &rotation, &ptsize)) + return NULL; + + /* Build rendering mode, always anti-aliased by default */ + if (PGFT_BuildRenderMode(ft, font, &render, + ptsize, style, rotation) != 0) + { + PyErr_SetString(PyExc_ValueError, PGFT_GetError(ft)); + return NULL; + } + + error = PGFT_GetTextSize(ft, font, &render,text, &width, &height); + + if (error) + PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft)); + else + rtuple = Py_BuildValue ("(ii)", width, height); + + return rtuple; +} + +static PyObject * +_ftfont_getmetrics(PyObject *self, PyObject* args, PyObject *kwds) +{ + /* keyword list */ + static char *kwlist[] = + { + "text", "ptsize", "bbmode", NULL + }; + + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + FontRenderMode render; + + /* aux vars */ + void *buf = NULL; + int char_id, length, i, isunicode = 0; + + /* arguments */ + PyObject *text, *list; + int ptsize = -1; + int bbmode = FT_BBOX_PIXEL_GRIDFIT; + + /* grab freetype */ + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + /* parse args */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ii", kwlist, + &text, &ptsize, &bbmode)) + return NULL; + + /* + * Build the render mode with the given size and no + * rotation/styles/vertical text + */ + if (PGFT_BuildRenderMode(ft, font, + &render, ptsize, FT_STYLE_NORMAL, 0) != 0) + { + PyErr_SetString(PyExc_ValueError, PGFT_GetError(ft)); + return NULL; + } + + /* check text */ + if (PyUnicode_Check(text)) + { + buf = PyUnicode_AsUnicode(text); + isunicode = 1; + } + else if (Bytes_Check(text)) + { + buf = Bytes_AS_STRING(text); + } + else + { + PyErr_SetString(PyExc_TypeError, + "argument must be a string or unicode"); + } + + if (!buf) + return NULL; + + if (isunicode) + length = PyUnicode_GetSize(text); + else + length = Bytes_Size(text); + +#define _GET_METRICS(_mt, _tuple_format) { \ + for (i = 0; i < length; i++) \ + { \ + _mt minx_##_mt, miny_##_mt; \ + _mt maxx_##_mt, maxy_##_mt; \ + _mt advance_##_mt; \ + \ + if (isunicode) char_id = ((Py_UNICODE *)buf)[i];\ + else char_id = ((char *)buf)[i]; \ + \ + if (PGFT_GetMetrics(ft, \ + (PyFreeTypeFont *)self, char_id, \ + &render, bbmode, \ + &minx_##_mt, &maxx_##_mt, \ + &miny_##_mt, &maxy_##_mt, \ + &advance_##_mt) == 0) \ + { \ + PyList_SetItem (list, i, \ + Py_BuildValue(_tuple_format, \ + minx_##_mt, maxx_##_mt, \ + miny_##_mt, maxy_##_mt, \ + advance_##_mt)); \ + } \ + else \ + { \ + Py_INCREF (Py_None); \ + PyList_SetItem (list, i, Py_None); \ + } \ + }} + + /* get metrics */ + if (bbmode == FT_BBOX_EXACT || bbmode == FT_BBOX_EXACT_GRIDFIT) + { + list = PyList_New(length); + _GET_METRICS(float, "(fffff)"); + } + else if (bbmode == FT_BBOX_PIXEL || bbmode == FT_BBOX_PIXEL_GRIDFIT) + { + list = PyList_New(length); + _GET_METRICS(int, "(iiiii)"); + } + else + { + PyErr_SetString(PyExc_ValueError, "Invalid bbox mode specified"); + return NULL; + } + +#undef _GET_METRICS + + return list; +} + +static PyObject* +_ftfont_render_raw(PyObject *self, PyObject* args, PyObject *kwds) +{ + /* keyword list */ + static char *kwlist[] = + { + "text", "ptsize", NULL + }; + + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + FontRenderMode render; + + /* input arguments */ + PyObject *text = NULL; + int ptsize = -1; + + /* output arguments */ + PyObject *rbuffer = NULL; + int width, height; + + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i", kwlist, &text, &ptsize)) + return NULL; + + /* + * Build the render mode with the given size and no + * rotation/styles/vertical text + */ + if (PGFT_BuildRenderMode(ft, font, + &render, ptsize, FT_STYLE_NORMAL, 0) != 0) + { + PyErr_SetString(PyExc_ValueError, PGFT_GetError(ft)); + return NULL; + } + + rbuffer = PGFT_Render_PixelArray(ft, font, &render, text, &width, &height); + + if (!rbuffer) + { + PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft)); + return NULL; + } + + return Py_BuildValue("(iiO)", width, height, rbuffer); +} + +static PyObject* +_ftfont_render(PyObject *self, PyObject* args, PyObject *kwds) +{ +#ifndef HAVE_PYGAME_SDL_VIDEO + + PyErr_SetString(PyExc_RuntimeError, "SDL support is missing. Cannot render on surfaces"); + return NULL; + +#else + /* keyword list */ + static char *kwlist[] = + { + "dest", "text", "fgcolor", "bgcolor", + "style", "rotation", "ptsize", NULL + }; + + PyFreeTypeFont *font = (PyFreeTypeFont *)self; + + /* input arguments */ + PyObject *text = NULL; + int ptsize = -1; + PyObject *target_tuple = NULL; + PyObject *fg_color_obj = NULL; + PyObject *bg_color_obj = NULL; + int rotation = 0; + int style = FT_STYLE_DEFAULT; + + /* output arguments */ + PyObject *rtuple = NULL; + int width, height; + + FontColor fg_color, bg_color; + FontRenderMode render; + + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|Oiii", kwlist, + &target_tuple, &text, &fg_color_obj, /* required */ + &bg_color_obj, &style, &rotation, &ptsize)) /* optional */ + return NULL; + + if (!RGBAFromColorObj(fg_color_obj, (Uint8 *)&fg_color)) + { + PyErr_SetString(PyExc_TypeError, "fgcolor must be a Color"); + return NULL; + } + + if (bg_color_obj) + { + if (bg_color_obj == Py_None) + bg_color_obj = NULL; + + else if (!RGBAFromColorObj(bg_color_obj, (Uint8 *)&bg_color)) + { + PyErr_SetString(PyExc_TypeError, "bgcolor must be a Color"); + return NULL; + } + } + + if (PGFT_BuildRenderMode(ft, font, + &render, ptsize, style, rotation) != 0) + { + PyErr_SetString(PyExc_ValueError, PGFT_GetError(ft)); + return NULL; + } + + if (target_tuple == Py_None) + { + SDL_Surface *r_surface = NULL; + + r_surface = PGFT_Render_NewSurface(ft, font, &render, text, + &fg_color, bg_color_obj ? &bg_color : NULL, + &width, &height); + + if (!r_surface) + { + PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft)); + return NULL; + } + + rtuple = Py_BuildValue("(Oii)", + PySurface_New(r_surface), width, height); + + } + else + { + SDL_Surface *surface = NULL; + PyObject *surface_obj = NULL; + int xpos = 0, ypos = 0; + + if (!PyArg_ParseTuple(target_tuple, "Oii", &surface_obj, &xpos, &ypos)) + return NULL; + + if (!PySurface_Check(surface_obj)) + { + PyErr_SetString(PyExc_TypeError, "Target surface must be a SDL surface"); + return NULL; + } + + surface = PySurface_AsSurface(surface_obj); + + if (PGFT_Render_ExistingSurface(ft, font, &render, + text, surface, xpos, ypos, + &fg_color, bg_color_obj ? &bg_color : NULL, + &width, &height) != 0) + { + PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft)); + return NULL; + } + + rtuple = Py_BuildValue("(iiO)", width, height); + } + + return rtuple; + +#endif // HAVE_PYGAME_SDL_VIDEO +} + +/**************************************************** + * C API CALLS + ****************************************************/ +PyObject* +PyFreeTypeFont_New(const char *filename, int face_index) +{ + PyFreeTypeFont *font; + + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + if (!filename) + return NULL; + + font = (PyFreeTypeFont *)PyFreeTypeFont_Type.tp_new( + &PyFreeTypeFont_Type, NULL, NULL); + + if (!font) + return NULL; + + font->ptsize = -1; + font->style = FT_STYLE_NORMAL; + font->antialias = 1; + font->vertical = 0; + + if (PGFT_TryLoadFont_Filename(ft, font, filename, face_index) != 0) + { + PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft)); + return NULL; + } + + return (PyObject*) font; +} + + + + + + + +/**************************************************** + * FREETYPE MODULE METHODS + ****************************************************/ + +/*************************************************************** + * + * Bindings for initialization/cleanup functions + * + * Explicit init/quit functions are required to work around + * some issues regarding module caching and multi-threaded apps. + * It's always good to let the user choose when to initialize + * the module. + * + * TODO: These bindings can be removed once proper threading + * support is in place. + * + ***************************************************************/ + +static PyObject* +_ft_autoinit(PyObject* self) +{ + FT_Error result = 1; + + if (FREETYPE_MOD_STATE(self)->freetype == NULL) + { + result = (PGFT_Init(&(FREETYPE_MOD_STATE(self)->freetype), + PGFT_DEFAULT_CACHE_SIZE) == 0); + } + + return PyInt_FromLong(result); +} + +static PyObject * +_ft_quit(PyObject *self) +{ + if (FREETYPE_MOD_STATE(self)->freetype != NULL) + { + PGFT_Quit(FREETYPE_MOD_STATE(self)->freetype); + FREETYPE_MOD_STATE(self)->freetype = NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +_ft_init(PyObject *self, PyObject *args) +{ + PyObject *result; + FT_Int cache_size = PGFT_DEFAULT_CACHE_SIZE; + + if (!PyArg_ParseTuple(args, "|i", &cache_size)) + return NULL; + + result = _ft_autoinit(self); + + if (!PyObject_IsTrue(result)) + { + PyErr_SetString(PyExc_RuntimeError, + "Failed to initialize the FreeType2 library"); + return NULL; + } + + FREETYPE_MOD_STATE(self)->freetype->cache_size = cache_size; + Py_RETURN_NONE; +} + + +static PyObject * +_ft_get_error(PyObject *self) +{ + FreeTypeInstance *ft; + ASSERT_GRAB_FREETYPE(ft, NULL); + + if (ft->_error_msg[0]) + { + return Text_FromUTF8(ft->_error_msg); + } + + Py_RETURN_NONE; +} + +static PyObject * +_ft_get_version(PyObject *self) +{ + /* Return the linked FreeType2 version */ + return Py_BuildValue("(iii)", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH); +} + +static PyObject * +_ft_was_init(PyObject *self) +{ + return PyBool_FromLong((FREETYPE_MOD_STATE (self)->freetype != NULL)); +} + +static int +_ft_traverse (PyObject *mod, visitproc visit, void *arg) +{ + return 0; +} + +static int +_ft_clear (PyObject *mod) +{ + if (FREETYPE_MOD_STATE(mod)->freetype) + { + PGFT_Quit(FREETYPE_MOD_STATE(mod)->freetype); + FREETYPE_MOD_STATE(mod)->freetype = NULL; + } + return 0; +} + + + +/**************************************************** + * FREETYPE MODULE DECLARATION + ****************************************************/ +#if PY3 +struct PyModuleDef _freetypemodule = +{ + PyModuleDef_HEAD_INIT, + "freetype", + DOC_PYGAMEFREETYPE, + sizeof(_FreeTypeState), + _ft_methods, + NULL, + _ft_traverse, + _ft_clear, + NULL +}; +#else +_FreeTypeState _modstate; +#endif + +MODINIT_DEFINE (freetype) +{ + PyObject *module, *apiobj, *base, *base_register_quit, *quit, *rval; + static void* c_api[PYGAMEAPI_FREETYPE_NUMSLOTS]; + + PyFREETYPE_C_API[0] = PyFREETYPE_C_API[0]; + + import_pygame_base(); + if (PyErr_Occurred()) + { + MODINIT_ERROR; + } + + import_pygame_surface(); + if (PyErr_Occurred()) + { + MODINIT_ERROR; + } + + import_pygame_color(); + if (PyErr_Occurred()) + { + MODINIT_ERROR; + } + + import_pygame_rwobject(); + if (PyErr_Occurred()) + { + MODINIT_ERROR; + } + + /* import needed modules. Do this first so if there is an error + the module is not loaded. + */ + base = PyImport_ImportModule ("base"); + if (!base) { + MODINIT_ERROR; + } + base_register_quit = PyObject_GetAttrString (base, "register_quit"); + Py_DECREF (base); + if (!base_register_quit) { + MODINIT_ERROR; + } + + /* type preparation */ + if (PyType_Ready(&PyFreeTypeFont_Type) < 0) + { + Py_DECREF(base_register_quit); + MODINIT_ERROR; + } + + PyFreeTypeFont_Type.tp_new = PyType_GenericNew; + +#if PY3 + module = PyModule_Create(&_freetypemodule); +#else + /* TODO: DOC */ + module = Py_InitModule3("freetype", _ft_methods, DOC_PYGAMEFREETYPE); +#endif + + if (module == NULL) + { + Py_DECREF(base_register_quit); + MODINIT_ERROR; + } + + Py_INCREF((PyObject *)&PyFreeTypeFont_Type); + if (PyModule_AddObject(module, "Font", (PyObject *)&PyFreeTypeFont_Type) == -1) + { + Py_DECREF(base_register_quit); + Py_DECREF((PyObject *) &PyFreeTypeFont_Type); + DECREF_MOD(module); + MODINIT_ERROR; + } + +# define DEC_CONST(x) PyModule_AddIntConstant(module, #x, (int)FT_##x) + + DEC_CONST(STYLE_NORMAL); + DEC_CONST(STYLE_BOLD); + DEC_CONST(STYLE_ITALIC); + DEC_CONST(STYLE_UNDERLINE); + + DEC_CONST(BBOX_EXACT); + DEC_CONST(BBOX_EXACT_GRIDFIT); + DEC_CONST(BBOX_PIXEL); + DEC_CONST(BBOX_PIXEL_GRIDFIT); + + /* export the c api */ + c_api[0] = &PyFreeTypeFont_Type; + c_api[1] = &PyFreeTypeFont_New; + + apiobj = PyCObject_FromVoidPtr(c_api, NULL); + if (apiobj == NULL) + { + Py_DECREF (base_register_quit); + DECREF_MOD(module); + MODINIT_ERROR; + } + + if (PyModule_AddObject(module, PYGAMEAPI_LOCAL_ENTRY, apiobj) == -1) + { + Py_DECREF(base_register_quit); + Py_DECREF(apiobj); + DECREF_MOD(module); + MODINIT_ERROR; + } + + quit = PyObject_GetAttrString (module, "quit"); + if (quit == NULL) { /* assertion */ + Py_DECREF (base_register_quit); + DECREF_MOD (module); + MODINIT_ERROR; + } + rval = PyObject_CallFunctionObjArgs (base_register_quit, quit, NULL); + Py_DECREF (base_register_quit); + Py_DECREF (quit); + if (rval == NULL) { + DECREF_MOD (module); + MODINIT_ERROR; + } + Py_DECREF (rval); + + MODINIT_RETURN(module); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype.doc Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,302 @@ +pygame.freetype +Enhanced Pygame module for loading and rendering fonts + +This module allows for rendering all font formats supported by FreeType, namely +TTF, Type1, CFF, OpenType, SFNT, PCF, FNT, BDF, PFR and Type42 fonts. + +This module is optional, and replaces all of the functionality of the +original 'font' module, whilst expanding it. This module depends in no +way on the SDL_ttf library. + +You should test that pygame.freetype is initialized before attempting +to use the module; if the module is available and loaded, it will be +automatically initialized by pygame.init() + +Most of the work done with fonts is done by using the actual Font objects. +The module by itself only has routines to initialize itself and create +Font objects with pygame.freetype.Font(). + +You can load fonts from the system by using the pygame.freetype.SysFont() +function. There are a few other functions to help lookup the system fonts. + +Pygame comes with a builtin default font. This can always be accessed by +passing None as the font name to the Font constructor. + +<SECTION> + +get_error +Get the latest error +pygame.freetype.get_error(): return str + +Returns the description of the last error which occurred in the +FreeType library, or None if no errors have occurred. +<END> + + +get_version +Get the FreeType version +pygame.freetype.get_version(): return (int, int, int) + +Gets the version of the FreeType2 library which was used to build +the 'freetype' module. + +Note that the FreeType module depends on the FreeType 2 library, +and will not compile with the original FreeType 1.0, hence the first +element of the tuple will always be 2. +<END> + +init +Initialize the underlying FreeType 2 library. +pygame.freetype.init(default_cache_size=64): return None + +This function initializes the underlying FreeType 2 library and must +be called before trying to use any of the functionality of the 'freetype' module. + +However, if the module is available, this function will be automatically +called by pygame.init(). It is safe to call this function more than once. + +Optionally, you may specify a default size for the Glyph cache: this is the +maximum amount of glyphs that will be cached at any given time by the module. +Exceedingly small values will be automatically tuned for performance. +<END> + +quit +Shuts down the underlying FreeType 2 library. +pygame.freetype.quit(): return None + +This function de-initializes the 'freetype' module. +After calling this function, you should not invoke any class, +method or function related to the 'freetype' module as they are likely to +fail or might give unpredictable results. It is safe to call this function +even if the module hasn't been initialized yet. +<END> + +was_init +Returns whether the the FreeType 2 library is initialized. +pygame.freetype.quit(): return bool + +Returns whether the the FreeType 2 library is initialized. +<END> + + +Font +Creates a new Font from a supported font file. +pygame.freetype.Font(file, style=STYLE_NONE, ptsize=-1, face_index=0): return Font + +'file' can be either a string representing the font's filename, +a file-like object containing the font, or None; in this last case +the default, built-in font will be used. + +Optionally, a *ptsize* argument may be specified to set the +default size in points which will be used to render the font. +Such size can also be specified manually on each method call. +Because of the way the caching system works, specifying a +default size on the constructor doesn't imply a performance +gain over manually passing the size on each function call. + +If the font file has more than one face, the *index* argument +may be specified to specify which face index to load. Defaults +to 0; font loading will fail if the given index is not contained +in the font. + +The 'style' argument will set the default style (italic, +underline, bold) used to draw this font. This style may be +overriden on any Font.render() call. +<SECTION> + +name +Gets the name of the font face. +Font.name: return string + +Read only. Returns the real (long) name of the font type face, +as specified on the font file. +<END> + +get_size +Gets the size of rendered text +Font.get_size(text, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (int, int) + +Gets the size in pixels which 'text' will occupy when rendered using +this Font. The calculations will take into account the font's default style +(e.g. underlined fonts take extra height for the underline), or the +style may be overridden by the 'style' parameter. + +Returns a tuple containing the width and height of the text's +bounding box. + +The calculations are done using the font's default size in points, +without any rotation, and taking into account fonts which are set +to be drawn vertically via the Font.vertical attribute. +Optionally you may specify another point size to use via the +'ptsize' argument, or a text rotation via the 'rotation' argument. +<END> + +get_metrics +Gets glyph metrics for the font's characters +Font.get_metrics(text, bbmode=BBOX_PIXEL_GRIDFIT, ptsize=default): return [(...), ...] + +Returns the glyph metrics for each character in 'text'. + +The glyph metrics are returned inside a list; each character will +be represented as a tuple inside the list with the following values: + + (min_x, max_x, min_y, max_y, horizontal_advance) + +By default, these values are returned as grid-fitted pixel +coordinates (ints) but one of the following constants +may be passed as the bbmode argument to change this: + + BBOX_EXACT: Return accurate floating point values. + + BBOX_EXACT_GRIDFIT: Return accurate floating point values aligned + to the drawing grid. + + BBOX_PIXEL: Return pixel coordinates (ints). + + BBOX_PIXEL_GRIDFIT (default): Return grid-aligned pixel coordinates. + +The calculations are done using the font's default size in points. +Optionally you may specify another point size to use. +<END> + +height +Gets the height of the Font +Font.height: return int + +Read only. Gets the height of the Font. This is the average value of all glyphs in the font. +<END> + +render +Renders text on a surface +Font.render(dest, text, fgcolor, bgcolor=None, style=STYLE_DEFAULT, rotation=0, ptsize=default): return (Surface, int, int) + +Renders the string 'text' to a pygame.Surface, using the color 'fgcolor'. + +The 'dest' parameter is supposed to be a tuple containing +the surface and the coordinates at which the text will be rendered, +in that order. + +If such tuple exists, and the destination surface is a valid +pygame.Surface (independently of its bit depth), the text will +be rendered directly on top of it at the +passed coordinates, using the given 'fgcolor', and painting +the background of the text with the given 'bgcolor', if available. +The alpha values for both colors are always taken into account. +The width and height of the rendered text will be returned in a tuple. + +If 'None' is passed instead of the destination tuple, a new 32 bit +pygame.Surface will be created with the required size to contain +the drawn text, and using *bgcolor* as its +background color. If a background color is not available, the +surface will be filled with zero alpha opacity. +The width and height of the rendered text, +together with the new :class:`pygame2.sdl.video.Surface`, will +be returned in a tuple. + +The rendering is done using the font's default size in points and +its default style, without any rotation, and taking into account +fonts which are set to be drawn vertically via the Font.vertical attribute. +Optionally you may specify another point size to use via the +'ptsize' argument, a text rotation via the 'rotation' argument, +or a new text style via the 'style' argument. +<END> + +style +Gets or sets the font's style +Font.style: return int + +Gets or sets the default style of the Font. This default style +will be used for all text rendering and size calculations unless +overriden specifically in the `render()` or `get_size()` calls. +The style value may be a bitwise OR of one or more of the following +constants: + + STYLE_NONE + STYLE_UNDERLINE + STYLE_ITALIC + STYLE_BOLD + +These constants may be found on the FreeType constants module. +Optionally, the default style can be modified or obtained +accessing the individual style attributes (underline, italic, +bold). +<END> + + +underline +Gets or sets the font's underline style +Font.underline: return bool + +Gets or sets whether the font will be underlined when drawing text. +This default style value will be used for all text rendering and +size calculations unless overriden specifically in the `render()` +or `get_size()` calls, via the 'style' parameter. +<END> + +bold +Gets or sets the font's bold style +Font.bold: return bool + +Gets or sets whether the font will be bold when drawing text. +This default style value will be used for all text rendering and +size calculations unless overriden specifically in the `render()` +or `get_size()` calls, via the 'style' parameter. +<END> + +italic +Gets or sets the font's italic style +Font.italic: return bool + +Gets or sets whether the font will be in italics when drawing text. +This default style value will be used for all text rendering and +size calculations unless overriden specifically in the `render()` +or `get_size()` calls, via the 'style' parameter. +<END> + +fixed_width +Gets whether the font is fixed-width +Font.fixed_width: return bool + +Read only. Returns whether this Font is a fixed-width (bitmap) font. + +Note that scalable fonts whose glyphs are all the same width +(i.e. monospace TTF fonts used for programming) are not considered +fixed width. +<END> + +antialiased +Font antialiasing mode +Font.antialiased: return bool + +Gets or sets the font's antialiasing mode. This defaults to True +on all fonts, which will be rendered by default antialiased. + +Setting this to true will change all rendering methods to use +glyph bitmaps without antialiasing, which supposes a small speed gain +and a significant memory gain because of the way glyphs are cached. +<END> + +vertical +Font vertical mode +Font.vertical: return bool + +Gets or sets whether the font is a vertical font such as fonts +representing Kanji glyphs or other styles of vertical writing. + +Changing this attribute will cause the font to be rendering +vertically, and affects all other methods which manage glyphs +or text layouts to use vertical metrics accordingly. + +Note that the FreeType library doesn't automatically detect +whether a font contains glyphs which are always supposed to +be drawn vertically, so this attribute must be set manually +by the user. + +Also note that several font formats (specially bitmap based +ones) don't contain the necessary metrics to draw glyphs +vertically, so drawing in those cases will give unspecified +results. +<END> + +<END> +<END>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,120 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef _PYGAME_FREETYPE_H_ +#define _PYGAME_FREETYPE_H_ + +#define PGFT_PYGAME1_COMPAT +#define HAVE_PYGAME_SDL_VIDEO +#define HAVE_PYGAME_SDL_RWOPS + +#include "pygame.h" +#include "pgcompat.h" + +#if PY3 +# define IS_PYTHON_3 +#endif + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_CACHE_H +#include FT_XFREE86_H + +/********************************************************** + * Global module constants + **********************************************************/ + +/* Render styles */ +#define FT_STYLE_NORMAL 0x00 +#define FT_STYLE_BOLD 0x01 +#define FT_STYLE_ITALIC 0x02 +#define FT_STYLE_UNDERLINE 0x04 +#define FT_STYLE_DEFAULT 0xFF + +/* Bounding box modes */ +#define FT_BBOX_EXACT FT_GLYPH_BBOX_SUBPIXELS +#define FT_BBOX_EXACT_GRIDFIT FT_GLYPH_BBOX_GRIDFIT +#define FT_BBOX_PIXEL FT_GLYPH_BBOX_TRUNCATE +#define FT_BBOX_PIXEL_GRIDFIT FT_GLYPH_BBOX_PIXELS + +/* Rendering flags */ +#define FT_RFLAG_NONE (0) +#define FT_RFLAG_ANTIALIAS (1 << 0) +#define FT_RFLAG_AUTOHINT (1 << 1) +#define FT_RFLAG_VERTICAL (1 << 2) +#define FT_RFLAG_HINTED (1 << 3) +#define FT_RFLAG_DEFAULTS (FT_RFLAG_NONE | FT_RFLAG_HINTED) + + +#define FT_RENDER_NEWBYTEARRAY 0x0 +#define FT_RENDER_NEWSURFACE 0x1 +#define FT_RENDER_EXISTINGSURFACE 0x2 + +/********************************************************** + * Global module types + **********************************************************/ + +typedef struct +{ + int face_index; + FT_Open_Args open_args; +} FontId; + +typedef struct +{ + PyObject_HEAD + FontId id; + + FT_Int16 ptsize; + FT_Byte style; + FT_Byte vertical; + FT_Byte antialias; + + void *_internals; +} PyFreeTypeFont; + + +/********************************************************** + * Module declaration + **********************************************************/ +#define PYGAMEAPI_FREETYPE_NUMSLOTS 2 + +#define PyFreeTypeFont_AsFont(x) (((PyFreeTypeFont *)x)->font) + +#ifndef PYGAME_FREETYPE_INTERNAL + +#define PyFreeTypeFont_Check(x) ((x)->ob_type == (PyTypeObject*)PyFREETYPE_C_API[0]) +#define PyFreeTypeFont_Type (*(PyTypeObject*)PyFREETYPE_C_API[0]) +#define PyFont_New (*(PyObject*(*)(const char*, int))PyFREETYPE_C_API[1]) + +#define import_pygame_freetype() { \ + PyObject *module = PyImport_ImportModule(MODPREFIX "freetype"); \ + if (module != NULL) { \ + PyObject *dict = PyModule_GetDict(module); \ + PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY); \ + if(PyCObject_Check(c_api)) {\ + void** localptr = (void**)PyCObject_AsVoidPtr(c_api); \ + memcpy(PyFREETYPE_C_API, localptr, sizeof(void*)*PYGAMEAPI_FREETYPE_NUMSLOTS); \ +} Py_DECREF(module); } } + +#endif /* PYGAME_FREETYPE_INTERNAL */ + +static void *PyFREETYPE_C_API[PYGAMEAPI_FREETYPE_NUMSLOTS] = {NULL}; + +#endif /* _PYGAME_FREETYPE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_cache.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,347 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#define PYGAME_FREETYPE_INTERNAL + +#include "ft_wrap.h" +#include FT_MODULE_H + +FT_UInt32 _PGFT_Cache_Hash(const FontRenderMode *, FT_UInt); +FT_UInt32 _PGFT_GetLoadFlags(const FontRenderMode *); + +FontCacheNode *_PGFT_Cache_AllocateNode(FreeTypeInstance *, + FontCache *, const FontRenderMode *, FT_UInt); +void _PGFT_Cache_FreeNode(FontCache *, FontCacheNode *); + + +FT_UInt32 _PGFT_GetLoadFlags(const FontRenderMode *render) +{ + FT_UInt32 load_flags = FT_LOAD_DEFAULT; + + load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; + + if (render->render_flags & FT_RFLAG_AUTOHINT) + load_flags |= FT_LOAD_FORCE_AUTOHINT; + + if (render->render_flags & FT_RFLAG_HINTED) + { + load_flags |= (render->render_flags & FT_RFLAG_ANTIALIAS) ? + FT_LOAD_TARGET_NORMAL : + FT_LOAD_TARGET_MONO; + } + else + { + load_flags |= FT_LOAD_NO_HINTING; + } + + return load_flags; +} + +FT_UInt32 _PGFT_Cache_Hash(const FontRenderMode *render, FT_UInt glyph_index) +{ + const FT_UInt32 m = 0x5bd1e995; + const int r = 24; + + FT_UInt32 h, k; + + /* + * Quick hashing algorithm, based off MurmurHash2. + * Assumes sizeof(FontRenderMode) == 8 + */ + + h = (glyph_index << 12) ^ glyph_index; + + k = *(const FT_UInt32 *)render; + k *= m; k ^= k >> r; + k *= m; h *= m; h ^= k; + + k = *(((const FT_UInt32 *)render) + 1); + k *= m; k ^= k >> r; + k *= m; h *= m; h ^= k; + + h ^= h >> 13; + h *= m; + h ^= h >> 15; + + return h; +} + +void PGFT_Cache_Init(FreeTypeInstance *ft, + FontCache *cache, PyFreeTypeFont *parent) +{ + int cache_size = MAX(ft->cache_size - 1, PGFT_MIN_CACHE_SIZE - 1); + + /* + * Make sure this is a power of 2. + */ + cache_size = cache_size | (cache_size >> 1); + cache_size = cache_size | (cache_size >> 2); + cache_size = cache_size | (cache_size >> 4); + cache_size = cache_size | (cache_size >> 8); + cache_size = cache_size | (cache_size >>16); + + cache_size = cache_size + 1; + + cache->nodes = calloc((size_t)cache_size, sizeof(FontGlyph *)); + cache->depths = calloc((size_t)cache_size, sizeof(FT_Byte)); + cache->font = parent; + cache->free_nodes = NULL; + cache->size_mask = (FT_UInt32)(cache_size - 1); + +#ifdef PGFT_DEBUG_CACHE + cache->count = 0; + cache->_debug_delete_count = 0; + cache->_debug_access = 0; + cache->_debug_hit = 0; + cache->_debug_miss = 0; +#endif +} + +void PGFT_Cache_Destroy(FontCache *cache) +{ + FT_UInt i; + FontCacheNode *node, *next; + + if (cache == NULL) + return; + +#ifdef PGFT_DEBUG_CACHE + fprintf(stderr, "Cache stats:\n"); + fprintf(stderr, "\t%d accesses in total\n", cache->_debug_access); + fprintf(stderr, "\t%d hits / %d misses\n", cache->_debug_hit, cache->_debug_miss); + fprintf(stderr, "\t%f hit ratio\n", (float)cache->_debug_hit/(float)cache->_debug_access); + fprintf(stderr, "\t%d nodes kicked\n", cache->_debug_delete_count); +#endif + + for (i = 0; i <= cache->size_mask; ++i) + { + node = cache->nodes[i]; + + while (node) + { + next = node->next; + _PGFT_Cache_FreeNode(cache, node); + node = next; + } + } + + free(cache->nodes); + free(cache->depths); +} + +void PGFT_Cache_Cleanup(FontCache *cache) +{ + const FT_Byte MAX_BUCKET_DEPTH = 2; + FontCacheNode *node, *prev; + FT_UInt32 i; + + for (i = 0; i <= cache->size_mask; ++i) + { + while (cache->depths[i] > MAX_BUCKET_DEPTH) + { + node = cache->nodes[i]; + prev = NULL; + + for (;;) + { + if (!node->next) + { +#ifdef PGFT_DEBUG_CACHE + cache->_debug_delete_count++; +#endif + + prev->next = NULL; + _PGFT_Cache_FreeNode(cache, node); + break; + } + + prev = node; + node = node->next; + } + } + } + +} + +FontGlyph *PGFT_Cache_FindGlyph(FreeTypeInstance *ft, FontCache *cache, + FT_UInt character, const FontRenderMode *render) +{ + FontCacheNode **nodes = cache->nodes; + FontCacheNode *node, *prev; + + FT_UInt32 hash = _PGFT_Cache_Hash(render, character); + FT_UInt32 bucket = hash & cache->size_mask; + + node = nodes[bucket]; + prev = NULL; + +#ifdef PGFT_DEBUG_CACHE + cache->_debug_access++; +#endif + + while (node) + { + if (node->hash == hash) + { + if (prev) + { + prev->next = node->next; + node->next = nodes[bucket]; + nodes[bucket] = node; + } + +#ifdef PGFT_DEBUG_CACHE + cache->_debug_hit++; +#endif + + return &node->glyph; + } + + prev = node; + node = node->next; + } + + node = _PGFT_Cache_AllocateNode(ft, cache, render, character); + +#ifdef PGFT_DEBUG_CACHE + cache->_debug_miss++; +#endif + + return &node->glyph; +} + +void _PGFT_Cache_FreeNode(FontCache *cache, FontCacheNode *node) +{ + if (node == NULL) + return; + +#ifdef PGFT_DEBUG_CACHE + cache->count--; +#endif + + cache->depths[node->hash & cache->size_mask]--; + + FT_Done_Glyph(node->glyph.image); + free(node); +} + +FontCacheNode *_PGFT_Cache_AllocateNode(FreeTypeInstance *ft, + FontCache *cache, const FontRenderMode *render, FT_UInt character) +{ + FontCacheNode *node = NULL; + FontGlyph *glyph = NULL; + + FT_Glyph_Metrics *metrics; + FT_Face face; + + FT_UInt32 load_flags; + FT_Fixed bold_str = 0; + int gindex; + FT_UInt32 bucket; + + /* + * Grab face reference + */ + face = _PGFT_GetFaceSized(ft, cache->font, render->pt_size); + + if (!face) + { + _PGFT_SetError(ft, "Failed to resize face", 0); + goto cleanup; + } + + /* + * Allocate cache node + */ + node = malloc(sizeof(FontCacheNode)); + glyph = &node->glyph; + + /* + * Calculate the corresponding glyph index for the char + */ + gindex = FTC_CMapCache_Lookup(ft->cache_charmap, + (FTC_FaceID)&(cache->font->id), -1, character); + + if (gindex < 0) + { + _PGFT_SetError(ft, "Glyph character not found in font", 0); + goto cleanup; + } + + glyph->glyph_index = (FT_UInt)gindex; + + /* + * Get loading information + */ + load_flags = _PGFT_GetLoadFlags(render); + + if (render->style & FT_STYLE_BOLD) + bold_str = PGFT_GetBoldStrength(face); + + /* + * Load the glyph into the glyph slot + */ + if (FT_Load_Glyph(face, glyph->glyph_index, (FT_Int)load_flags) != 0 || + FT_Get_Glyph(face->glyph, &(glyph->image)) != 0) + goto cleanup; + + /* + * Precalculate useful metric values + */ + metrics = &face->glyph->metrics; + + glyph->vvector.x = (metrics->vertBearingX - bold_str / 2) - metrics->horiBearingX; + glyph->vvector.y = -(metrics->vertBearingY + bold_str) - (metrics->horiBearingY + bold_str); + + glyph->vadvance.x = 0; + glyph->vadvance.y = -(metrics->vertAdvance + bold_str); + + glyph->baseline = metrics->height - metrics->horiBearingY; + + glyph->size.x = metrics->width + bold_str; + glyph->size.y = metrics->height + bold_str; + + + /* + * Update cache internals + */ + node->hash = _PGFT_Cache_Hash(render, character); + bucket = node->hash & cache->size_mask; + node->next = cache->nodes[bucket]; + cache->nodes[bucket] = node; + + cache->depths[bucket]++; + +#ifdef PGFT_DEBUG_CACHE + cache->count++; +#endif + + return node; + + /* + * Cleanup on error + */ +cleanup: + if (glyph && glyph->image) + FT_Done_Glyph(glyph->image); + + free(node); + return NULL; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_metrics.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,170 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#define PYGAME_FREETYPE_INTERNAL + +#include "ft_wrap.h" +#include FT_MODULE_H + +extern FT_Matrix PGFT_SlantMatrix; + +/* Declarations */ +void _PGFT_GetMetrics_INTERNAL(FT_Glyph, FT_UInt, int *, int *, int *, int *, int *); +int _PGFT_GetTextSize_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, FontText *text); + + +/* Real text metrics */ +void _PGFT_GetMetrics_INTERNAL(FT_Glyph glyph, FT_UInt bbmode, + int *minx, int *maxx, int *miny, int *maxy, int *advance) +{ + FT_BBox box; + FT_Glyph_Get_CBox(glyph, bbmode, &box); + + *minx = box.xMin; + *maxx = box.xMax; + *miny = box.yMin; + *maxy = box.yMax; + *advance = glyph->advance.x; + + if (bbmode == FT_GLYPH_BBOX_TRUNCATE || + bbmode == FT_GLYPH_BBOX_PIXELS) + *advance >>= 16; +} + + +int PGFT_GetMetrics(FreeTypeInstance *ft, PyFreeTypeFont *font, + int character, const FontRenderMode *render, int bbmode, + void *minx, void *maxx, void *miny, void *maxy, void *advance) +{ + FontGlyph * glyph = NULL; + + glyph = PGFT_Cache_FindGlyph(ft, &PGFT_INTERNALS(font)->cache, + (FT_UInt)character, render); + + if (!glyph) + return -1; + + _PGFT_GetMetrics_INTERNAL(glyph->image, (FT_UInt)bbmode, + minx, maxx, miny, maxy, advance); + + if (bbmode == FT_BBOX_EXACT || bbmode == FT_BBOX_EXACT_GRIDFIT) + { +# define FP16_16(i) ((float)((int)(i) / 65536.0f)) +# define FP26_6(i) ((float)((int)(i) / 64.0f)) + + *(float *)minx = FP26_6(*(int *)minx); + *(float *)miny = FP26_6(*(int *)miny); + *(float *)maxx = FP26_6(*(int *)maxx); + *(float *)maxy = FP26_6(*(int *)maxy); + *(float *)advance = FP16_16(*(int *)advance); + +# undef FP16_16 +# undef FP26_6 + } + + return 0; + +} + + +int +_PGFT_GetTextSize_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, FontText *text) +{ + FT_Vector extent; + FT_Error error; + FT_Vector size; + + error = PGFT_LoadTextAdvances(ft, font, render, text); + + if (error) + return error; + + extent = text->advances[text->length - 1]; + + if (render->render_flags & FT_RFLAG_VERTICAL) + { + size.x = text->glyph_size.x; + size.y = ABS(extent.y); + } + else + { + size.x = extent.x; + size.y = text->glyph_size.y; + } + + if (render->rotation_angle) + { + size.x = MAX(size.x, size.y); + size.y = MAX(size.x, size.y); + } + + text->text_size.x = ABS(size.x); + text->text_size.y = ABS(size.y); + + return 0; +} + +int +PGFT_GetSurfaceSize(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, FontText *text, + int *width, int *height) +{ + int w, h; + + if (text == NULL || + _PGFT_GetTextSize_INTERNAL(ft, font, render, text) != 0) + return -1; + + w = text->text_size.x; + h = text->text_size.y; + + if (text->underline_size > 0) + { + h = MAX(h, text->underline_pos + text->underline_size); + } + + if (render->style & FT_STYLE_ITALIC) + { + FT_Vector s = {w, h}; + + FT_Vector_Transform(&s, &PGFT_SlantMatrix); + w = s.x; h = s.y; + } + + *width = PGFT_TRUNC(PGFT_CEIL(w)); + *height = PGFT_TRUNC(PGFT_CEIL(h)); + return 0; +} + +int +PGFT_GetTextSize(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, int *w, int *h) +{ + FontText *font_text; + + font_text = PGFT_LoadFontText(ft, font, render, text); + + if (!font_text) + return -1; + + return PGFT_GetSurfaceSize(ft, font, render, font_text, w, h); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_pixel.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,78 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef _PYGAME_FREETYPE_PIXEL_H_ +#define _PYGAME_FREETYPE_PIXEL_H_ + +#include "../surface.h" + +#define GET_RGB_VALS(pixel, fmt, r, g, b, a) \ + (r) = ((pixel) & (fmt)->Rmask) >> (fmt)->Rshift; \ + (r) = ((r) << (fmt)->Rloss) + ((r) >> (8 - ((fmt)->Rloss << 1))); \ + (g) = ((pixel) & (fmt)->Gmask) >> (fmt)->Gshift; \ + (g) = ((g) << (fmt)->Gloss) + ((g) >> (8 - ((fmt)->Gloss << 1))); \ + (b) = ((pixel) & (fmt)->Bmask) >> (fmt)->Bshift; \ + (b) = ((b) << (fmt)->Bloss) + ((b) >> (8 - ((fmt)->Bloss << 1))); \ + if ((fmt)->Amask) \ + { \ + (a) = ((pixel) & (fmt)->Amask) >> (fmt)->Ashift; \ + (a) = ((a) << (fmt)->Aloss) + ((a) >> (8 - ((fmt)->Aloss << 1))); \ + } \ + else \ + (a) = 255; + +#define GET_PALETTE_VALS(pixel, fmt, sr, sg, sb, sa) \ + (sr) = (fmt)->palette->colors[*((Uint8 *) (pixel))].r; \ + (sg) = (fmt)->palette->colors[*((Uint8 *) (pixel))].g; \ + (sb) = (fmt)->palette->colors[*((Uint8 *) (pixel))].b; \ + (sa) = 255; + +#define GET_PIXEL_VALS(pixel, fmt, r, g, b, a) \ + if ((fmt)->palette == NULL) \ + { \ + GET_RGB_VALS(pixel, fmt, r, g, b, a); \ + } \ + else \ + { \ + GET_PALETTE_VALS (pixel, fmt, r, g, b, a); \ + } + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define GET_PIXEL24(b) ((b)[0] + ((b)[1] << 8) + ((b)[2] << 16)) +#define SET_PIXEL24_RGB(buf,format,r,g,b) \ + *((buf) + ((format)->Rshift >> 3)) = (r); \ + *((buf) + ((format)->Gshift >> 3)) = (g); \ + *((buf) + ((format)->Bshift >> 3)) = (b); +#define SET_PIXEL24(buf,format,rgb) \ + *((buf) + ((format)->Rshift >> 3)) = (rgb)[0]; \ + *((buf) + ((format)->Gshift >> 3)) = (rgb)[1]; \ + *((buf) + ((format)->Bshift >> 3)) = (rgb)[2]; +#else +#define GET_PIXEL24(b) ((b)[2] + ((b)[1] << 8) + ((b)[0] << 16)) +#define SET_PIXEL24_RGB(buf,format,r,g,b) \ + *((buf) + 2 - ((format)->Rshift >> 3)) = (r); \ + *((buf) + 2 - ((format)->Gshift >> 3)) = (g); \ + *((buf) + 2 - ((format)->Bshift >> 3)) = (b); +#define SET_PIXEL24(buf,format,rgb) \ + *((buf) + 2 - ((format)->Rshift >> 3)) = (rgb)[0]; \ + *((buf) + 2 - ((format)->Gshift >> 3)) = (rgb)[1]; \ + *((buf) + 2 - ((format)->Bshift >> 3)) = (rgb)[2]; +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_render.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,632 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#define PYGAME_FREETYPE_INTERNAL + +#include "ft_wrap.h" +#include FT_MODULE_H +#include FT_OUTLINE_H + +typedef void (* FontRenderPtr)(int, int, FontSurface *, FT_Bitmap *, FontColor *); +typedef void (* FontFillPtr)(int, int, int, int, FontSurface *, FontColor *); + +#define SLANT_FACTOR 0.22 +FT_Matrix PGFT_SlantMatrix = +{ + (1 << 16), (FT_Fixed)(SLANT_FACTOR * (1 << 16)), + 0, (1 << 16) +}; + +FT_Fixed PGFT_GetBoldStrength(FT_Face face) +{ + const float bold_factor = 0.06f; + FT_Fixed bold_str; + + bold_str = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale); + bold_str = (FT_Fixed)((float)bold_str * bold_factor); + + return bold_str; +} + +int PGFT_CheckStyle(FT_UInt32 style) +{ + const FT_UInt32 max_style = + FT_STYLE_NORMAL | + FT_STYLE_BOLD | + FT_STYLE_ITALIC | + FT_STYLE_UNDERLINE; + + return (style > max_style); +} + +int +PGFT_BuildRenderMode(FreeTypeInstance *ft, + PyFreeTypeFont *font, FontRenderMode *mode, + int pt_size, int style, int rotation) +{ + int angle; + + if (pt_size == -1) + { + if (font->ptsize == -1) + { + _PGFT_SetError(ft, "No font point size specified" + " and no default font size in typeface", 0); + return -1; + } + + pt_size = font->ptsize; + } + + if (pt_size <= 0) + { + _PGFT_SetError(ft, "Invalid point size for font.", 0); + return -1; + } + + mode->pt_size = (FT_UInt16)pt_size; + + if (style == FT_STYLE_DEFAULT) + { + mode->style = (FT_Byte)font->style; + } + else + { + if (PGFT_CheckStyle((FT_UInt32)style) != 0) + { + _PGFT_SetError(ft, "Invalid style value", 0); + return -1; + } + + mode->style = (FT_Byte)style; + } + + mode->render_flags = FT_RFLAG_DEFAULTS; + + if (font->vertical) + mode->render_flags |= FT_RFLAG_VERTICAL; + + if (font->antialias) + mode->render_flags |= FT_RFLAG_ANTIALIAS; + + angle = rotation % 360; + while (angle < 0) angle += 360; + mode->rotation_angle = (FT_UInt16)angle; + + return 0; +} + + +/********************************************************* + * + * Rendering on SDL-specific surfaces + * + *********************************************************/ +#ifdef HAVE_PYGAME_SDL_VIDEO +int PGFT_Render_ExistingSurface(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, SDL_Surface *surface, + int x, int y, FontColor *fgcolor, FontColor *bgcolor, int *_width, int *_height) +{ + static const FontRenderPtr __SDLrenderFuncs[] = + { + NULL, + __render_glyph_RGB1, + __render_glyph_RGB2, + __render_glyph_RGB3, + __render_glyph_RGB4 + }; + + static const FontRenderPtr __MONOrenderFuncs[] = + { + NULL, + __render_glyph_MONO1, + __render_glyph_MONO2, + __render_glyph_MONO3, + __render_glyph_MONO4 + }; + + static const FontFillPtr __RGBfillFuncs[] = + { + NULL, + __fill_glyph_RGB1, + __fill_glyph_RGB2, + __fill_glyph_RGB3, + __fill_glyph_RGB4 + }; + + int locked = 0; + int width, height; + + FontSurface font_surf; + FontText *font_text; + + if (SDL_MUSTLOCK(surface)) + { + if (SDL_LockSurface(surface) == -1) + { + _PGFT_SetError(ft, SDL_GetError (), 0); + SDL_FreeSurface(surface); + return -1; + } + locked = 1; + } + + /* build font text */ + font_text = PGFT_LoadFontText(ft, font, render, text); + + if (!font_text) + return -1; + + if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0) + return -1; + + /* + * Setup target surface struct + */ + font_surf.buffer = surface->pixels; + font_surf.x_offset = x; + font_surf.y_offset = y; + + font_surf.width = surface->w; + font_surf.height = surface->h; + font_surf.pitch = surface->pitch / surface->format->BytesPerPixel; + + font_surf.format = surface->format; + + if (render->render_flags & FT_RFLAG_ANTIALIAS) + font_surf.render = __SDLrenderFuncs[surface->format->BytesPerPixel]; + else + font_surf.render = __MONOrenderFuncs[surface->format->BytesPerPixel]; + + font_surf.fill = __RGBfillFuncs[surface->format->BytesPerPixel]; + + /* + * if bg color exists, paint background + */ + if (bgcolor) + { + if (bgcolor->a == 0xFF) + { + SDL_Rect bg_fill; + FT_UInt32 fillcolor; + + fillcolor = SDL_MapRGBA(surface->format, + bgcolor->r, bgcolor->g, bgcolor->b, bgcolor->a); + + bg_fill.x = (FT_Int16)x; + bg_fill.y = (FT_Int16)y; + bg_fill.w = (FT_UInt16)width; + bg_fill.h = (FT_UInt16)height; + + SDL_FillRect(surface, &bg_fill, fillcolor); + } + else + { + font_surf.fill(x, y, width, height, &font_surf, bgcolor); + } + } + + /* + * Render! + */ + if (_PGFT_Render_INTERNAL(ft, font, font_text, render, fgcolor, &font_surf) != 0) + return -1; + + *_width = width; + *_height = height; + + if (locked) + SDL_UnlockSurface(surface); + + return 0; +} + +SDL_Surface *PGFT_Render_NewSurface(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, + FontColor *fgcolor, FontColor *bgcolor, int *_width, int *_height) +{ + int locked = 0; + FT_UInt32 fillcolor, rmask, gmask, bmask, amask; + SDL_Surface *surface = NULL; + + FontSurface font_surf; + FontText *font_text; + int width, height; + + /* build font text */ + font_text = PGFT_LoadFontText(ft, font, render, text); + + if (!font_text) + return NULL; + + if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0) + return NULL; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, + width, height, + 32, rmask, gmask, bmask, amask); + + if (!surface) + { + _PGFT_SetError(ft, SDL_GetError (), 0); + return NULL; + } + + if (SDL_MUSTLOCK(surface)) + { + if (SDL_LockSurface(surface) == -1) + { + _PGFT_SetError(ft, SDL_GetError (), 0); + SDL_FreeSurface(surface); + return NULL; + } + locked = 1; + } + + font_surf.buffer = surface->pixels; + font_surf.x_offset = font_surf.y_offset = 0; + + font_surf.width = surface->w; + font_surf.height = surface->h; + font_surf.pitch = surface->pitch / sizeof(FT_UInt32); + + font_surf.format = surface->format; + font_surf.render = __render_glyph_RGB4; + font_surf.fill = __fill_glyph_RGB4; + + /* + * Fill our texture with the required bg color + */ + if (bgcolor) + { + fillcolor = SDL_MapRGBA(surface->format, + bgcolor->r, bgcolor->g, bgcolor->b, bgcolor->a); + } + else + { + fillcolor = SDL_MapRGBA(surface->format, 0, 0, 0, 0); + } + + SDL_FillRect(surface, NULL, fillcolor); + + /* + * Render the text! + */ + if (_PGFT_Render_INTERNAL(ft, font, font_text, render, fgcolor, &font_surf) != 0) + { + SDL_FreeSurface(surface); + return NULL; + } + + *_width = width; + *_height = height; + + if (locked) + SDL_UnlockSurface(surface); + + return surface; +} +#endif + + + + +/********************************************************* + * + * Rendering on generic arrays + * + *********************************************************/ + +PyObject *PGFT_Render_PixelArray(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, int *_width, int *_height) +{ + FT_Byte *buffer = NULL; + PyObject *array = NULL; + FontSurface surf; + int width, height; + + FontText *font_text; + int array_size; + + /* build font text */ + font_text = PGFT_LoadFontText(ft, font, render, text); + + if (!font_text) + goto cleanup; + + if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0) + goto cleanup; + + array_size = width * height; + + buffer = malloc((size_t)array_size); + if (!buffer) + { + _PGFT_SetError(ft, "Could not allocate memory", 0); + goto cleanup; + } + + memset(buffer, 0xFF, (size_t)array_size); + + surf.buffer = buffer; + surf.width = surf.pitch = width; + surf.height = height; + + surf.format = NULL; + surf.render = __render_glyph_ByteArray; + + if (_PGFT_Render_INTERNAL(ft, font, font_text, render, 0x0, &surf) != 0) + goto cleanup; + + *_width = width; + *_height = height; + + array = Bytes_FromStringAndSize((char *)buffer, array_size); + +cleanup: + if (buffer) + free(buffer); + + return array; +} + + + + +/********************************************************* + * + * New rendering algorithm (rotation + veritical drawing) + * + *********************************************************/ +int _PGFT_Render_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, + FontText *text, const FontRenderMode *render, FontColor *fg_color, + FontSurface *surface) +{ + const FT_Fixed center = (1 << 15); // 0.5 + + int n; + FT_Vector pen; + FT_Matrix rotation_matrix; + FT_Face face; + FT_Error error; + FT_Vector *advances = NULL; + + FT_Fixed bold_str = 0; + + int x = (surface->x_offset << 6); + int y = (surface->y_offset << 6); + + assert(text->text_size.x); + assert(text->text_size.y); + + x += (text->text_size.x / 2); + y += (text->text_size.y / 2); + y -= (text->baseline_offset.y); + + /****************************************************** + * Load scaler, size & face + ******************************************************/ + face = _PGFT_GetFaceSized(ft, font, render->pt_size); + + if (!face) + { + _PGFT_SetError(ft, "Failed to resize face", 0); + return -1; + } + + /****************************************************** + * Load advance information + ******************************************************/ + error = PGFT_LoadTextAdvances(ft, font, render, text); + + if (error) + { + _PGFT_SetError(ft, "Failed to load advance glyph advances", error); + return error; + } + + advances = text->advances; + + /****************************************************** + * Build rotation matrix for rotated text + ******************************************************/ + if (render->rotation_angle != 0) + { + double radian; + FT_Fixed cosinus; + FT_Fixed sinus; + + radian = render->rotation_angle * 3.14159 / 180.0; + cosinus = (FT_Fixed)(cos(radian) * 65536.0); + sinus = (FT_Fixed)(sin(radian) * 65536.0); + + rotation_matrix.xx = cosinus; + rotation_matrix.yx = sinus; + rotation_matrix.xy = -sinus; + rotation_matrix.yy = cosinus; + } + + /****************************************************** + * Prepare pen for drawing + ******************************************************/ + + /* change to Cartesian coordinates */ + y = (surface->height << 6) - y; + + /* get the extent, which we store in the last slot */ + pen = advances[text->length - 1]; + + pen.x = FT_MulFix(pen.x, center); + pen.y = FT_MulFix(pen.y, center); + + if ((render->render_flags & FT_RFLAG_VERTICAL) == 0) + pen.y += PGFT_ROUND(text->glyph_size.y / 2); + + /* get pen position */ + if (render->rotation_angle && FT_IS_SCALABLE(face)) + { + FT_Vector_Transform(&pen, &rotation_matrix); + pen.x = x - pen.x; + pen.y = y - pen.y; + } + else + { + pen.x = PGFT_ROUND(x - pen.x); + pen.y = PGFT_ROUND(y - pen.y); + } + + /****************************************************** + * Prepare data for glyph transformations + ******************************************************/ + if (render->style & FT_STYLE_BOLD) + { + bold_str = PGFT_GetBoldStrength(face); + } + + /****************************************************** + * Draw text + ******************************************************/ + + for (n = 0; n < text->length; ++n) + { + FT_Glyph image; + FT_BBox bbox; + + FontGlyph *glyph = text->glyphs[n]; + + if (!glyph || !glyph->image) + continue; + + /* copy image */ + error = FT_Glyph_Copy(glyph->image, &image); + if (error) + continue; + + if (image->format == FT_GLYPH_FORMAT_OUTLINE) + { + FT_OutlineGlyph outline; + FT_Vector *trans_vector = NULL; + FT_Matrix *trans_matrix = NULL; + + outline = (FT_OutlineGlyph)image; + + if (render->style & FT_STYLE_BOLD) + FT_Outline_Embolden(&(outline->outline), bold_str); + + if (render->style & FT_STYLE_ITALIC) + FT_Outline_Transform(&(outline->outline), &PGFT_SlantMatrix); + + if (render->render_flags & FT_RFLAG_VERTICAL) + trans_vector = &glyph->vvector; + + if (render->rotation_angle) + trans_matrix = &rotation_matrix; + + if (FT_Glyph_Transform(image, NULL, trans_vector) != 0 || + FT_Glyph_Transform(image, trans_matrix, &pen) != 0) + { + FT_Done_Glyph(image); + continue; + } + } + else + { + FT_BitmapGlyph bitmap = (FT_BitmapGlyph)image; + + if (render->render_flags & FT_RFLAG_VERTICAL) + { + bitmap->left += (glyph->vvector.x + pen.x) >> 6; + bitmap->top += (glyph->vvector.x + pen.y) >> 6; + } + else + { + bitmap->left += pen.x >> 6; + bitmap->top += pen.y >> 6; + } + } + + if (render->rotation_angle) + FT_Vector_Transform(advances + n, &rotation_matrix); + + pen.x += advances[n].x; + pen.y += advances[n].y; + + FT_Glyph_Get_CBox(image, FT_GLYPH_BBOX_PIXELS, &bbox); + + if (bbox.xMax > 0 && bbox.yMax > 0 && + bbox.xMin < surface->width && + bbox.yMin < surface->height) + { + int left, top; + FT_Bitmap* source; + FT_BitmapGlyph bitmap; + + if (image->format == FT_GLYPH_FORMAT_OUTLINE) + { + FT_Render_Mode render_mode = + (render->render_flags & FT_RFLAG_ANTIALIAS) ? + FT_RENDER_MODE_NORMAL : + FT_RENDER_MODE_MONO; + + /* render the glyph to a bitmap, don't destroy original */ + FT_Glyph_To_Bitmap(&image, render_mode, NULL, 0); + } + + if (image->format != FT_GLYPH_FORMAT_BITMAP) + continue; + + bitmap = (FT_BitmapGlyph)image; + source = &bitmap->bitmap; + + left = bitmap->left; + top = bitmap->top; + + top = surface->height - top; + + surface->render(left, top, surface, source, fg_color); + } + + FT_Done_Glyph(image); + } /* END OF RENDERING LOOP */ + + if (text->underline_size > 0) + { + surface->fill( + surface->x_offset, + surface->y_offset + PGFT_TRUNC(text->underline_pos), + PGFT_TRUNC(text->text_size.x), PGFT_TRUNC(text->underline_size), + surface, fg_color); + } + + return error; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_render_cb.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,309 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#define PYGAME_FREETYPE_INTERNAL + +#include "ft_wrap.h" +#include FT_MODULE_H + +#if defined (PGFT_PYGAME1_COMPAT) +# include "ft_pixel.h" +#elif defined (HAVE_PYGAME_SDL_VIDEO) +# include "surface.h" +#endif + +void __render_glyph_ByteArray(int x, int y, FontSurface *surface, + FT_Bitmap *bitmap, FontColor *fg_color) +{ + FT_Byte *dst = ((FT_Byte *)surface->buffer) + x + (y * surface->pitch); + FT_Byte *dst_cpy; + + const FT_Byte *src = bitmap->buffer; + const FT_Byte *src_cpy; + + int j, i; + + for (j = 0; j < bitmap->rows; ++j) + { + src_cpy = src; + dst_cpy = dst; + + for (i = 0; i < bitmap->width; ++i) + *dst_cpy++ = (FT_Byte)(~(*src_cpy++)); + + dst += surface->pitch; + src += bitmap->pitch; + } +} + +#ifdef HAVE_PYGAME_SDL_VIDEO + +#define _CREATE_RGB_FILLER(_bpp, _getp, _setp, _blendp) \ + void __fill_glyph_RGB##_bpp(int x, int y, int w, int h, \ + FontSurface *surface, FontColor *color) \ + { \ + int i, j; \ + unsigned char *dst; \ + FT_UInt32 bgR, bgG, bgB, bgA; \ + \ + x = MAX(0, x); \ + y = MAX(0, y); \ + \ + if (x + w > surface->width) \ + w = surface->width - x; \ + \ + if (y + h > surface->height) \ + h = surface->height - y; \ + \ + dst = (unsigned char *)surface->buffer + (x * _bpp) +\ + (y * _bpp * surface->pitch); \ + \ + for (j = 0; j < h; ++j) \ + { \ + unsigned char *_dst = dst; \ + \ + for (i = 0; i < w; ++i, _dst += _bpp) \ + { \ + FT_UInt32 pixel = (FT_UInt32)_getp; \ + \ + if (_bpp == 1) \ + { \ + GET_PALETTE_VALS( \ + pixel, surface->format, \ + bgR, bgG, bgB, bgA); \ + } \ + else \ + { \ + GET_RGB_VALS( \ + pixel, surface->format, \ + bgR, bgG, bgB, bgA); \ + \ + } \ + \ + ALPHA_BLEND( \ + color->r, color->g, color->b, \ + color->a, bgR, bgG, bgB, bgA); \ + \ + _blendp; \ + } \ + \ + dst += surface->pitch * _bpp; \ + } \ + } + +#define __MONO_RENDER_INNER_LOOP(_bpp, _code) \ + for (j = ry; j < max_y; ++j) \ + { \ + unsigned char* _src = src; \ + unsigned char* _dst = dst; \ + FT_UInt32 val = (FT_UInt32)(*_src++ | 0x100) << shift;\ + \ + for (i = rx; i < max_x; ++i, _dst += _bpp) \ + { \ + if (val & 0x10000) \ + val = (FT_UInt32)(*_src++ | 0x100); \ + \ + if (val & 0x80) \ + { \ + _code; \ + } \ + \ + val <<= 1; \ + } \ + \ + src += bitmap->pitch; \ + dst += surface->pitch * _bpp; \ + } \ + +#define _CREATE_MONO_RENDER(_bpp, _getp, _setp, _blendp) \ + void __render_glyph_MONO##_bpp(int x, int y, FontSurface *surface, \ + FT_Bitmap *bitmap, FontColor *color) \ + { \ + const int off_x = (x < 0) ? -x : 0; \ + const int off_y = (y < 0) ? -y : 0; \ + \ + const int max_x = MIN(x + bitmap->width, surface->width); \ + const int max_y = MIN(y + bitmap->rows, surface->height); \ + \ + const int rx = MAX(0, x); \ + const int ry = MAX(0, y); \ + \ + int i, j, shift; \ + unsigned char* src; \ + unsigned char* dst; \ + FT_UInt32 full_color; \ + FT_UInt32 bgR, bgG, bgB, bgA; \ + \ + src = bitmap->buffer + (off_y * bitmap->pitch) + (off_x >> 3); \ + dst = (unsigned char *)surface->buffer + (rx * _bpp) + \ + (ry * _bpp * surface->pitch); \ + \ + full_color = SDL_MapRGBA(surface->format, (FT_Byte)color->r, \ + (FT_Byte)color->g, (FT_Byte)color->b, 255); \ + \ + shift = off_x & 7; \ + \ + if (color->a == 0xFF) \ + { \ + __MONO_RENDER_INNER_LOOP(_bpp, \ + { \ + _setp; \ + }); \ + } \ + else if (color->a > 0) \ + { \ + __MONO_RENDER_INNER_LOOP(_bpp, \ + { \ + FT_UInt32 pixel = (FT_UInt32)_getp; \ + \ + if (_bpp == 1) \ + { \ + GET_PALETTE_VALS( \ + pixel, surface->format, \ + bgR, bgG, bgB, bgA); \ + } \ + else \ + { \ + GET_RGB_VALS( \ + pixel, surface->format, \ + bgR, bgG, bgB, bgA); \ + \ + } \ + \ + ALPHA_BLEND( \ + color->r, color->g, color->b, color->a, \ + bgR, bgG, bgB, bgA); \ + \ + _blendp; \ + }); \ + } \ + } + +#define _CREATE_RGB_RENDER(_bpp, _getp, _setp, _blendp) \ + void __render_glyph_RGB##_bpp(int x, int y, FontSurface *surface, \ + FT_Bitmap *bitmap, FontColor *color) \ + { \ + const int off_x = (x < 0) ? -x : 0; \ + const int off_y = (y < 0) ? -y : 0; \ + \ + const int max_x = MIN(x + bitmap->width, surface->width); \ + const int max_y = MIN(y + bitmap->rows, surface->height); \ + \ + const int rx = MAX(0, x); \ + const int ry = MAX(0, y); \ + \ + FT_Byte *dst = ((FT_Byte*)surface->buffer) + (rx * _bpp) + \ + (ry * _bpp * surface->pitch); \ + FT_Byte *_dst; \ + \ + const FT_Byte *src = bitmap->buffer + off_x + \ + (off_y * bitmap->pitch); \ + const FT_Byte *_src; \ + \ + const FT_UInt32 full_color = \ + SDL_MapRGBA(surface->format, (FT_Byte)color->r, \ + (FT_Byte)color->g, (FT_Byte)color->b, 255); \ + \ + FT_UInt32 bgR, bgG, bgB, bgA; \ + int j, i; \ + \ + for (j = ry; j < max_y; ++j) \ + { \ + _src = src; \ + _dst = dst; \ + \ + for (i = rx; i < max_x; ++i, _dst += _bpp) \ + { \ + FT_UInt32 alpha = (*_src++); \ + alpha = (alpha * color->a) / 255; \ + \ + if (alpha == 0xFF) \ + { \ + _setp; \ + } \ + else if (alpha > 0) \ + { \ + FT_UInt32 pixel = (FT_UInt32)_getp; \ + \ + if (_bpp == 1) \ + { \ + GET_PALETTE_VALS( \ + pixel, surface->format, \ + bgR, bgG, bgB, bgA); \ + } \ + else \ + { \ + GET_RGB_VALS( \ + pixel, surface->format, \ + bgR, bgG, bgB, bgA); \ + \ + } \ + \ + ALPHA_BLEND( \ + color->r, color->g, color->b, alpha, \ + bgR, bgG, bgB, bgA); \ + \ + _blendp; \ + } \ + } \ + \ + dst += surface->pitch * _bpp; \ + src += bitmap->pitch; \ + } \ + } + + +#define _SET_PIXEL_24 \ + SET_PIXEL24_RGB(_dst, surface->format, color->r, color->g, color->b); + +#define _BLEND_PIXEL_24 \ + SET_PIXEL24_RGB(_dst, surface->format, bgR, bgG, bgB); + +#define _SET_PIXEL(T) \ + *(T*)_dst = (T)full_color; + +#define _BLEND_PIXEL(T) *((T*)_dst) = (T)( \ + ((bgR >> surface->format->Rloss) << surface->format->Rshift) | \ + ((bgG >> surface->format->Gloss) << surface->format->Gshift) | \ + ((bgB >> surface->format->Bloss) << surface->format->Bshift) | \ + ((255 >> surface->format->Aloss) << surface->format->Ashift & \ + surface->format->Amask) ) + +#define _BLEND_PIXEL_GENERIC(T) *(T*)_dst = (T)( \ + SDL_MapRGB(surface->format, \ + (FT_Byte)bgR, (FT_Byte)bgG, (FT_Byte)bgB) ) + +#define _GET_PIXEL(T) (*((T*)_dst)) + +_CREATE_RGB_RENDER(4, _GET_PIXEL(FT_UInt32), _SET_PIXEL(FT_UInt32), _BLEND_PIXEL(FT_UInt32)) +_CREATE_RGB_RENDER(3, GET_PIXEL24(_dst), _SET_PIXEL_24, _BLEND_PIXEL_24) +_CREATE_RGB_RENDER(2, _GET_PIXEL(FT_UInt16), _SET_PIXEL(FT_UInt16), _BLEND_PIXEL(FT_UInt16)) +_CREATE_RGB_RENDER(1, _GET_PIXEL(FT_Byte), _SET_PIXEL(FT_Byte), _BLEND_PIXEL_GENERIC(FT_Byte)) + +_CREATE_MONO_RENDER(4, _GET_PIXEL(FT_UInt32), _SET_PIXEL(FT_UInt32), _BLEND_PIXEL(FT_UInt32)) +_CREATE_MONO_RENDER(3, GET_PIXEL24(_dst), _SET_PIXEL_24, _BLEND_PIXEL_24) +_CREATE_MONO_RENDER(2, _GET_PIXEL(FT_UInt16), _SET_PIXEL(FT_UInt16), _BLEND_PIXEL(FT_UInt16)) +_CREATE_MONO_RENDER(1, _GET_PIXEL(FT_Byte), _SET_PIXEL(FT_Byte), _BLEND_PIXEL_GENERIC(FT_Byte)) + +_CREATE_RGB_FILLER(4, _GET_PIXEL(FT_UInt32), _SET_PIXEL(FT_UInt32), _BLEND_PIXEL(FT_UInt32)) +_CREATE_RGB_FILLER(3, GET_PIXEL24(_dst), _SET_PIXEL_24, _BLEND_PIXEL_24) +_CREATE_RGB_FILLER(2, _GET_PIXEL(FT_UInt16), _SET_PIXEL(FT_UInt16), _BLEND_PIXEL(FT_UInt16)) +_CREATE_RGB_FILLER(1, _GET_PIXEL(FT_Byte), _SET_PIXEL(FT_Byte), _BLEND_PIXEL_GENERIC(FT_Byte)) +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_text.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,353 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#define PYGAME_FREETYPE_INTERNAL + +#include "ft_wrap.h" +#include FT_MODULE_H + +FontText * +PGFT_LoadFontText(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text) +{ + const FT_UInt16 UNICODE_BOM_NATIVE = 0xFEFF; + const FT_UInt16 UNICODE_BOM_SWAPPED = 0xFFFE; + + int swapped = 0; + int string_length = 0; + + FT_UInt16 * buffer = NULL; + FT_UInt16 * orig_buffer; + FT_UInt16 * ch; + + FT_Fixed y_scale; + FT_Fixed bold_str = 0; + + FontText *ftext = NULL; + FontGlyph *glyph = NULL; + FontGlyph **glyph_array = NULL; + + FT_Face face; + + /* load our sized face */ + face = _PGFT_GetFaceSized(ft, font, render->pt_size); + + if (!face) + { + _PGFT_SetError(ft, "Failed to scale the given face", 0); + return NULL; + } + + /* get the text as an unicode string */ + orig_buffer = buffer = PGFT_BuildUnicodeString(text); + + if (!buffer) + { + _PGFT_SetError(ft, "Invalid text string specified", 0); + return NULL; + } + + /* get the length of the text */ + for (ch = buffer; *ch; ++ch) + { + if (*ch != UNICODE_BOM_NATIVE && + *ch != UNICODE_BOM_SWAPPED) + string_length++; + } + + /* cleanup the cache */ + PGFT_Cache_Cleanup(&PGFT_INTERNALS(font)->cache); + + /* create the text struct */ + ftext = &(PGFT_INTERNALS(font)->active_text); + + if (string_length > ftext->length) + { + free(ftext->glyphs); + ftext->glyphs = malloc((size_t)string_length * sizeof(FontGlyph *)); + + free(ftext->advances); + ftext->advances = malloc((size_t)string_length * sizeof(FT_Vector)); + } + + ftext->length = string_length; + ftext->glyph_size.x = ftext->glyph_size.y = 0; + ftext->text_size.x = ftext->text_size.y = 0; + ftext->baseline_offset.x = ftext->baseline_offset.y = 0; + ftext->underline_pos = ftext->underline_size = 0; + + y_scale = face->size->metrics.y_scale; + + /* fill it with the glyphs */ + glyph_array = ftext->glyphs; + + for (ch = buffer; *ch; ++ch) + { + FT_UInt16 c = *ch; + + /* + * Handle byte-order markers in the unicode string + */ + if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) + { + swapped = (c == UNICODE_BOM_SWAPPED); + if (buffer == ch) + ++buffer; + + continue; + } + + if (swapped) + c = (FT_UInt16)((c << 8) | (c >> 8)); + + /* + * Load the corresponding glyph from the cache + */ + glyph = PGFT_Cache_FindGlyph(ft, &PGFT_INTERNALS(font)->cache, + (FT_UInt)c, render); + + if (!glyph) + continue; + + /* + * Do size calculations for all the glyphs in the text + */ + if (glyph->baseline > ftext->baseline_offset.y) + ftext->baseline_offset.y = glyph->baseline; + + if (glyph->size.x > ftext->glyph_size.x) + ftext->glyph_size.x = glyph->size.x; + + if (glyph->size.y > ftext->glyph_size.y) + ftext->glyph_size.y = glyph->size.y; + + *glyph_array++ = glyph; + } + + if (render->style & FT_STYLE_UNDERLINE && + (render->render_flags & FT_RFLAG_VERTICAL) == 0 && + (render->rotation_angle == 0)) + { + FT_Fixed scale; + FT_Fixed underline_pos; + FT_Fixed underline_size; + + scale = face->size->metrics.y_scale; + + underline_pos = FT_MulFix(face->underline_position, scale); + underline_size = FT_MulFix(face->underline_thickness, scale) + bold_str; + + /* + * HACK HACK HACK + * + * According to the FT documentation, 'underline_pos' is the offset + * to draw the underline in 26.6 FP, based on the text's baseline + * (negative values mean below the baseline). + * + * However, after scaling the underline position, the values for all + * fonts are WAY off (e.g. fonts with 32pt size get underline offsets + * of -14 pixels). + * + * Dividing the offset by 4, somehow, returns very sane results for + * all kind of fonts; the underline seems to fit perfectly between + * the baseline and bottom of the glyphs. + * + * We'll leave it like this until we can figure out what's wrong + * with it... + * + */ + + ftext->underline_pos = + ftext->glyph_size.y - ftext->baseline_offset.y - (underline_pos / 4); + + ftext->underline_size = underline_size; + } + + free(orig_buffer); + return ftext; +} + +int +PGFT_LoadTextAdvances(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, FontText *text) +{ + /* Default kerning mode for all text */ + const int FT_KERNING_MODE = 1; + + FT_Face face; + FontGlyph *glyph; + FT_Pos track_kern = 0; + FT_UInt prev_index = 0; + FT_Vector* prev_advance = NULL; + FT_Vector extent = {0, 0}; + FT_Int i; + FT_Fixed bold_str = 0; + FT_Vector *advances = NULL; + + face = _PGFT_GetFaceSized(ft, font, render->pt_size); + + if (!face) + return -1; + + advances = text->advances; + + if (render->style & FT_STYLE_BOLD) + bold_str = PGFT_GetBoldStrength(face); + +#if 0 + if (!(render->render_flags & FT_RFLAG_VERTICAL) && render->kerning_degree) + { + FT_Fixed ptsize; + + ptsize = FT_MulFix(face->units_per_EM, face->size->metrics.x_scale); + + if (FT_Get_Track_Kerning(face, ptsize << 10, + -render->kerning_degree, &track_kern)) + track_kern = 0; + else + track_kern >>= 10; + } +#endif + + for (i = 0; i < text->length; i++) + { + glyph = text->glyphs[i]; + + if (!glyph || !glyph->image) + continue; + + if (render->render_flags & FT_RFLAG_VERTICAL) + advances[i] = glyph->vadvance; + else + { + advances[i] = glyph->image->advance; + + /* Convert to 26.6 */ + advances[i].x >>= 10; + advances[i].y >>= 10; + + /* Apply BOLD transformation */ + if (advances[i].x) + advances[i].x += bold_str; + + if (advances[i].y) + advances[i].y += bold_str; + + if (prev_advance) + { + prev_advance->x += track_kern; + + if (FT_KERNING_MODE > 0) + { + FT_Vector kern; + + FT_Get_Kerning(face, prev_index, glyph->glyph_index, + FT_KERNING_UNFITTED, &kern); + + prev_advance->x += kern.x; + prev_advance->y += kern.y; + + if (FT_KERNING_MODE > 1) /* KERNING_MODE_NORMAL */ + prev_advance->x += glyph->delta; + } + } + } + + if (prev_advance) + { + if (render->render_flags & FT_RFLAG_HINTED) + { + prev_advance->x = PGFT_ROUND(prev_advance->x); + prev_advance->y = PGFT_ROUND(prev_advance->y); + } + + extent.x += prev_advance->x; + extent.y += prev_advance->y; + } + + prev_index = glyph->glyph_index; + prev_advance = advances + i; + } + + if (prev_advance) + { + if (render->render_flags & FT_RFLAG_HINTED) + { + prev_advance->x = PGFT_ROUND(prev_advance->x); + prev_advance->y = PGFT_ROUND(prev_advance->y); + } + + extent.x += prev_advance->x; + extent.y += prev_advance->y; + } + + /* store the extent in the last slot */ + i = text->length - 1; + advances[i] = extent; + + return 0; +} + +FT_UInt16 * +PGFT_BuildUnicodeString(PyObject *obj) +{ + size_t len; + FT_UInt16 *utf16_buffer = NULL; + char *tmp_buffer; + + if (PyUnicode_Check(obj)) + { + /* + * For unicode objects, create a new Bytes object + * with the unicode contents as UTF16 and copy + * the raw contents of that object. + */ + PyObject *utf_bytes; + + utf_bytes = PyUnicode_AsUTF16String(obj); + Bytes_AsStringAndSize(utf_bytes, &tmp_buffer, (int *)&len); + utf16_buffer = malloc(len + 2); + + memcpy(utf16_buffer, tmp_buffer, len); + utf16_buffer[len / sizeof(FT_UInt16)] = 0; + + Py_DECREF(utf_bytes); + } + else if (Bytes_Check(obj)) + { + /* + * For bytes objects, assume the bytes are + * Latin1 text (who would manually enter bytes as + * UTF8 anyway?), so manually copy the raw contents + * of the object expanding each byte to 16 bits. + */ + size_t i; + + Bytes_AsStringAndSize(obj, &tmp_buffer, (int *)&len); + utf16_buffer = malloc((size_t)(len + 1) * sizeof(FT_UInt16)); + + for (i = 0; i < len; ++i) + utf16_buffer[i] = (FT_UInt16)tmp_buffer[i]; + + utf16_buffer[len] = 0; + } + + return utf16_buffer; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_wrap.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,392 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#define PYGAME_FREETYPE_INTERNAL + +#include "ft_wrap.h" +#include FT_MODULE_H + +static unsigned long _RWops_read(FT_Stream stream, unsigned long offset, + unsigned char *buffer, unsigned long count); +int _PGFT_Init_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font); + + +/********************************************************* + * + * Error management + * + *********************************************************/ +void +_PGFT_SetError(FreeTypeInstance *ft, const char *error_msg, FT_Error error_id) +{ +#undef __FTERRORS_H__ +#define FT_ERRORDEF( e, v, s ) { e, s }, +#define FT_ERROR_START_LIST { +#define FT_ERROR_END_LIST {0, 0}}; + static const struct + { + int err_code; + const char* err_msg; + } ft_errors[] = +#include FT_ERRORS_H + + int i; + const char *ft_msg; + + ft_msg = NULL; + for (i = 0; ft_errors[i].err_msg != NULL; ++i) + { + if (error_id == ft_errors[i].err_code) + { + ft_msg = ft_errors[i].err_msg; + break; + } + } + + if (error_id && ft_msg) + sprintf(ft->_error_msg, "%s: %s", error_msg, ft_msg); + else + strcpy(ft->_error_msg, error_msg); +} + +const char * +PGFT_GetError(FreeTypeInstance *ft) +{ + return ft->_error_msg; +} + + + + +/********************************************************* + * + * Misc getters + * + *********************************************************/ +int +PGFT_Face_IsFixedWidth(FreeTypeInstance *ft, PyFreeTypeFont *font) +{ + FT_Face face; + face = _PGFT_GetFace(ft, font); + + return face ? FT_IS_FIXED_WIDTH(face) : 0; +} + +const char * +PGFT_Face_GetName(FreeTypeInstance *ft, PyFreeTypeFont *font) +{ + FT_Face face; + face = _PGFT_GetFace(ft, font); + + return face ? face->family_name : ""; +} + +int +PGFT_Face_GetHeight(FreeTypeInstance *ft, PyFreeTypeFont *font) +{ + FT_Face face; + face = _PGFT_GetFace(ft, font); + + return face ? face->height : 0; +} + + + + +/********************************************************* + * + * Face access + * + *********************************************************/ +FT_Face +_PGFT_GetFaceSized(FreeTypeInstance *ft, + PyFreeTypeFont *font, + int face_size) +{ + FT_Error error; + FTC_ScalerRec scale; + FT_Size _fts; + + _PGFT_BuildScaler(font, &scale, face_size); + + error = FTC_Manager_LookupSize(ft->cache_manager, + &scale, &_fts); + + if (error) + { + _PGFT_SetError(ft, "Failed to resize face", error); + return NULL; + } + + return _fts->face; +} + +FT_Face +_PGFT_GetFace(FreeTypeInstance *ft, + PyFreeTypeFont *font) +{ + FT_Error error; + FT_Face face; + + error = FTC_Manager_LookupFace(ft->cache_manager, + (FTC_FaceID)(&font->id), + &face); + + if (error) + { + _PGFT_SetError(ft, "Failed to load face", error); + return NULL; + } + + return face; +} + + + + +/********************************************************* + * + * Scaling + * + *********************************************************/ +void +_PGFT_BuildScaler(PyFreeTypeFont *font, FTC_Scaler scale, int size) +{ + scale->face_id = (FTC_FaceID)(&font->id); + scale->width = scale->height = (FT_UInt32)(size * 64); + scale->pixel = 0; + scale->x_res = scale->y_res = 0; +} + + + + + + + +/********************************************************* + * + * Font loading + * + * TODO: + * - Loading from rwops, existing files, etc + * + *********************************************************/ +static FT_Error +_PGFT_face_request(FTC_FaceID face_id, + FT_Library library, + FT_Pointer request_data, + FT_Face *aface) +{ + FontId *id = (FontId *)face_id; + FT_Error error; + + Py_BEGIN_ALLOW_THREADS; + error = FT_Open_Face(library, &id->open_args, id->face_index, aface); + Py_END_ALLOW_THREADS; + + return error; +} + + + +int _PGFT_Init_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font) +{ + font->_internals = malloc(sizeof(FontInternals)); + + if (font->_internals == NULL) + return -1; + + memset(font->_internals, 0x0, sizeof(FontInternals)); + PGFT_Cache_Init(ft, &PGFT_INTERNALS(font)->cache, font); + + return (_PGFT_GetFace(ft, font)) ? 0 : -1; +} + +int +PGFT_TryLoadFont_Filename(FreeTypeInstance *ft, + PyFreeTypeFont *font, + const char *filename, + int face_index) +{ + char *filename_alloc; + size_t file_len; + + file_len = strlen(filename); + filename_alloc = malloc(file_len + 1); + if (!filename_alloc) + { + _PGFT_SetError(ft, "Could not allocate memory", 0); + return -1; + } + + strcpy(filename_alloc, filename); + filename_alloc[file_len] = 0; + + font->id.face_index = face_index; + font->id.open_args.flags = FT_OPEN_PATHNAME; + font->id.open_args.pathname = filename_alloc; + + return _PGFT_Init_INTERNAL(ft, font); +} + +#ifdef HAVE_PYGAME_SDL_RWOPS +static unsigned long +_RWops_read(FT_Stream stream, unsigned long offset, + unsigned char *buffer, unsigned long count) +{ + SDL_RWops *src; + + src = (SDL_RWops *)stream->descriptor.pointer; + SDL_RWseek(src, (int)offset, SEEK_SET); + + if (count == 0) + return 0; + + return SDL_RWread(src, buffer, 1, (int)count); +} + +int PGFT_TryLoadFont_RWops(FreeTypeInstance *ft, + PyFreeTypeFont *font, SDL_RWops *src, int face_index) +{ + FT_Stream stream; + int position; + + position = SDL_RWtell(src); + + if (position < 0) + { + _PGFT_SetError(ft, "Failed to seek in font stream", 0); + return -1; + } + + stream = malloc(sizeof(*stream)); + + if (stream == NULL) + { + _PGFT_SetError(ft, "Failed to alloc font stream", 0); + return -1; + } + + memset(stream, 0, sizeof(*stream)); + + stream->read = _RWops_read; + stream->descriptor.pointer = src; + stream->pos = (unsigned long)position; + SDL_RWseek(src, 0, SEEK_END); + stream->size = (unsigned long)(SDL_RWtell(src) - position); + SDL_RWseek(src, position, SEEK_SET); + + font->id.face_index = face_index; + font->id.open_args.flags = FT_OPEN_STREAM; + font->id.open_args.stream = stream; + + return _PGFT_Init_INTERNAL(ft, font); +} +#endif + +void +PGFT_UnloadFont(FreeTypeInstance *ft, PyFreeTypeFont *font) +{ + if (ft != NULL) + { + FTC_Manager_RemoveFaceID(ft->cache_manager, (FTC_FaceID)(&font->id)); + if (PGFT_INTERNALS(font)) + PGFT_Cache_Destroy(&PGFT_INTERNALS(font)->cache); + } + + if (PGFT_INTERNALS(font)) + { + free(PGFT_INTERNALS(font)->active_text.glyphs); + free(PGFT_INTERNALS(font)); + } + + if (font->id.open_args.flags == FT_OPEN_STREAM) + { + free(font->id.open_args.pathname); + } + else if (font->id.open_args.flags == FT_OPEN_PATHNAME) + { + free(font->id.open_args.stream); + } +} + + + + +/********************************************************* + * + * Library (de)initialization + * + *********************************************************/ +int +PGFT_Init(FreeTypeInstance **_instance, int cache_size) +{ + FreeTypeInstance *inst = NULL; + + inst = malloc(sizeof(FreeTypeInstance)); + + if (!inst) + goto error_cleanup; + + memset(inst, 0, sizeof(FreeTypeInstance)); + inst->_error_msg = calloc(1024, sizeof(char)); + inst->cache_size = cache_size; + + if (FT_Init_FreeType(&inst->library) != 0) + goto error_cleanup; + + if (FTC_Manager_New(inst->library, 0, 0, 0, + &_PGFT_face_request, NULL, + &inst->cache_manager) != 0) + goto error_cleanup; + + if (FTC_CMapCache_New(inst->cache_manager, + &inst->cache_charmap) != 0) + goto error_cleanup; + + *_instance = inst; + return 0; + +error_cleanup: + PGFT_Quit(inst); + *_instance = NULL; + + return -1; +} + +void +PGFT_Quit(FreeTypeInstance *ft) +{ + if (ft == NULL) + return; + + if (ft->cache_manager) + FTC_Manager_Done(ft->cache_manager); + + if (ft->library) + FT_Done_FreeType(ft->library); + + if (ft->_error_msg) + free (ft->_error_msg); + + free (ft); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/freetype/ft_wrap.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,291 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef _PYGAME_FREETYPE_WRAP_H_ +#define _PYGAME_FREETYPE_WRAP_H_ + +#define PYGAME_FREETYPE_INTERNAL +#include "../freetype.h" + +/********************************************************** + * Internal module defines + **********************************************************/ + +/* Fixed point (26.6) math macros */ +#define PGFT_FLOOR(x) ( (x) & -64 ) +#define PGFT_CEIL(x) ( ( (x) + 63 ) & -64 ) +#define PGFT_ROUND(x) ( ( (x) + 32 ) & -64 ) +#define PGFT_TRUNC(x) ( (x) >> 6 ) + +/* Internal configuration variables */ +#define PGFT_DEFAULT_CACHE_SIZE 64 +#define PGFT_MIN_CACHE_SIZE 32 +#undef PGFT_DEBUG_CACHE + + +/********************************************************** + * Internal data structures + **********************************************************/ +typedef struct +{ + FT_Library library; + FTC_Manager cache_manager; + FTC_CMapCache cache_charmap; + + int cache_size; + char *_error_msg; +} FreeTypeInstance; + +typedef struct __fontcolor +{ + FT_Byte r; + FT_Byte g; + FT_Byte b; + FT_Byte a; +} FontColor; + +typedef struct __fontsurface +{ + void *buffer; + + int x_offset; + int y_offset; + + int width; + int height; + int pitch; + + SDL_PixelFormat *format; + + void (* render) (int, int, struct __fontsurface *, FT_Bitmap *, FontColor *); + void (* fill) (int, int, int, int, struct __fontsurface *, FontColor *); + +} FontSurface; + +typedef struct __rendermode +{ + FT_UInt16 pt_size; + FT_UInt16 rotation_angle; + FT_UInt16 render_flags; + FT_UInt16 style; +} FontRenderMode; + +typedef struct __fontglyph +{ + FT_UInt glyph_index; + FT_Glyph image; + + FT_Pos delta; + FT_Vector vvector; + FT_Vector vadvance; + + FT_Fixed baseline; + FT_Vector size; +} FontGlyph; + +typedef struct __fonttext +{ + FontGlyph **glyphs; + FT_Vector *advances; + int length; + + FT_Vector glyph_size; /* 26.6 */ + FT_Vector text_size; /* 26.6 */ + FT_Vector baseline_offset; /* 26.6 */ + + FT_Fixed underline_size; + FT_Fixed underline_pos; +} FontText; + +typedef struct __cachenode +{ + FontGlyph glyph; + struct __cachenode *next; + FT_UInt32 hash; + +} FontCacheNode; + +typedef struct __fontcache +{ + FontCacheNode **nodes; + FontCacheNode *free_nodes; + + FT_Byte *depths; + +#ifdef PGFT_DEBUG_CACHE + FT_UInt32 count; + FT_UInt32 _debug_delete_count; + FT_UInt32 _debug_access; + FT_UInt32 _debug_hit; + FT_UInt32 _debug_miss; +#endif + + FT_UInt32 size_mask; + PyFreeTypeFont *font; +} FontCache; + +#define PGFT_INTERNALS(f) ((FontInternals *)(f->_internals)) +typedef struct FontInternals_ +{ + FontCache cache; + FontText active_text; +} FontInternals; + + + +/********************************************************** + * Module state + **********************************************************/ +typedef struct { + FreeTypeInstance *freetype; +} _FreeTypeState; + +#ifdef IS_PYTHON_3 + extern struct PyModuleDef _freetypemodule; +# define FREETYPE_MOD_STATE(mod) ((_FreeTypeState*)PyModule_GetState(mod)) +# define FREETYPE_STATE FREETYPE_MOD_STATE(PyState_FindModule(&_freetypemodule)) +#else + extern _FreeTypeState _modstate; +# define FREETYPE_MOD_STATE(mod) (&_modstate) +# define FREETYPE_STATE FREETYPE_MOD_STATE(NULL) +#endif + +#define ASSERT_GRAB_FREETYPE(ft_ptr, rvalue) \ + ft_ptr = FREETYPE_STATE->freetype; \ + if (ft_ptr == NULL) \ + { \ + PyErr_SetString(PyExc_RuntimeError, \ + "The FreeType 2 library hasn't been initialized"); \ + return (rvalue); \ + } + + + + +/********************************************************** + * Internal API + **********************************************************/ + +/********************************************************* General functions ****/ +const char *PGFT_GetError(FreeTypeInstance *); +void PGFT_Quit(FreeTypeInstance *); +int PGFT_Init(FreeTypeInstance **, int cache_size); + +int PGFT_Face_GetHeight(FreeTypeInstance *ft, PyFreeTypeFont *); +int PGFT_Face_IsFixedWidth(FreeTypeInstance *ft, PyFreeTypeFont *); +const char *PGFT_Face_GetName(FreeTypeInstance *ft, PyFreeTypeFont *); + +int PGFT_TryLoadFont_Filename(FreeTypeInstance *, + PyFreeTypeFont *, const char *, int); + +#ifdef HAVE_PYGAME_SDL_RWOPS +int PGFT_TryLoadFont_RWops(FreeTypeInstance *, + PyFreeTypeFont *, SDL_RWops *, int); +#endif + +void PGFT_UnloadFont(FreeTypeInstance *, PyFreeTypeFont *); + + + +/********************************************************* Metrics management ****/ +int PGFT_GetTextSize(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, int *w, int *h); + +int PGFT_GetMetrics(FreeTypeInstance *ft, PyFreeTypeFont *font, + int character, const FontRenderMode *render, int bbmode, + void *minx, void *maxx, void *miny, void *maxy, void *advance); + +int PGFT_GetSurfaceSize(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, FontText *text, + int *width, int *height); + + + +/******************************************************************* Rendering ****/ +PyObject * PGFT_Render_PixelArray(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, int *_width, int *_height); + +SDL_Surface *PGFT_Render_NewSurface(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, + FontColor *fgcolor, FontColor *bgcolor, int *_width, int *_height); + +int PGFT_Render_ExistingSurface(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text, + SDL_Surface *_surface, int x, int y, FontColor *fgcolor, FontColor *bgcolor, + int *_width, int *_height); + +int PGFT_BuildRenderMode(FreeTypeInstance *ft, + PyFreeTypeFont *font, FontRenderMode *mode, int pt_size, + int style, int rotation); + +FT_Fixed PGFT_GetBoldStrength(FT_Face face); + +int _PGFT_Render_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, + FontText *text, const FontRenderMode *render, FontColor *fg_color, + FontSurface *surface); + +int PGFT_CheckStyle(FT_UInt32 style); + + +/******************************************************************* Render callbacks ****/ + +void __fill_glyph_RGB1(int x, int y, int w, int h, FontSurface *surface, FontColor *color); +void __fill_glyph_RGB2(int x, int y, int w, int h, FontSurface *surface, FontColor *color); +void __fill_glyph_RGB3(int x, int y, int w, int h, FontSurface *surface, FontColor *color); +void __fill_glyph_RGB4(int x, int y, int w, int h, FontSurface *surface, FontColor *color); + +void __render_glyph_MONO1(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); +void __render_glyph_MONO2(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); +void __render_glyph_MONO3(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); +void __render_glyph_MONO4(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); + +void __render_glyph_RGB1(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); +void __render_glyph_RGB2(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); +void __render_glyph_RGB3(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); +void __render_glyph_RGB4(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); + +void __render_glyph_ByteArray(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, FontColor *color); + +/******************************************************** Font text management ****/ +FontText * PGFT_LoadFontText(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, PyObject *text); + +int PGFT_LoadTextAdvances(FreeTypeInstance *ft, PyFreeTypeFont *font, + const FontRenderMode *render, FontText *text); + +FT_UInt16 * PGFT_BuildUnicodeString(PyObject *); + + +/******************************************************** Glyph cache management ****/ +void PGFT_Cache_Init(FreeTypeInstance *ft, FontCache *cache, PyFreeTypeFont *parent); +void PGFT_Cache_Destroy(FontCache *cache); +void PGFT_Cache_Cleanup(FontCache *cache); +FontGlyph * PGFT_Cache_FindGlyph(FreeTypeInstance *ft, FontCache *cache, FT_UInt character, + const FontRenderMode *render); + + +/******************************************************************* Internals ****/ +void _PGFT_SetError(FreeTypeInstance *, const char *, FT_Error); +FT_Face _PGFT_GetFace(FreeTypeInstance *, PyFreeTypeFont *); +FT_Face _PGFT_GetFaceSized(FreeTypeInstance *, PyFreeTypeFont *, int); +void _PGFT_BuildScaler(PyFreeTypeFont *, FTC_Scaler, int); + + +#endif
--- a/src/gfxdraw.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/gfxdraw.c Mon Nov 16 18:31:40 2009 +0000 @@ -33,7 +33,7 @@ #define PYGAME_SDLGFXPRIM_INTERNAL #include "pygame.h" -#include "pygamedocs.h" +#include "doc/gfxdraw_doc.h" #include "surface.h" #include "pgcompat.h" #include "SDL_gfx/SDL_gfxPrimitives.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gmovie.c Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,948 @@ +#include "gmovie.h" + + +void _movie_init_internal(PyMovie *self, const char *filename, SDL_Surface *surf) +{ + Py_INCREF(self); + //already malloced memory for PyMovie. + self->_backend="FFMPEG_WRAPPER"; + self->commands = (CommandQueue *)PyMem_Malloc(sizeof(CommandQueue)); + self->commands->q_mutex = SDL_CreateMutex(); + self->commands->size=0; + self->commands->reg_ix=0; + registerCommands(self); + self->commands->size=0; + if(!surf) + { + //set overlay to true + self->overlay = 1; + } + else + { + self->overlay = 0; + self->canon_surf=surf; + } + /* filename checking... */ + PyObject *path = PyImport_ImportModule("os.path"); + Py_INCREF(path); + PyObject *dict = PyModule_GetDict(path); + PyObject *key = Py_BuildValue("s", "exists"); + Py_INCREF(key); + PyObject *existsFunc = PyDict_GetItem(dict, key); + PyObject *boolean = PyObject_CallFunction(existsFunc, "s", filename); + Py_INCREF(boolean); + if(boolean==Py_False) + { + Py_DECREF(boolean); + Py_DECREF(key); + Py_DECREF(path); + RAISE(PyExc_ValueError, "This filename does not exist."); + return; + //Py_RETURN_NONE; + } + Py_DECREF(boolean); + Py_DECREF(key); + Py_DECREF(path); + + self->start_time = AV_NOPTS_VALUE; + stream_open(self, filename, NULL, 0); + //PySys_WriteStdout("Time-base-a: %f\n", av_q2d(self->audio_st->codec->time_base)); + if(!self) + { + PyErr_SetString(PyExc_IOError, "stream_open failed"); + Py_DECREF(self); + return; + } + if(self->canon_surf) + { + /*Here we check if the surface's dimensions match the aspect ratio of the video. If not, + * we throw an error. + */ + int width = self->canon_surf->w; + int height = self->canon_surf->h; + double aspect_ratio = (double)self->video_st->codec->width/(double)self->video_st->codec->height; + double surf_ratio = (double)width/(double)height; + if (surf_ratio!=aspect_ratio) + { + PyErr_SetString(PyExc_ValueError, "surface does not have the same aspect ratio as the video. This would cause surface corruption."); + Py_DECREF(self); + return; + } + } + //PySys_WriteStdout("Movie->filename: %s\n", self->filename); + Py_DECREF(self); + return; +} + + +int _movie_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + Py_INCREF(self); + const char *c; + PyObject *surf; + if (!PyArg_ParseTuple (args, "s|O", &c, &surf)) + { + PyErr_SetString(PyExc_TypeError, "No valid arguments"); + return -1; + } + + if(surf && PySurface_Check(surf)) + { + SDL_Surface *target = PySurface_AsSurface(surf); + _movie_init_internal((PyMovie *)self, c, target); + } + else + { + _movie_init_internal((PyMovie *)self, c, NULL); + } + PyObject *er; + er = PyErr_Occurred(); + Py_XINCREF(er); + if(er) + { + PyErr_Print(); + } + Py_XDECREF(er); + if(!self) + { + PyErr_SetString(PyExc_IOError, "No movie object created."); + PyErr_Print(); + Py_DECREF(self); + return -1; + } + Py_DECREF(self); + //PySys_WriteStdout("Returning from _movie_init\n"); + return 0; +} + +void _movie_dealloc(PyMovie *movie) +{ + //PySys_WriteStdout("Deleting\n"); + if(movie->_tstate) + { + PyThreadState_Clear(movie->_tstate); + //PyThreadState_Delete(movie->_tstate); + } + #ifdef PROFILE + TimeSampleNode *cur = movie->istats->first; + TimeSampleNode *prev; + while(cur!=NULL) + { + prev=cur; + cur=cur->next; + PyMem_Free(prev); + } + PyMem_Free(movie->istats); + #endif + SDL_DestroyMutex(movie->commands->q_mutex); + PyMem_Free(movie->commands); + movie->commands=NULL; + stream_close(movie, 0); + movie->ob_type->tp_free((PyObject *) movie); +} + +char *format_timestamp(double pts, char *buf) +{ + int h, m; + double s; + if(pts/60 > 60) + { + h = (int)pts/3600; + pts = pts-h*3600; + } + else + { + h=0; + } + m=(int)pts/60; + if(m>0) + { + s = pts-m*60; + } + else + { + s = pts; + m=0; + } + //char buf[50]; + if(h>0 && m>0) + { + PyOS_snprintf(buf, sizeof(buf), "%i:%i:%fs", h, m, s); + } + else if (m>0) + { + PyOS_snprintf(buf, sizeof(buf), "%i:%fs", m, s); + } + else if(s>0) + { + PyOS_snprintf(buf, sizeof(buf), "%fs", s); + } + else + { + PyOS_snprintf(buf, sizeof(buf), "0.0s"); + } + return buf; +} + +PyObject* _movie_repr (PyMovie *movie) +{ + /*Eventually add a time-code call */ + Py_INCREF(movie); + char buf[150]; + char buf2[50]; + PyOS_snprintf(buf, sizeof(buf), "(Movie: %s, %s)", movie->filename, format_timestamp(movie->pts, buf2)); + PyObject *buffer = PyString_FromString(buf); + Py_DECREF(movie); + return buffer; +} +PyObject* _movie_play(PyMovie *movie, PyObject* args) +{ + PyEval_InitThreads(); + if(movie->playing) + { + if(movie->paused) + { + //if we've called this after we paused n times where n is odd, then we unpause the movie + _movie_pause(movie); + } + //indicating we've called play again before its finished + } + else if(movie->_tstate==NULL) + { + PyInterpreterState *interp; + PyThreadState *thread; + thread=PyThreadState_Get(); + interp = thread->interp; + movie->_tstate = PyThreadState_New(interp); + } + Py_INCREF(movie); + //PySys_WriteStdout("Inside .play\n"); + int loops; + if(!PyArg_ParseTuple(args, "i", &loops)) + { + loops = 0; + } + //movie has been stopped, need to close down streams and that. + if(movie->stop) + { + //first we release the GIL, then we release all the resources associated with the streams, if they exist. + PyEval_ReleaseLock(); + _movie_stop(movie); + } + + SDL_LockMutex(movie->dest_mutex); + movie->loops =loops; + movie->paused = 0; + movie->playing = 1; + SDL_UnlockMutex(movie->dest_mutex); + Py_BEGIN_ALLOW_THREADS + movie->parse_tid = SDL_CreateThread(decoder_wrapper, movie); + Py_END_ALLOW_THREADS + Py_DECREF(movie); + Py_RETURN_NONE; +} + +PyObject* _movie_stop(PyMovie *movie) +{ + //stream_pause(movie); + ALLOC_COMMAND(stopCommand, stop); + addCommand(movie->commands, (Command *)stop); + Py_RETURN_NONE; +} + +PyObject* _movie_pause(PyMovie *movie) +{ + + stream_pause(movie); + Py_RETURN_NONE; +} + +PyObject* _movie_rewind(PyMovie *movie, PyObject* args) +{ + /* For now, just alias rewind to stop */ + return _movie_stop(movie); +} + +PyObject* _movie_resize (PyMovie *movie, PyObject* args) +{ + int w, h; + if(PyArg_ParseTuple(args, "ii", &w, &h)<0) + { + return NULL; + } + if(w<0 || h<0) + { + return RAISE (PyExc_SDLError, "Cannot set negative sized display mode"); + } + if(movie->canon_surf) + { + Py_RETURN_NONE; + } + ALLOC_COMMAND(resizeCommand, resize); + + resize->h = h; + resize->w = w; + addCommand(movie->commands, (Command *)resize); + Py_RETURN_NONE; + +} + +PyObject *_movie_shift(PyMovie *movie, PyObject*args) +{ + int x=0; + int y=0; + if(PyArg_ParseTuple(args, "ii", &x, &y)<0) + { + return NULL; + } + ALLOC_COMMAND(shiftCommand, shift); + shift->xleft=x; + shift->ytop=y; + addCommand(movie->commands, (Command *)shift); + Py_RETURN_NONE; +} + +PyObject* _movie_easy_seek (PyMovie *movie, PyObject* args) +{ + int64_t pos=0; + int hour=0; + int minute=0; + int second=0; + int reverse=0; + //int relative=0; + //char *keywords[4] = {"second", "minute", "hour", "reverse"}; + if(!PyArg_ParseTuple(args, "iiii", &second, &minute, &hour, &reverse)) + { + Py_RETURN_NONE; + } + if(second) + { + pos+=(int64_t)second; + } + if(minute) + { + pos+=60*(int64_t)minute; + } + if(hour) + { + pos+=3600*(int64_t)hour; + } + if(reverse) + { + reverse=-1; + } + else + { + reverse=1; + } + pos *= AV_TIME_BASE; + stream_seek(movie, pos, reverse); + Py_RETURN_NONE; +} + +PyObject* _movie_get_paused (PyMovie *movie, void *closure) +{ + return PyBool_FromLong((long)movie->paused); +} +PyObject* _movie_get_playing (PyMovie *movie, void *closure) +{ + PyObject *pyo; + pyo= PyBool_FromLong((long)movie->playing); + return pyo; +} + +PyObject* _movie_get_finished(PyMovie *movie, void *closure) +{ + return PyBool_FromLong((long)movie->finished); +} + +PyObject* _movie_get_width (PyMovie *movie, void *closure) +{ + PyObject *pyo; + if(movie->video_st) + { + if(movie->resize_w) + { + pyo = PyInt_FromLong((long)movie->width); + } + else + { + if(movie->video_st->codec) + { + pyo= PyInt_FromLong((long)movie->video_st->codec->width); + } + else + { + pyo = PyInt_FromLong((long)0); + } + } + } + else + { + pyo = PyInt_FromLong((long)0); + } + return pyo; +} + +int _movie_set_width (PyMovie *movie, PyObject *width, void *closure) +{ + int w; + if(PyInt_Check(width) && !movie->canon_surf) + { + w = (int)PyInt_AsLong(width); + ALLOC_COMMAND(resizeCommand, resize); + + resize->h = 0; + resize->w = w; + addCommand(movie->commands, (Command *)resize); + return 0; + } + else + { + return -1; + } + +} + +PyObject* _movie_get_height (PyMovie *movie, void *closure) +{ + PyObject *pyo; + if(movie->video_st) + { + if(movie->resize_h) + { + pyo=PyInt_FromLong((long)movie->height); + } + else + { + pyo= PyInt_FromLong((long)movie->video_st->codec->height); + } + } + else + { + pyo = PyInt_FromLong((long)0); + } + return pyo; +} +int _movie_set_height (PyMovie *movie, PyObject *height, void *closure) +{ + int h; + if(PyInt_Check(height) && !movie->canon_surf) + { + h = (int)PyInt_AsLong(height); + + ALLOC_COMMAND(resizeCommand, resize); + resize->h = h; + resize->w = 0; + addCommand(movie->commands, (Command *)resize); + return 0; + } + else + { + return -1; + } + +} + +PyObject* _movie_get_ytop (PyMovie *movie, void *closure) +{ + PyObject *pyo; + if(movie->video_st) + { + pyo= PyInt_FromLong((long)movie->ytop); + } + else + { + pyo = PyInt_FromLong((long)0); + } + return pyo; +} +int _movie_set_ytop (PyMovie *movie, PyObject *ytop, void *closure) +{ + int y; + if(PyInt_Check(ytop)) + { + y = (int)PyInt_AsLong(ytop); + ALLOC_COMMAND(shiftCommand, shift); + shift->ytop = y; + shift->xleft = 0; + addCommand(movie->commands, (Command *)shift); + return 0; + } + else + { + return -1; + } +} + +PyObject* _movie_get_xleft (PyMovie *movie, void *closure) +{ + PyObject *pyo; + if(movie->video_st) + { + pyo= PyInt_FromLong((long)movie->xleft); + } + else + { + pyo = PyInt_FromLong((long)0); + } + return pyo; +} +int _movie_set_xleft (PyMovie *movie, PyObject *xleft, void *closure) +{ + int x; + if(PyInt_Check(xleft)) + { + x = (int)PyInt_AsLong(xleft); + ALLOC_COMMAND(shiftCommand, shift); + shift->ytop = 0; + shift->xleft = x; + addCommand(movie->commands, (Command *)shift); + return 0; + } + else + { + return -1; + } + +} + +PyObject *_movie_get_surface(PyMovie *movie, void *closure) +{ + if(movie->canon_surf) + { + return (PyObject *)PySurface_New(movie->canon_surf); + } + Py_RETURN_NONE; +} + +int _movie_set_surface(PyObject *mov, PyObject *surface, void *closure) +{ + PyMovie *movie = (PyMovie *)mov; + surfaceCommand *surf; + if(PySurface_Check(surface)) + { + SDL_Surface *surfa = PySurface_AsSurface(surface); + int width = surfa->w; + int height = surfa->h; + double aspect_ratio = (double)movie->video_st->codec->width/(double)movie->video_st->codec->height; + double surf_ratio = (double)width/(double)height; + if (surf_ratio!=aspect_ratio) + { + RAISE(PyExc_ValueError, "surface does not have the same aspect ratio as the video. This would cause surface corruption."); + return -1; + } + /*movie->canon_surf=PySurface_AsSurface(surface); + movie->overlay=0;*/ + surf = (surfaceCommand *)PyMem_Malloc(sizeof(surfaceCommand)); + surf->type = movie->surfaceCommandType; + surf->surface = surfa; + addCommand(movie->commands, (Command *)surf); + return 0; + } + else if(surface == Py_None) + { + surf = (surfaceCommand *)PyMem_Malloc(sizeof(surfaceCommand)); + surf->type = movie->surfaceCommandType; + surf->surface = NULL; + addCommand(movie->commands, (Command *)surf); + return 0; + } + return -1; +} + +static PyMethodDef _movie_methods[] = { + { "play", (PyCFunction) _movie_play, METH_VARARGS, DOC_GMOVIEMOVIEPLAY}, + { "stop", (PyCFunction) _movie_stop, METH_NOARGS, DOC_GMOVIEMOVIESTOP}, + { "pause", (PyCFunction) _movie_pause, METH_NOARGS, DOC_GMOVIEMOVIEPAUSE}, + { "rewind", (PyCFunction) _movie_rewind, METH_VARARGS, DOC_GMOVIEMOVIEREWIND}, + { "resize", (PyCFunction) _movie_resize, METH_VARARGS, DOC_GMOVIEMOVIERESIZE}, + { "easy_seek", (PyCFunction) _movie_easy_seek, METH_VARARGS, DOC_GMOVIEMOVIEEASY_SEEK}, + { "shift", (PyCFunction) _movie_shift, METH_VARARGS, DOC_GMOVIEMOVIESHIFT}, + { NULL, NULL, 0, NULL } + }; + +static PyMemberDef _movie_members[] = { + { "_backend", T_STRING, offsetof(struct PyMovie, _backend), 0, "Lists which backend this movie object belongs to."}, + { NULL} + }; + +static PyGetSetDef _movie_getsets[] = + { + { "paused", (getter) _movie_get_paused, NULL, DOC_GMOVIEMOVIEPAUSE, NULL }, + { "playing", (getter) _movie_get_playing, NULL, DOC_GMOVIEMOVIEPLAYING, NULL }, + { "finished", (getter) _movie_get_finished, NULL, DOC_GMOVIEMOVIEFINISHED, NULL }, + { "height", (getter) _movie_get_height, (setter) _movie_set_height, DOC_GMOVIEMOVIEHEIGHT, NULL }, + { "width", (getter) _movie_get_width, (setter) _movie_set_width, DOC_GMOVIEMOVIEWIDTH, NULL }, + { "surface", (getter) _movie_get_surface, (setter) _movie_set_surface, DOC_GMOVIEMOVIESURFACE, NULL }, + { "ytop", (getter) _movie_get_ytop, (setter) _movie_set_ytop, DOC_GMOVIEMOVIEYTOP, NULL }, + { "xleft", (getter) _movie_get_xleft, (setter) _movie_set_xleft, DOC_GMOVIEMOVIEXLEFT, NULL }, + { NULL, NULL, NULL, NULL, NULL } + }; + +static PyTypeObject PyMovie_Type = + { + PyObject_HEAD_INIT(NULL) + 0, + "pygame._movie.Movie", /* tp_name */ + sizeof (PyMovie), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) _movie_dealloc,/* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc) _movie_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + DOC_GMOVIE, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + _movie_methods, /* tp_methods */ + _movie_members, /* tp_members */ + _movie_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) _movie_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0 /* tp_del */ + }; +/*DOC*/ +static char _movie_doc[] = + /*DOC*/ "ffmpeg wrapper module for pygame"; + + + +void _info_init_internal(PyMovieInfo *self, const char *filename) +{ + /* filename checking... */ + self->vid_codec = ""; + self->aud_codec = ""; + + PyObject *path = PyImport_ImportModule("os.path"); + Py_INCREF(path); + PyObject *dict = PyModule_GetDict(path); + PyObject *key = Py_BuildValue("s", "exists"); + Py_INCREF(key); + PyObject *existsFunc = PyDict_GetItem(dict, key); + PyObject *boolean = PyObject_CallFunction(existsFunc, "s", filename); + Py_INCREF(boolean); + if(boolean==Py_False) + { + Py_DECREF(boolean); + Py_DECREF(key); + Py_DECREF(path); + RAISE(PyExc_ValueError, "This filename does not exist."); + return; + //Py_RETURN_NONE; + } + Py_DECREF(boolean); + Py_DECREF(key); + Py_DECREF(path); + + self->filename = (char *)PyMem_Malloc((sizeof(char)*strlen(filename))+sizeof(char)); + strncpy(self->filename, filename, strlen(filename)+1); + AVFormatContext *ic; + AVFormatParameters params, *ap = ¶ms; + int ret, err; + + memset(ap, 0, sizeof(*ap)); + ap->width = 0; + ap->height= 0; + ap->time_base= (AVRational) + { + 1, 25 + }; + ap->pix_fmt = PIX_FMT_NONE; + + err = av_open_input_file(&ic, filename, NULL, 0, ap); + if (err < 0) + { + PyErr_Format(PyExc_IOError, "There was a problem opening up %s, due to %i", filename, err); + ret = -1; + goto fail; + } + err = av_find_stream_info(ic); + if (err < 0) + { + PyErr_Format(PyExc_IOError, "%s: could not find codec parameters", filename); + ret = -1; + goto fail; + } + + if(ic->duration > 0) + { + double duration =(double)ic->duration; + duration /=AV_TIME_BASE; + //should now be number of seconds in a double + self->duration=duration; + } + else + { + self->duration = -1; //to indicate a negative duration value + } + int i; + for(i =0; i<ic->nb_streams; i++) + { + AVCodecContext *enc = ic->streams[i]->codec; + AVCodec *codec; + codec = avcodec_find_decoder(enc->codec_id); + + switch(enc->codec_type) + { + case CODEC_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: + self->width = enc->width; + self->height = enc->height; + self->aspect_ratio = (double)self->width/(double)self->height; + self->vid_codec = (char *)PyMem_Malloc((sizeof(char)*strlen(codec->name))+sizeof(char)); + strncpy(self->vid_codec, codec->name, strlen(codec->name)+1); + break; + + default: + break; + } + } + + ret=0; +fail: + //av_freep(ic); + return; + +} + +int _info_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + Py_INCREF(self); + const char *c; + + if (!PyArg_ParseTuple (args, "s", &c)) + { + PyErr_SetString(PyExc_TypeError, "No valid arguments"); + return -1; + } + + _info_init_internal((PyMovieInfo *)self, c); + + PyObject *er; + er = PyErr_Occurred(); + Py_XINCREF(er); + if(er) + { + PyErr_Print(); + } + Py_XDECREF(er); + if(!self) + { + PyErr_SetString(PyExc_IOError, "No info object created."); + PyErr_Print(); + Py_DECREF(self); + return -1; + } + Py_DECREF(self); + //PySys_WriteStdout("Returning from _movie_init\n"); + return 0; +} + +void _info_dealloc(PyMovieInfo *info) +{ + info->ob_type->tp_free((PyObject *) info); +} + +PyObject* _info_get_duration (PyMovieInfo *info, void *closure) +{ + return PyFloat_FromDouble(info->duration); +} + + +PyObject* _info_get_aspect_ratio (PyMovieInfo *info, void *closure) +{ + return PyFloat_FromDouble(info->aspect_ratio); +} + +PyObject* _info_get_width (PyMovieInfo *info, void *closure) +{ + return PyInt_FromLong((long)info->width); +} + +PyObject* _info_get_height (PyMovieInfo *info, void *closure) +{ + return PyInt_FromLong((long)info->height); +} + +PyObject* _info_get_sample_rate(PyMovieInfo *info, void *closure) +{ + return PyInt_FromLong((long)info->sample_rate); +} + +PyObject* _info_get_channels(PyMovieInfo *info, void *closure) +{ + return PyInt_FromLong((long)info->channels); +} + +PyObject* _info_get_video_codec(PyMovieInfo *info, void *closure) +{ + return PyString_FromString(info->vid_codec); +} + +PyObject* _info_get_audio_codec(PyMovieInfo *info, void *closure) +{ + return PyString_FromString(info->aud_codec); +} + +PyObject* _info_get_filename(PyMovieInfo *info, void *closure) +{ + return PyString_FromString(info->filename); +} + +static PyGetSetDef _info_getsets[] = + { + { "duration", (getter) _info_get_duration, NULL, NULL, NULL }, + { "aspect_ratio", (getter) _info_get_aspect_ratio, NULL, NULL, NULL }, + { "sample_rate", (getter) _info_get_sample_rate, NULL, NULL, NULL }, + { "height", (getter) _info_get_height, NULL, NULL, NULL }, + { "width", (getter) _info_get_width, NULL, NULL, NULL }, + { "channels", (getter) _info_get_channels, NULL, NULL, NULL }, + { "video_codec", (getter) _info_get_video_codec, NULL, NULL, NULL }, + { "audio_codec", (getter) _info_get_audio_codec, NULL, NULL, NULL }, + { "filename", (getter) _info_get_filename, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL } + }; + + +static PyTypeObject PyMovieInfo_Type = + { + PyObject_HEAD_INIT(NULL) + 0, + "pygame._movie.MovieInfo", /* tp_name */ + sizeof (PyMovieInfo), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) _info_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + _info_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) _info_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0 /* tp_del */ + }; + + +PyMODINIT_FUNC +init_movie(void) +{ + PyObject* module; + + /* imported needed apis; Do this first so if there is an error + the module is not loaded. + */ + import_pygame_base (); + if (PyErr_Occurred ()) + { + MODINIT_ERROR; + } + + // Fill in some slots in the type, and make it ready + PyMovie_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&PyMovie_Type) < 0) + { + MODINIT_ERROR; + } + + PyMovieInfo_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&PyMovieInfo_Type) < 0) + { + MODINIT_ERROR; + } + + // Create the module + + module = Py_InitModule3 ("_movie", NULL, _movie_doc); //movie doc needed + + if (module == NULL) + { + return; + } + + + + //Register all the fun stuff for movies. + avcodec_register_all(); + av_register_all(); + //import stuff we need + import_pygame_surface(); + //initialize our flush marker for the queues. + av_init_packet(&flush_pkt); + uint8_t *s = (uint8_t *)"FLUSH"; + flush_pkt.data= s; + + // Add the type to the module. + Py_INCREF(&PyMovie_Type); + PyModule_AddObject(module, "Movie", (PyObject*)&PyMovie_Type); + + Py_INCREF(&PyMovieInfo_Type); + PyModule_AddObject(module, "MovieInfo", (PyObject *)&PyMovieInfo_Type); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gmovie.h Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,59 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* + * _movie - movie support for pygame with ffmpeg + * Author: Tyler Laing + * + * This module allows for the loading of, playing, pausing, stopping, and so on + * of a video file. Any format supported by ffmpeg is supported by this + * video player. Any bugs, please email trinioler@gmail.com :) + */ + + +#ifndef GMOVIE_H_ +#define GMOVIE_H_ +#include "_gmovie.h" + +/*class methods and internals */ +void _movie_init_internal(PyMovie *self, const char *filename, SDL_Surface *surf); +int _movie_init (PyObject *self, PyObject *args, PyObject *kwds); +void _movie_dealloc (PyMovie *movie); +PyObject* _movie_repr (PyMovie *movie); +PyObject* _movie_play (PyMovie *movie, PyObject* args); +PyObject* _movie_stop (PyMovie *movie); +PyObject* _movie_pause (PyMovie *movie); +PyObject* _movie_rewind (PyMovie *movie, PyObject* args); +PyObject* _movie_resize (PyMovie *movie, PyObject* args); +PyObject* _movie_seek (PyMovie *movie, PyObject* args); +PyObject* _movie_easy_seek (PyMovie *movie, PyObject* args); +PyObject *_movie_shift(PyMovie *movie, PyObject*args); + +/* Getters/setters */ +PyObject* _movie_get_paused (PyMovie *movie, void *closure); +PyObject* _movie_get_playing (PyMovie *movie, void *closure); +PyObject* _movie_get_finished(PyMovie *movie, void *closure); +PyObject* _movie_get_width (PyMovie *movie, void *closure); +int _movie_set_width (PyMovie *movie, PyObject *width, void *closure); +PyObject* _movie_get_height (PyMovie *movie, void *closure); +int _movie_set_height (PyMovie *movie, PyObject *height, void *closure); +PyObject* _movie_get_surface (PyMovie *movie, void *closure); +int _movie_set_surface (PyObject *movie, PyObject *surface, void *closure); + +#endif /*GMOVIE_H_*/
--- a/src/image.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/image.c Mon Nov 16 18:31:40 2009 +0000 @@ -26,7 +26,7 @@ */ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/image_doc.h" #include "pgopengl.h" struct _module_state {
--- a/src/imageext.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/imageext.c Mon Nov 16 18:31:40 2009 +0000 @@ -46,7 +46,7 @@ #endif #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/image_doc.h" #include "pgopengl.h" #include <SDL_image.h>
--- a/src/joystick.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/joystick.c Mon Nov 16 18:31:40 2009 +0000 @@ -23,7 +23,7 @@ #define PYGAMEAPI_JOYSTICK_INTERNAL #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/joystick_doc.h" #define JOYSTICK_MAXSTICKS 32 static SDL_Joystick* joystick_stickdata[JOYSTICK_MAXSTICKS] = {NULL}; @@ -201,8 +201,9 @@ } value = SDL_JoystickGetAxis (joy, axis); +#ifdef DEBUG printf("SDL_JoystickGetAxis value:%d:\n", value); - +#endif return PyFloat_FromDouble (value / 32768.0); } @@ -241,8 +242,9 @@ } value = SDL_JoystickGetButton (joy, _index); +#ifdef DEBUG printf("SDL_JoystickGetButton value:%d:\n", value); - +#endif return PyInt_FromLong (value); } @@ -277,8 +279,9 @@ return RAISE (PyExc_SDLError, "Joystick not initialized"); } value = SDL_JoystickNumBalls (joy); +#ifdef DEBUG printf("SDL_JoystickNumBalls value:%d:\n", value); - +#endif if (_index < 0 || _index >= value) { return RAISE (PyExc_SDLError, "Invalid joystick trackball"); } @@ -300,8 +303,9 @@ } value = SDL_JoystickNumHats (joy); +#ifdef DEBUG printf("SDL_JoystickNumHats value:%d:\n", value); - +#endif return PyInt_FromLong (value); } @@ -327,8 +331,9 @@ px = py = 0; value = SDL_JoystickGetHat (joy, _index); +#ifdef DEBUG printf("SDL_JoystickGetHat value:%d:\n", value); - +#endif if (value & SDL_HAT_UP) { py = 1; }
--- a/src/key.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/key.c Mon Nov 16 18:31:40 2009 +0000 @@ -25,7 +25,7 @@ */ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/key_doc.h" /* keyboard module functions */ static PyObject*
--- a/src/mask.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/mask.c Mon Nov 16 18:31:40 2009 +0000 @@ -30,7 +30,7 @@ #include "mask.h" #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/mask_doc.h" #include "structmember.h" #include "bitmask.h" #include <math.h>
--- a/src/mixer.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/mixer.c Mon Nov 16 18:31:40 2009 +0000 @@ -26,7 +26,7 @@ #define PYGAMEAPI_MIXER_INTERNAL #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/mixer_doc.h" #include "mixer.h"
--- a/src/mouse.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/mouse.c Mon Nov 16 18:31:40 2009 +0000 @@ -25,7 +25,7 @@ */ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/mouse_doc.h" /* mouse module functions */ static PyObject*
--- a/src/movie.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/movie.c Mon Nov 16 18:31:40 2009 +0000 @@ -25,7 +25,7 @@ */ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/movie_doc.h" #include "smpeg.h" typedef struct
--- a/src/music.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/music.c Mon Nov 16 18:31:40 2009 +0000 @@ -26,7 +26,7 @@ #define PYGAMEAPI_MUSIC_INTERNAL #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/music_doc.h" #include "mixer.h" static Mix_Music* current_music = NULL;
--- a/src/overlay.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/overlay.c Mon Nov 16 18:31:40 2009 +0000 @@ -26,7 +26,7 @@ #include <Python.h> #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/overlay_doc.h" typedef struct {
--- a/src/pixelarray.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/pixelarray.c Mon Nov 16 18:31:40 2009 +0000 @@ -22,7 +22,7 @@ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/pixelarray_doc.h" #include "surface.h" #if PY_VERSION_HEX < 0x02050000
--- a/src/rect.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/rect.c Mon Nov 16 18:31:40 2009 +0000 @@ -25,7 +25,7 @@ */ #define PYGAMEAPI_RECT_INTERNAL #include "pygame.h" -#include "pygamedocs.h" +#include "doc/rect_doc.h" #include "structmember.h" #include "pgcompat.h"
--- a/src/rect.doc Mon Nov 16 18:05:30 2009 +0000 +++ b/src/rect.doc Mon Nov 16 18:31:40 2009 +0000 @@ -68,6 +68,8 @@ Rect.copy(): return Rect Returns a new rectangle having the same position and size as the orginal. + +New in pygame 1.9 <END>
--- a/src/scale.h Mon Nov 16 18:05:30 2009 +0000 +++ b/src/scale.h Mon Nov 16 18:31:40 2009 +0000 @@ -29,7 +29,7 @@ #if !defined(SCALE_HEADER) #define SCALE_HEADER -#if (defined(__GNUC__) && ((defined(__x86_64__) && !defined(_NO_MMX_FOR_X86_64)) || defined(__i386__))) || defined(MS_WIN32) +#if (defined(__GNUC__) && ((defined(__x86_64__) && !defined(_NO_MMX_FOR_X86_64)) || defined(__i386__))) || (defined(MS_WIN32) && !(defined(_M_X64) && defined(_NO_MMX_FOR_X86_64))) #define SCALE_MMX_SUPPORT /* These functions implement an area-averaging shrinking filter in the X-dimension.
--- a/src/scrap.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/scrap.c Mon Nov 16 18:31:40 2009 +0000 @@ -29,7 +29,7 @@ #include "scrap.h" #include "pygame.h" -#include "pygamedocs.h" +#include "doc/scrap_doc.h" /** * Indicates, whether pygame.scrap was initialized or not.
--- a/src/surface.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/surface.c Mon Nov 16 18:31:40 2009 +0000 @@ -24,7 +24,7 @@ #define PYGAMEAPI_SURFACE_INTERNAL #include "surface.h" -#include "pygamedocs.h" +#include "doc/surface_doc.h" #include "structmember.h" #include "pgcompat.h"
--- a/src/surface.doc Mon Nov 16 18:05:30 2009 +0000 +++ b/src/surface.doc Mon Nov 16 18:31:40 2009 +0000 @@ -195,6 +195,8 @@ overwritten retain their original pixel values. Scrolling is contained by the Surface clip area. It is safe to have dx and dy values that exceed the surface size. + +New in Pygame 1.9 <END>
--- a/src/time.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/time.c Mon Nov 16 18:31:40 2009 +0000 @@ -22,7 +22,7 @@ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/time_doc.h" #define WORST_CLOCK_ACCURACY 12 static SDL_TimerID event_timers[SDL_NUMEVENTS] = {NULL};
--- a/src/transform.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/transform.c Mon Nov 16 18:31:40 2009 +0000 @@ -26,7 +26,7 @@ */ #include "pygame.h" #include "pgcompat.h" -#include "pygamedocs.h" +#include "doc/transform_doc.h" #include <math.h> #include <string.h> #include "scale.h"
--- a/symbian/BuildPygameRelease.py Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/BuildPygameRelease.py Mon Nov 16 18:31:40 2009 +0000 @@ -1,4 +1,5 @@ -""" Full build configuration for pygame +""" Full build configuration for pygame. +Reads configuration and creates appropriate parameters for SCons build scripts. For SVN support, install pysvn. """ @@ -26,9 +27,7 @@ UID_PYGAMEAPP = getuid() UID_SDL = getuid() UID_JPEG = getuid() - -#: Base uid for PyS60 CE scripts -UID_BASE = getuid() +UID_BASE = getuid() #: Capability configuration CAPABILITIES = CAPS_SELF_SIGNED[:] @@ -104,13 +103,16 @@ # Build pygame args["pythonsis"] = sisname args["pythonsis"] = sisname - args["sisappname"] = '"pygame for S60"' + args["sisappname"] = '"pygame"' args['sisversion'] = '1,%d,%d%s' % ( int(version[2:4]), int( version[4:6]),version[6:]) args['sisuid'] = hex(UID_PACKAGE).replace("L","") args['appuid'] = hex(UID_PYGAMEAPP).replace("L","") args['sdluid'] = hex(UID_SDL).replace("L","") args['jpeguid']= hex(UID_JPEG).replace("L","") args['pythoninclude'] = config.pythoninclude + args["staticmods"] = config.staticmods + args["modbaseuid"] = hex(UID_BASE).replace("L","") + args["build_libs"] = config.build_libs #args['defines'] = "STDERR_TO_STDOUT" args['winscw_options'] = "-nostderr" # Don't show the stdioserver output dobuild(args)
--- a/symbian/SConscript.SDL.py Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/SConscript.SDL.py Mon Nov 16 18:31:40 2009 +0000 @@ -37,7 +37,7 @@ 'cone', 'bitgdi', 'scdv', - 'hal', + 'hal', # 'libc', # 'libm', ]
--- a/symbian/SConscript.app.py Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/SConscript.app.py Mon Nov 16 18:31:40 2009 +0000 @@ -10,36 +10,42 @@ pygame_rss = File("app/pygame.rss") pygame_reg_rss = File( "app/pygame_reg.rss") +defines = [ + #"__LOGMAN_ENABLED__", +] +sources = [ + "app/pygame_app.cpp", + "app/pygame_main.cpp", +] + +if HAVE_STATIC_MODULES: + sources += [ "common/builtins.c" ] + defines += [ "HAVE_STATIC_MODULES=1"] + SymbianProgram( "pygame", TARGETTYPE_EXE, resources = [pygame_rss, pygame_reg_rss], - sources = ["app/pygame_app.cpp", - "app/pygame_main.cpp" - ], - includes = ["app", "common", + sources = sources, + includes = ["app", "common", join( "deps", "SDL", "include"), join( "deps", "SDL", "symbian", "inc"), - C_INCLUDE ] + python_includes - - , - defines = [ - #"__LOGMAN_ENABLED__", - ], + C_INCLUDE ] + + python_includes, + defines = defines, libraries = C_LIBRARY + ["euser", "avkon", "apparc", "cone","eikcore", "libGLES_CM", "bafl", # arrays and command line PYTHON_LIB_NAME, - SDL_DLL_NAME, - "pygame.lib", + SDL_DLL_NAME, 'pygame_libjpeg', #"LogMan" - ], - uid3=UID_PYGAMEAPP, - icons = [ ("../lib/pygame_icon.svg", "pygame") ], - package=PACKAGE_NAME, + ] + PYGAME_STATIC_MODULES, # Add static pygame modules + uid3 = UID_PYGAMEAPP, + icons = [ ("../lib/pygame_icon.svg", "pygame") ], + package = PACKAGE_NAME, capabilities = CAPABILITIES, # 100k, 4MB - epocheapsize = ( 0x19000, 0x400000 ), - epocstacksize = 0x14000, + epocheapsize = ( 0x19000, 0x400000 ), + epocstacksize = 0x14000, winscw_options = "-w noempty", )
--- a/symbian/SConscript.pygame.py Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/SConscript.pygame.py Mon Nov 16 18:31:40 2009 +0000 @@ -1,14 +1,11 @@ Import("*") +from glob import glob from scons_symbian import * -import glob +import os python_includes = [ PYTHON_INCLUDE ] - -#music.c -#mixer.c -#font.c -#imageext.c + IGNORED = r""" pypm.c camera.c @@ -27,8 +24,8 @@ joystick.c cdrom.c""".split() -pygame_sources = glob.glob( "../src/*.c" ) -pygame_sources += glob.glob( "../src/SDL_gfx/*.c" ) +pygame_sources = glob( "../src/*.c" ) +pygame_sources += glob( "../src/SDL_gfx/*.c" ) removed = [] for x in pygame_sources: for y in IGNORED: @@ -38,17 +35,27 @@ for x in removed: pygame_sources.remove(x) - -pygame_sources.append("common/builtins.c") - + if USE_OPENC: C_LIB_INCLUDE = "OPENC" else: C_LIB_INCLUDE = "" - -# Build pygame library -SymbianProgram( "pygame", TARGETTYPE_LIB, - sources = pygame_sources, + +#: List of static modules for linking +PYGAME_STATIC_MODULES = [] + +def createPygameLibrary( modname, sources, ): + modname = "pygame_" + modname + uid = 0 + targettype = TARGETTYPE_LIB + if not HAVE_STATIC_MODULES: + targettype = TARGETTYPE_PYD + # Add the PyS60 prefix + modname = "kf_" + modname + uid = getUID() + # Build pygame library + SymbianProgram( modname, targettype, + sources = ["../src/" + x for x in sources], defines = [ C_LIB_INCLUDE ], @@ -62,21 +69,64 @@ join( "deps", "SDL", "include"), join( "deps", "SDL", "symbian", "inc"), C_INCLUDE, - #join( "..", "..", "tools", "debug" ) ], package = PACKAGE_NAME, libraries = C_LIBRARY + [ PYTHON_LIB_NAME, "euser", "avkon", "apparc", - "cone","eikcore", "libGLES_CM", + "cone","eikcore", "libGLES_CM", "pygame_libjpeg", SDL_DLL_NAME, ], winscw_options = "-w noempty", + uid3 = uid, ) + m = ".".join( [modname, targettype] ) + + if HAVE_STATIC_MODULES: + PYGAME_STATIC_MODULES.append( m ) + + +def createPygameMods(): + """ Create pygame native modules """ + + # Get the mods. Python wrappers can be conveniently used here. + mods = [ os.path.basename( x ).replace(".py", "") for x in glob("lib/*.py") ] + + # Most of the modules have only 1 source file : <modname>.c + # This dict can be used to map differing or multiple source files to module. + module_src_map = { + "surface" : ( + "surface.c", + "scale2x.c", + "surface_fill.c", + "alphablit.c", + ), + "gfxdraw" : ( + "gfxdraw.c", + "SDL_gfx/SDL_gfxPrimitives.c" + ), + "fastevent" : ( + "fastevents.c", + "fastevent.c" + ), + "transform" : ( + "transform.c", + "rotozoom.c", + "scale2x.c" + ) + } + + for x in mods: + # Get source mapping + src = module_src_map.get( x, [ x + ".c"]) + createPygameLibrary( x, src ) + + # This one is special + createPygameLibrary( "mixer_music", ["music.c"]) + +createPygameMods() # Install pygame python libraries -from glob import glob - pylibzip = "data/pygame/libs/pygame.zip" def to_package(**kwargs): kwargs["source"] = abspath( kwargs["source"] ) @@ -100,16 +150,16 @@ for x in glob( "lib/*.py"): to_package( source = x, target = pygame_lib ) -# Install default font -#to_package( source = "../lib/freesansbold.ttf", target = pygame_lib ) - - - def packagePyS60Stdlib(**kwargs): kwargs["source"] = join( "deps/PythonForS60/module-repo/standard-modules", kwargs["source"] ) return to_package( **kwargs ) -packagePyS60Stdlib( source = "glob.py", target = "data/pygame/libs" ) +# Add files missing from standard PyS60 installation +packagePyS60Stdlib( source = "glob.py", target = "data/pygame/libs" ) zippath = packagePyS60Stdlib( source = "fnmatch.py", target = "data/pygame/libs" ) +# Install default font into zip as well File2Zip( zippath, "../lib/freesansbold.ttf", "pygame/freesansbold.ttf" ) + +# Export static library names to be used for building pygame.exe +Export( "PYGAME_STATIC_MODULES")
--- a/symbian/SConstruct Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/SConstruct Mon Nov 16 18:31:40 2009 +0000 @@ -2,8 +2,7 @@ from scons_symbian import * constants.SIGNSIS_OUTPUT_EXTENSION = ".sisx" -gcce.GCCE_OPTIMIZATION_FLAGS = "-O2 -fno-unit-at-a-time" - +gcce.GCCE_OPTIMIZATION_FLAGS = "-O3 -fno-unit-at-a-time -ffast-math" SVNREVISION = "" @@ -39,6 +38,9 @@ #: Name of the used libpng.dll PNG_DLL_NAME = ARGUMENTS.get( "pngdll", "pygame_libpng" ) +#: Create static modules or dynamic modules( pyds ) +HAVE_STATIC_MODULES = eval( ARGUMENTS.get( "staticmods", False ) ) + #: Using OpenC or estlib? USE_OPENC = ARGUMENTS.get( "openc", True ) if USE_OPENC: @@ -78,8 +80,14 @@ UID_PYGAMEAPP = ARGUMENTS["appuid"] UID_SDL = ARGUMENTS["sdluid"] UID_JPEG = ARGUMENTS["jpeguid"] -UID_PNG = 0#ARGUMENTS["pnguid"] - +UID_PNG = 0#ARGUMENTS["pnguid"] +#: The base uid for all pygame modules. +UID_MODBASE = ARGUMENTS["modbaseuid"] +__uid = int(UID_MODBASE, 16) +def getUID(): + global __uid + __uid += 1 + return __uid EMBEDDED_PYTHON_SIS = ARGUMENTS.get( "pythonsis", "none" ) if EMBEDDED_PYTHON_SIS.lower() != "none" and COMPILER != COMPILER_WINSCW: @@ -97,10 +105,14 @@ EMBEDDED_PYTHON_SIS = None EMBEDDED_PYTHON_SIS_UID = 0x0 -Export("PACKAGE_NAME PYTHON_LIB_NAME PATH_PY_LIBS SDL_DLL_NAME CAPABILITIES PYTHON_INCLUDE USE_OPENC C_LIBRARY C_INCLUDE") +Export("PACKAGE_NAME PYTHON_LIB_NAME" + " PATH_PY_LIBS SDL_DLL_NAME" + " CAPABILITIES PYTHON_INCLUDE" + " USE_OPENC C_LIBRARY C_INCLUDE" + " HAVE_STATIC_MODULES getUID") # Build external libraries. Conditional because needed only once and takes extra time after that. -if ARGUMENTS.get( "buildlibs", True ): +if eval( ARGUMENTS.get( "build_libs", "True" ) ): SConscript( "SConscript.sft2.py" ) SConscript( "SConscript.Ogg.py" ) SConscript( "SConscript.Vorbis.py" )
--- a/symbian/app/launcher/pygame_launcher.py Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/app/launcher/pygame_launcher.py Mon Nov 16 18:31:40 2009 +0000 @@ -30,6 +30,9 @@ THISDIR = os.path.dirname(__file__) +def make_surface(rect, flags=0, depth=16): + return pygame.Surface(rect, flags, depth) + def load_image(name, colorkey=None): """ Image loading utility from chimp.py """ fullname = os.path.join(THISDIR, name) @@ -106,7 +109,11 @@ def tweenEaseInBack(self, t, b, c, d, s=1.7158): t /= d return c * (t) * t * ((s + 1) * t - s) + b; - + + def easeNone(self, t, b, c, d, s=1.7158): + v = c*t/d + b; + return v + def _slide_and_replace(self, direction, surf, surfold, surfnew, v): r = surf.get_rect() @@ -153,19 +160,47 @@ """ This creates an effect where the surface is scaled and moved so that it looks like the surface moves to the distance. + + @param surf: The surface containing the result of the effect. + @param surfold: The surface to be zoomed. + @param surfnew: The next surface acting as a background. + @param v: The tween value. Position of the animation. """ r = surf.get_rect() - w = int(r.width * (1 - v)) - h = int(r.height * (1 - v)) + # Define size of the scaling + w, h = int(r.width * (1 - v)), int(r.height * (1 - v)) + x, y = int(r.width / 2 * (v)), int(r.height / 2 * (v)) - s = pygame.transform.scale(surfold, (w, h)) + _x = max(0,x) + _y = max(0,y) + _w = min(r.width,w) + _h = min(r.height,h) + target_subsurf = surf.subsurface((_x, _y, _w, _h)) + # Scale full or only partial if scaling larger + use_subsurf = (v < 0) + if use_subsurf: + # Full size - exceeding size and scale that instead of full surface + if w > r.width: + w -= ( w - r.width ) * 2 + if h > r.height: + h -= ( h - r.height) * 2 + if x < 0: + x *= -1 + if y < 0: + y *= -1 + + source_subsurf = surfold.subsurface( ( x, y, w, h) ) + else: + source_subsurf = surfold + + # The new surface is the background surf.blit(surfnew,(0,0)) - - surf.blit(s, (r.width / 2 * (v), r.height / 2 * (v))) + s = pygame.transform.scale(source_subsurf, (_w, _h), target_subsurf) + return surf, 0,0 def do(self, effect_tween, duration): @@ -194,7 +229,7 @@ now = time.time() # The animation buffer - #surf = pygame.Surface(self.surf1.get_size(), ) + #surf = make_surface(self.surf1.get_size(), ) while True: t = now - start @@ -335,7 +370,7 @@ self.sysdata = sysdata self.screen = sysdata.screen screen_size = self.screen.get_size() - self.surface = pygame.Surface(screen_size, ) + self.surface = make_surface(screen_size, ) class BackgroundTransparent(BackgroundBase): @@ -357,27 +392,29 @@ self.rect = self.surface.get_rect() #: The logo - self.img_logo, r = load_image("logo.jpg") - - # Position the logo on middle of the screen. - c = self.rect.center - self.img_pos = [ c[0] - r.w / 2, c[1] - r.h / 2 ] - - #: Make alpha the same size as the image - #self.alpha = pygame.Surface(r.size, ) + self.img_logo, self.img_size = load_image("logo.jpg") self.alphaval = 0. self.alphaprev = -1 - self.alphadir = - 1. # per second + self.alphadir = - 2. # per second + + self.updateAlphaValue() + # Position the logo on middle of the screen. + self.draw() + def draw(self): + c = self.rect.center + r = self.img_size + self.img_pos = [ c[0] - r.w / 2, c[1] - r.h / 2 ] + self.surface.fill(BLACK) self.surface.blit(self.img_logo, self.img_pos) self.surface.set_alpha(10) def updateAlphaValue(self): """ Update the visibility of the logo """ - min = 6. - max = 12. + min = 12. + max = 24. s = self.sysdata.ticdiff / 1000. @@ -390,15 +427,11 @@ if self.alphaval < min: self.alphaval = min self.alphadir = - self.alphadir + return self.alphaval def update(self): self.surface.set_alpha(self.updateAlphaValue()) - #print a - #a = self.alphaval - #self.surface.fill(BLACK) - #self.surface.blit(self.img_logo, self.img_pos) - #self.surface.fill( (a,a,a), None, BLEND_RGB_MULT ) class TextField(pygame.sprite.Sprite): """ Handles text rendering and updating when necessary """ @@ -436,12 +469,12 @@ psize = self.bg.surface.get_size() size = (psize[0], psize[1] - startposy) - surf = pygame.Surface(size, ) + surf = make_surface(size, ) # Create text contents DrawUtils.drawRectWithText(surf, size, TITLE_BG, TITLE_STROKE, textsurf=None) - #text = textwrap.dedent(text) + font = self.sysdata.getFontSmall() lines = text.split("\n") @@ -474,7 +507,7 @@ size = (size[0], 40) # Draw the surrounding rect - surf = titlebg = pygame.Surface(size, ) + surf = titlebg = make_surface(size, ) DrawUtils.drawRectWithText(surf, size, TITLE_BG, TITLE_STROKE, textsurf=text, textpos=textpos) @@ -753,7 +786,7 @@ def _create_list_bg(self, size): - surf = pygame.Surface(size, ) + surf = make_surface(size, ) DrawUtils.drawRectWithText(surf, size, TITLE_BG, TITLE_STROKE, textsurf=None) self.itemsurface = surf return surf @@ -870,7 +903,7 @@ size = (size[0], 40) # Render the final title surface with combined background and text - surf = pygame.Surface(size, ) + surf = make_surface(size, ) DrawUtils.drawRectWithText(surf, size , TITLE_BG, TITLE_STROKE, text, textpos) # Update data @@ -893,16 +926,19 @@ def __init__(self): if sys.platform == "symbian_s60": - size = pygame.display.list_modes(16)[0] - self.screen = pygame.display.set_mode(size, ) + modes = pygame.display.list_modes(16) + print "Available display modes:", modes + size = modes[0] + self.screen = pygame.display.set_mode(size, 0, 16) else: - self.screen = pygame.display.set_mode(DISPLAY_SIZE, 16) + self.screen = pygame.display.set_mode(DISPLAY_SIZE, 0, 16) self.sysdata = SystemData() self.sysdata.screen = self.screen self.mainbg = Background(self.sysdata) - self.bg = BackgroundTransparent(self.sysdata) + self.bg = BackgroundTransparent(self.sysdata) + self.bganim = self.mainbg#BackgroundTransparent(self.sysdata) items = [("Applications", self.mhApplications, ()), # TODO: Disabled settings for now... @@ -926,29 +962,31 @@ #: Updated by foreground event self.is_foreground = True - - def initialize(self): - pass - + def run(self): - """ Main application loop """ - self.initialize() - + """ Main application loop """ # From black - black = pygame.Surface(self.screen.get_size(), ) - self.sprites.update() - self.screen.blit(self.bg.surface, (0, 0)) + def anim(): + self.bganim.surface.fill(BLACK) + #black = make_surface(self.screen.get_size()) + self.sprites.update() + self.screen.blit(self.bganim.surface, (0, 0)) + + # Start the tween animation + e = Effects(self.screen, self.clock, self.bganim.surface, self.bg.surface ) - # Start the tween animation - e = Effects(self.screen, self.clock, black, self.bg.surface ) - - # Blocks for the duration of the animation - e.do( [ - (e.effectFadeTo, e.tweenEaseOutSine), - #(e.effectSlideRightReplace, e.tweenEaseInBack), - ], 0.5) - - self.sysdata.tics = pygame.time.get_ticks() + # Blocks for the duration of the animation + e.do( [ + (e.effectFadeTo, e.tweenEaseOutSine), + #(e.effectSlideRightReplace, e.tweenEaseInBack), + ], 0.5) + + self.sysdata.tics = pygame.time.get_ticks() + + # Restore alpha + self.mainbg.surface.set_alpha(255) + self.mainbg.draw() + anim() eventhandler = self.handleEvent while self.running: @@ -967,7 +1005,6 @@ self.bg.surface.set_alpha(96) # This creates a nice fade effect for menu items self.screen.blit(self.bg.surface, (0, 0)) - pygame.display.flip() if self.is_foreground: @@ -987,7 +1024,6 @@ if app_path is None: # Restore pygame launcher menu - self.__handle_transition_animation(self.focused, self._main_menu, effect=1) self.focused.clear() @@ -997,14 +1033,27 @@ return # Start the tween animation - blacksurf = pygame.Surface(self.screen.get_size(), ) - blacksurf.fill(BLACK) - e = Effects(self.screen, self.clock, self.focused.bg.surface, blacksurf, + #self.bganim.surface.fill(BLACK) + self.bganim.surface.set_alpha(255) + self.bg.surface.set_alpha(96) + e = Effects(self.screen, self.clock, self.focused.bg.surface, self.bganim.surface, render_callback=None) # Blocks for the duration of the animation - effect = e.effectZoomOut - e.do((effect, e.tweenEaseInBack), 0.75) + effect = [ + (e.effectZoomOut, e.tweenEaseInBack), + ] + + e.do(effect, 0.5) + + # Fade the logo + self.bg.surface.fill(BLACK) + e = Effects(self.screen, self.clock, self.bganim.surface, self.bg.surface ) + + # Blocks for the duration of the animation + e.do( [ + (e.effectFadeTo, e.easeNone), + ], 0.5) # Remove so it won't flash at the end self.sprites.remove(self.focused) @@ -1014,18 +1063,25 @@ self.running = 0 def __handle_transition_animation(self, menu1, menu2, effect): - bg1 = BackgroundTransparent(self.sysdata) - bg2 = BackgroundTransparent(self.sysdata) - menu1.bg = bg1 - menu2.bg = bg2 + + # We use the mainbg as temporary buffer during animation + self.mainbg.surface.set_alpha(255) + + menu2.bg = self.bganim + menu1.update() + menu2.update() - def render_callback(surf): - menu1.update() - menu2.update() + bg1 = menu1.bg + bg2 = menu2.bg + + # This makes the logo appear from behind + bg2.surface.set_alpha(96) + #def render_callback(s): + # Make the logo appear on both + #menu2.bg.surface.fill(WHITE) # Start the tween animation - e = Effects(self.screen, self.clock, bg1.surface, bg2.surface, - render_callback=render_callback) + e = Effects(self.screen, self.clock, bg1.surface, bg2.surface)#, render_callback) # Blocks for the duration of the animation effect = [e.effectSlideLeftReplace, e.effectSlideRightReplace, e.effectFadeTo][effect] @@ -1038,7 +1094,8 @@ menu2.bg = self.bg menu2.update() - bg1.surface.blit(bg2.surface, (0, 0)) + # Restore the background logo + self.mainbg.draw() def mhApplications(self): """ Menu handler for 'Applications' item """ @@ -1065,15 +1122,15 @@ self.sprites.remove(self.focused) # Create tween effect for transition - background = Background(self.sysdata) - + background = self.bganim menu = Menu(background, self.sysdata, title="Applications", items=items, cancel_callback=(self.mhLaunchApplication, (None,)), ) - menu.textcache.max_size = 24 + menu.textcache.max_size = 12 menu.update() + self.__handle_transition_animation(self.focused, menu, effect=0) self.focused = menu @@ -1083,16 +1140,21 @@ """ Menu handler for exit item """ self.running = 0 - # Fade to black - black = pygame.Surface(self.screen.get_size(), ) - + # Fade to logo and then to black # Start the tween animation - e = Effects(self.screen, self.clock, self.bg.surface, black ) + e = Effects(self.screen, self.clock, self.bg.surface, self.bganim.surface ) # Blocks for the duration of the animation e.do( [ - (e.effectFadeTo, e.tweenEaseOutSine), - (e.effectZoomOut, lambda t, b, c, d, s=3.70158:e.tweenEaseInBack(t,0,0.5,d,s)), + (e.effectFadeTo, e.easeNone), + ], 0.5) + + self.bg.surface.fill(BLACK) + e = Effects(self.screen, self.clock, self.bganim.surface, self.bg.surface ) + + # Blocks for the duration of the animation + e.do( [ + (e.effectFadeTo, e.easeNone), ], 0.5) self.focused = None @@ -1102,7 +1164,7 @@ """ Menu handler for settings item """ self.sprites.remove(self.focused) - tf = TextField(self.bg, self.sysdata, + tf = TextField(self.bganim, self.sysdata, exit_callback=self._exit_to_main, title="Settings", text="Begone! Nothing to see here!", @@ -1115,7 +1177,6 @@ def _exit_to_main(self): """ Callback to exit back to main menu """ - self.__handle_transition_animation(self.focused, self._main_menu, effect=1) self.sprites.remove(self.focused) @@ -1136,7 +1197,7 @@ """ self.sprites.remove(self.focused) - self.focused = TextField(self.bg.surface, self.sysdata, + self.focused = TextField(self.bganim, self.sysdata, exit_callback=self._exit_to_main, title="About", text=text, @@ -1177,7 +1238,8 @@ def start(): """ Start pygame launcher """ - pygame.init() + pygame.display.init() + pygame.font.init() while True: # Don't handle events given for launched application
--- a/symbian/app/pygame_app.cpp Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/app/pygame_app.cpp Mon Nov 16 18:31:40 2009 +0000 @@ -13,9 +13,6 @@ #include "logmanutils.h" -const TUid KUidPygameApp = -{ __UID3__ }; - TInt Ticks; TInt Frames; TInt Done; @@ -310,7 +307,8 @@ TUid CSdlApplication::AppDllUid() const { - return KUidPygameApp; + // Get the uid from process + return RProcess().SecureId(); } CApaDocument* CSdlApplication::CreateDocumentL()
--- a/symbian/app/pygame_main.cpp Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/app/pygame_main.cpp Mon Nov 16 18:31:40 2009 +0000 @@ -34,7 +34,9 @@ Py_Initialize(); // Add built-in pygame modules +#ifdef HAVE_STATIC_MODULES PyImport_ExtendInittab(_PyGame_Inittab); +#endif LOGMAN_SENDLOG( "Entering interpreter"); #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2
--- a/symbian/default_build_config.py Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/default_build_config.py Mon Nov 16 18:31:40 2009 +0000 @@ -1,12 +1,15 @@ # These are the defaults used by configure.py # when build_config.py does not exist build_python = False +build_libs = True pys60_ce_src = '' pys60_sis = None pythondll = 'python25' pythoninclude = r'/epoc32/include/python25' pycompiler = "python" +staticmods = False + # Defaults for certificates cert = None privkey = None -passphrase = None \ No newline at end of file +passphrase = None
--- a/symbian/how_to_build.txt Mon Nov 16 18:05:30 2009 +0000 +++ b/symbian/how_to_build.txt Mon Nov 16 18:31:40 2009 +0000 @@ -9,18 +9,41 @@ Run 'makeref.py --no-code-docs' - This regenerates pygame module documentation without documentation in code. +-- Not very useful on the phone. -Create symbian/deps directory +- The build scripts use SCons for Symbian. +-- http://code.google.com/p/scons-for-symbian/ +-- Follow the installation instructions + + +The used libraries are stored in pygame-for-s60 project page at code.google.com. +They must be copied to symbian/deps directory. + +Go to the symbian folder and execute SVN checkout: + +svn checkout http://pygame-symbian-s60.googlecode.com/svn/trunk/deps deps -Get PyS60 SDK from Maemo Garage +== Install PyS60 stuff == + +- Make sure your EPOCROOT environment variable points to your Symbian SDK +- Run: + deps\misc\get_pys60.py --tools-path=deps + +-- This gets the latest PyS60 release and unzips it into your EPOCROOT + +Or do it manually: + +Get latest PyS60 & OpenC SDKs from Maemo Garage - https://garage.maemo.org/frs/?group_id=854&release_id=2673 -- Unzip the stuff to your Symbian epocroot -Get PyS60 packaging tool -- Use the installer or get the tar.gz package. +Get PyS60 packaging tool( from maemo ) +- Get the tar.gz package. -- Copy the PythonForS60 folder to 'deps' +== The original sources of external libraries == + Checkout ogg to symbian/deps/ogg - IMPORTANT: Revision 7524 - SVN: http://svn.xiph.org/trunk/ogg @@ -64,10 +87,6 @@ Checkout PNG library to symbian/deps/libpng - http://pamp.svn.sourceforge.net/svnroot/pamp/libpng/trunk/libpng-1.2.18 -- The build scripts use SCons for Symbian. --- http://code.google.com/p/scons-for-symbian/ --- Follow the installation instructions - === Building ===
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian/lib/bufferproxy.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,1 @@ +from pygame_bufferproxy import *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian/lib/fastevent.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,1 @@ +from pygame_fastevent import *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian/lib/imageext.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,1 @@ +from pygame_imageext import *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian/lib/overlay.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,1 @@ +from pygame_overlay import *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian/lib/pixelarray.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,1 @@ +from pygame_pixelarray import *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/_dummymovietest.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,142 @@ +#################################### IMPORTS ################################### + +from __future__ import generators + +if __name__ == '__main__': + import sys + import os + pkg_dir = os.path.split(os.path.abspath(__file__))[0] + parent_dir, pkg_name = os.path.split(pkg_dir) + is_pygame_pkg = (pkg_name == 'tests' and + os.path.split(parent_dir)[1] == 'pygame') + if not is_pygame_pkg: + sys.path.insert(0, parent_dir) +else: + is_pygame_pkg = __name__.startswith('pygame.tests.') + +if is_pygame_pkg: + from pygame.tests.test_utils import test_not_implemented, unittest, trunk_relative_path +else: + from test.test_utils import test_not_implemented, unittest + + +import pygame +import pygame._dummybackend as gmovie +from pygame.locals import * + +import os +import sys +import time + +################################### CONSTANTS ################################## +filename = "War3.avi" + + +class MovieTypeTest( unittest.TestCase ): + def test_init(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + self.assertEqual(movie, True) + + #screen = pygame.display.get_surface() + #movie = pygame.gmovie.Movie(filename, screen) + #self.assertEqual(movie, True) + + del movie + + def test_play_pause(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + self.assertEqual(movie.playing, False) + + movie.play(-1) + + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + + movie.pause() + + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, True) + + movie.pause() + + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + + del movie + + def test_stop(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + self.assertEqual(movie.playing, False) + movie.play(-1) + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + movie.stop() + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, False) + + del movie + + def test_rewind(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + movie.play(-1) + time.sleep(2) + #equivalent to stop without a time-argument + movie.rewind() + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, False) + + del movie + + def test_width(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + print movie.width + self.assertEqual(movie.width, 200) + + del movie + + def test_height(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + print movie.height + self.assertEqual(movie.height, 200) + + del movie + + + def test_resize(self): + + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + movie.play(-1) + movie.resize(movie.width/2, movie.height/2) + #equivalent to stop without a time-argument + + self.assertEqual(movie.height, 100) + self.assertEqual(movie.width, 100) + + del movie + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/_movie_tags.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,15 @@ +__tags__ = [] +import sys + +# only supported on linux so far. +if (sys.platform == 'linux2'): + exclude = False +else: + exclude = True + +# not portable to Python 3 yet. +exclude = exclude or sys.version_info > (3,) + +if exclude: + __tags__.extend(['ignore', 'subprocess_ignore']) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/_movie_test.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,141 @@ +#################################### IMPORTS ################################### + +from __future__ import generators + +if __name__ == '__main__': + import sys + import os + pkg_dir = os.path.split(os.path.abspath(__file__))[0] + parent_dir, pkg_name = os.path.split(pkg_dir) + is_pygame_pkg = (pkg_name == 'tests' and + os.path.split(parent_dir)[1] == 'pygame') + if not is_pygame_pkg: + sys.path.insert(0, parent_dir) +else: + is_pygame_pkg = __name__.startswith('pygame.tests.') + +if is_pygame_pkg: + from pygame.tests.test_utils import test_not_implemented, unittest, trunk_relative_path +else: + from test.test_utils import test_not_implemented, unittest, trunk_relative_path + + +import pygame +try: + import pygame._movie as gmovie +except: + gmovie = None + + + +from pygame.locals import * + +import os +import sys +import time + +################################### CONSTANTS ################################## +filename = "War3.avi" + + +class MovieTypeTest( unittest.TestCase ): + def setUp(self): + pygame.display.init() + pygame.mixer.quit() + + def tearDown(self): + pygame.quit() + + def test_init(self): + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + self.assertEqual(movie, True) + + #screen = pygame.display.get_surface() + #movie = pygame.gmovie.Movie(filename, screen) + #self.assertEqual(movie, True) + + del movie + + def test_play_pause(self): + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + self.assertEqual(movie.playing, False) + + movie.play(-1) + + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + + movie.pause() + + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, True) + + movie.pause() + + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + + del movie + + def test_stop(self): + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + self.assertEqual(movie.playing, False) + movie.play(-1) + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + movie.stop() + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, False) + + del movie + + def test_rewind(self): + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + movie.play(-1) + time.sleep(2) + #equivalent to stop without a time-argument + movie.rewind() + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, False) + + del movie + + def test_width(self): + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + self.assertEqual(movie.width, 200) + + del movie + + def test_height(self): + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + self.assertEqual(movie.height, 200) + + del movie + + + def test_resize(self): + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + movie.play(-1) + movie.resize(movie.width/2, movie.height/2) + #equivalent to stop without a time-argument + + self.assertEqual(movie.height, 100) + self.assertEqual(movie.width, 100) + + del movie + + +if __name__ == '__main__': + unittest.main() +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/_vlcmovietest.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,142 @@ +#################################### IMPORTS ################################### + +from __future__ import generators + +if __name__ == '__main__': + import sys + import os + pkg_dir = os.path.split(os.path.abspath(__file__))[0] + parent_dir, pkg_name = os.path.split(pkg_dir) + is_pygame_pkg = (pkg_name == 'tests' and + os.path.split(parent_dir)[1] == 'pygame') + if not is_pygame_pkg: + sys.path.insert(0, parent_dir) +else: + is_pygame_pkg = __name__.startswith('pygame.tests.') + +if is_pygame_pkg: + from pygame.tests.test_utils import test_not_implemented, unittest, trunk_relative_path +else: + from test.test_utils import test_not_implemented, unittest + + +import pygame +import pygame._vlcbackend as gmovie +from pygame.locals import * + +import os +import sys +import time + +################################### CONSTANTS ################################## +filename = "War3.avi" + + +class MovieTypeTest( unittest.TestCase ): + def test_init(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + self.assertEqual(movie, True) + + #screen = pygame.display.get_surface() + #movie = pygame.gmovie.Movie(filename, screen) + #self.assertEqual(movie, True) + + del movie + + def test_play_pause(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + self.assertEqual(movie.playing, False) + + movie.play(-1) + + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + + movie.pause() + + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, True) + + movie.pause() + + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + + del movie + + def test_stop(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + self.assertEqual(movie.playing, False) + movie.play(-1) + self.assertEqual(movie.playing, True) + self.assertEqual(movie.paused, False) + movie.stop() + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, False) + + del movie + + def test_rewind(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + movie.play(-1) + time.sleep(2) + #equivalent to stop without a time-argument + movie.rewind() + self.assertEqual(movie.playing, False) + self.assertEqual(movie.paused, False) + + del movie + + def test_width(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + print movie.width + self.assertEqual(movie.width, 200) + + del movie + + def test_height(self): + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + print movie.height + self.assertEqual(movie.height, 200) + + del movie + + + def test_resize(self): + + pygame.display.init() + pygame.mixer.quit() + movie_file = trunk_relative_path('examples/data/blue.mpg') + movie = gmovie.Movie(movie_file) + + movie.play(-1) + movie.resize(movie.width/2, movie.height/2) + #equivalent to stop without a time-argument + + self.assertEqual(movie.height, 100) + self.assertEqual(movie.width, 100) + + del movie + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/camera_test.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,29 @@ +#################################### IMPORTS ################################### + +from __future__ import generators + +if __name__ == '__main__': + import sys + import os + pkg_dir = os.path.split(os.path.abspath(__file__))[0] + parent_dir, pkg_name = os.path.split(pkg_dir) + is_pygame_pkg = (pkg_name == 'tests' and + os.path.split(parent_dir)[1] == 'pygame') + if not is_pygame_pkg: + sys.path.insert(0, parent_dir) +else: + is_pygame_pkg = __name__.startswith('pygame.tests.') + +if is_pygame_pkg: + from pygame.tests.test_utils import test_not_implemented, unittest +else: + from test.test_utils import test_not_implemented, unittest +import pygame +from pygame.compat import long_ +import math + +#################################### Tests ##################################### + +class CameraModuleTest(unittest.TestCase): + pass +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/font_tags.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,6 @@ +__tags__ = [] + +import sys +# Font support not fully implemented for Python 3.x. +if sys.version_info >= (3, 0, 0) and sys.platform.startswith('Win'): + __tags__.extend(['ignore', 'subprocess_ignore'])
--- a/test/font_test.py Mon Nov 16 18:05:30 2009 +0000 +++ b/test/font_test.py Mon Nov 16 18:31:40 2009 +0000 @@ -45,6 +45,21 @@ self.failUnless(fnts) + # to test if some files exist... + #def XXtest_has_file_osx_10_5_sdk(self): + # import os + # f = "/Developer/SDKs/MacOSX10.5.sdk/usr/X11/include/ft2build.h" + # self.assertEqual(os.path.exists(f), True) + + #def XXtest_has_file_osx_10_4_sdk(self): + # import os + # f = "/Developer/SDKs/MacOSX10.4u.sdk/usr/X11R6/include/ft2build.h" + # self.assertEqual(os.path.exists(f), True) + + + + + def test_get_fonts(self): fnts = pygame.font.get_fonts()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/freetype_font_t_disabled_est.py Mon Nov 16 18:31:40 2009 +0000 @@ -0,0 +1,240 @@ +import sys +import os +if __name__ == '__main__': + pkg_dir = os.path.split(os.path.abspath(__file__))[0] + parent_dir, pkg_name = os.path.split(pkg_dir) + is_pygame_pkg = (pkg_name == 'tests' and + os.path.split(parent_dir)[1] == 'pygame') + if not is_pygame_pkg: + sys.path.insert(0, parent_dir) +else: + is_pygame_pkg = __name__.startswith('pygame.tests.') + +if is_pygame_pkg: + from pygame.tests.test_utils import test_not_implemented, unittest, \ + geterror +else: + from test.test_utils import test_not_implemented, unittest, geterror + +import pygame +try: + import pygame.freetype as ft +except ImportError: + ft = None + + + +FONTDIR = os.path.join(os.path.dirname (os.path.abspath (__file__)), + 'fixtures', 'fonts') + +class FreeTypeFontTest(unittest.TestCase): + + _TEST_FONTS = {} + + def setUp(self): + ft.init() + + if 'fixed' not in self._TEST_FONTS: + # Inconsolata is an open-source font designed by Raph Levien + # Licensed under the Open Font License + # http://www.levien.com/type/myfonts/inconsolata.html + self._TEST_FONTS['fixed'] = ft.Font(os.path.join (FONTDIR, 'test_fixed.otf')) + + if 'sans' not in self._TEST_FONTS: + # Liberation Sans is an open-source font designed by Steve Matteson + # Licensed under the GNU GPL + # https://fedorahosted.org/liberation-fonts/ + self._TEST_FONTS['sans'] = ft.Font(os.path.join (FONTDIR, 'test_sans.ttf')) + + def test_freetype_defaultfont(self): + font = ft.Font(None) + self.assertEqual(font.name, "FreeSans") + + def test_freetype_Font_init(self): + + self.assertRaises(RuntimeError, ft.Font, os.path.join (FONTDIR, 'nonexistant.ttf')) + + f = self._TEST_FONTS['sans'] + self.assertTrue(isinstance(f, ft.Font)) + + f = self._TEST_FONTS['fixed'] + self.assertTrue(isinstance(f, ft.Font)) + + + def test_freetype_Font_fixed_width(self): + + f = self._TEST_FONTS['sans'] + self.assertFalse(f.fixed_width) + + f = self._TEST_FONTS['fixed'] + self.assertFalse(f.fixed_width) + + def test_freetype_Font_get_metrics(self): + + font = self._TEST_FONTS['sans'] + + # test for floating point values (BBOX_EXACT) + metrics = font.get_metrics('ABCD', ptsize=24, bbmode=ft.BBOX_EXACT) + self.assertEqual(len(metrics), len('ABCD')) + self.assertTrue(isinstance(metrics, list)) + + for metrics_tuple in metrics: + self.assertTrue(isinstance(metrics_tuple, tuple)) + self.assertEqual(len(metrics_tuple), 5) + for m in metrics_tuple: + self.assertTrue(isinstance(m, float)) + + # test for integer values (BBOX_PIXEL) + metrics = font.get_metrics('foobar', ptsize=24, bbmode=ft.BBOX_PIXEL) + self.assertEqual(len(metrics), len('foobar')) + self.assertTrue(isinstance(metrics, list)) + + for metrics_tuple in metrics: + self.assertTrue(isinstance(metrics_tuple, tuple)) + self.assertEqual(len(metrics_tuple), 5) + for m in metrics_tuple: + self.assertTrue(isinstance(m, int)) + + # test for empty string + metrics = font.get_metrics('', ptsize=24) + self.assertEqual(metrics, []) + + # test for invalid string + self.assertRaises(TypeError, font.get_metrics, 24, 24) + + def test_freetype_Font_get_size(self): + + font = self._TEST_FONTS['sans'] + + def test_size(s): + self.assertTrue(isinstance(s, tuple)) + self.assertEqual(len(s), 2) + self.assertTrue(isinstance(s[0], int)) + self.assertTrue(isinstance(s[1], int)) + + size_default = font.get_size("ABCDabcd", ptsize=24) + test_size(size_default) + self.assertTrue(size_default > (0, 0)) + self.assertTrue(size_default[0] > size_default[1]) + + size_bigger = font.get_size("ABCDabcd", ptsize=32) + test_size(size_bigger) + self.assertTrue(size_bigger > size_default) + + size_bolden = font.get_size("ABCDabcd", ptsize=24, style=ft.STYLE_BOLD) + test_size(size_bolden) + self.assertTrue(size_bolden > size_default) + + font.vertical = True + size_vert = font.get_size("ABCDabcd", ptsize=24) + test_size(size_vert) + self.assertTrue(size_vert[0] < size_vert[1]) + font.vertical = False + + size_italic = font.get_size("ABCDabcd", ptsize=24, style=ft.STYLE_ITALIC) + test_size(size_italic) + self.assertTrue(size_italic[0] > size_default[0]) + self.assertTrue(size_italic[1] == size_default[1]) + + size_under = font.get_size("ABCDabcd", ptsize=24, style=ft.STYLE_UNDERLINE) + test_size(size_under) + self.assertTrue(size_under[0] == size_default[0]) + self.assertTrue(size_under[1] > size_default[1]) + + + def test_freetype_Font_height(self): + + f = self._TEST_FONTS['sans'] + self.assertEqual(f.height, 2355) + + f = self._TEST_FONTS['fixed'] + self.assertEqual(f.height, 1100) + + + def test_freetype_Font_name(self): + + f = self._TEST_FONTS['sans'] + self.assertEqual(f.name, 'Liberation Sans') + + f = self._TEST_FONTS['fixed'] + self.assertEqual(f.name, 'Inconsolata') + + + def test_freetype_Font_render(self): + + font = self._TEST_FONTS['sans'] + + surf = pygame.Surface((800, 600)) + color = pygame.Color(0, 0, 0) + + # make sure we always have a valid fg color + self.assertRaises(TypeError, font.render, None, 'FoobarBaz') + self.assertRaises(TypeError, font.render, None, 'FoobarBaz', None) + + # render to new surface + rend = font.render(None, 'FoobarBaz', pygame.Color(0, 0, 0), None, ptsize=24) + self.assertTrue(isinstance(rend, tuple)) + self.assertTrue(isinstance(rend[0], pygame.Surface)) + self.assertTrue(isinstance(rend[1], int)) + self.assertTrue(isinstance(rend[2], int)) + + # render to existing surface + rend = font.render((surf, 32, 32), 'FoobarBaz', color, None, ptsize=24) + self.assertTrue(isinstance(rend, tuple)) + self.assertTrue(isinstance(rend[0], int)) + self.assertTrue(isinstance(rend[1], int)) + + # misc parameter test + self.assertRaises(ValueError, font.render, None, 'foobar', color) + self.assertRaises(TypeError, font.render, None, 'foobar', color, "", + ptsize=24) + self.assertRaises(ValueError, font.render, None, 'foobar', color, None, + style=42, ptsize=24) + self.assertRaises(TypeError, font.render, None, 'foobar', color, None, + style=None, ptsize=24) + self.assertRaises(ValueError, font.render, None, 'foobar', color, None, + style=97, ptsize=24) + + + def test_freetype_Font_style(self): + + font = self._TEST_FONTS['sans'] + + # make sure STYLE_NORMAL is the default value + self.assertEqual(ft.STYLE_NORMAL, font.style) + + # make sure we check for style type + try: font.style = "None" + except TypeError: pass + else: self.fail("Failed style assignement") + + try: font.style = None + except TypeError: pass + else: self.fail("Failed style assignement") + + # make sure we only accept valid constants + try: font.style = 112 + except ValueError: pass + else: self.fail("Failed style assignement") + + # make assure no assignements happened + self.assertEqual(ft.STYLE_NORMAL, font.style) + + # test assignement + font.style = ft.STYLE_UNDERLINE + self.assertEqual(ft.STYLE_UNDERLINE, font.style) + + # test complex styles + st = ( ft.STYLE_BOLD | ft.STYLE_UNDERLINE | + ft.STYLE_ITALIC ) + + font.style = st + self.assertEqual(st, font.style) + + # revert changes + font.style = ft.STYLE_NORMAL + self.assertEqual(ft.STYLE_NORMAL, font.style) + + +if __name__ == '__main__': + unittest.main()
