├── CHANGES ├── .gitignore ├── MANIFEST.in ├── demo ├── Pacifico.ttf ├── gddemo.py └── Pacifico SIL OFL Font License 1.1.txt ├── MANIFEST ├── PKG-INFO ├── INSTALL ├── README ├── LICENSE ├── install_notes.html ├── gd.py ├── setup.py ├── gd-ref.html └── _gdmodule.c /CHANGES: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | build 3 | dist 4 | *.pyc 5 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.html 2 | include gddemo.py 3 | include adventure.ttf 4 | -------------------------------------------------------------------------------- /demo/Pacifico.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KBNLresearch/gdmodule/master/demo/Pacifico.ttf -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | README 2 | Setup.py 3 | _gdmodule.c 4 | adventure.ttf 5 | gd-ref.html 6 | gd.py 7 | gddemo.py 8 | install_notes.html 9 | -------------------------------------------------------------------------------- /PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: gdmodule 3 | Version: 0.54 4 | Summary: GD Package 5 | Home-page: http://newcenturycomputers.net/projects/gdmodule.html 6 | Author: Chris Gonnerman 7 | Author-email: chris.gonnerman@newcenturycomputers.net 8 | License: UNKNOWN 9 | Description: GD Package 10 | Platform: UNKNOWN 11 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | gd module install notes 2 | 3 | I'm going to assume that you've got the GD library (version 2.0.8 or 4 | higher) installed, which is pretty trivial to do. If you're having 5 | troubles with that, I suggest you have a look at that package's 6 | instructions. 7 | 8 | This version of gdmodule is written assuming you have PNG, JPEG, FreeType, 9 | and Xpm libraries incorporated into your copy of GD. If you have an 10 | incomplete version you will have difficulty getting this one to build. 11 | 12 | Starting with gdmodule 0.30 the installation is done via the standard 13 | Distutils. Do this (as root if necessary): 14 | 15 | python Setup.py install 16 | 17 | This should build the _gd.so extension and install it along with the gd.py 18 | module in the standard location on your system. 19 | 20 | As of right now, I don't have a build for Windows. If I get time I might 21 | put one together. 22 | 23 | -------------------------------------------------------------------------------- /demo/gddemo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import gd, os, cStringIO, urllib2 4 | 5 | os.environ["GDFONTPATH"] = "." 6 | 7 | FONT = "Pacifico" 8 | 9 | def simple(): 10 | im = gd.image((200, 200)) 11 | 12 | white = im.colorAllocate((255, 255, 255)) 13 | black = im.colorAllocate((0, 0, 0)) 14 | red = im.colorAllocate((255, 0, 0)) 15 | blue = im.colorAllocate((0, 0, 255)) 16 | 17 | im.colorTransparent(white) 18 | im.interlace(1) 19 | 20 | im.rectangle((0,0),(199,199),black) 21 | im.arc((100,100),(195,175),0,360,blue) 22 | im.fill((100,100),red) 23 | 24 | print im.get_bounding_rect(FONT, 12.0, 0.0, (10, 100), "Hello Python") 25 | 26 | im.string_ttf(FONT, 20.0, 0.0, (10, 100), "Hello Python", black) 27 | 28 | f=open("xx.png","w") 29 | im.writePng(f) 30 | f.close() 31 | 32 | f=open("xx.jpg", "w") 33 | im.writeJpeg(f,100) 34 | f.close() 35 | 36 | f=cStringIO.StringIO() 37 | im.writePng(f) 38 | print "PNG size:", len(f.getvalue()) 39 | f.close() 40 | 41 | f = urllib2.urlopen("http://www.gnu.org/graphics/gnu-head-sm.jpg") 42 | im = gd.image(f, "jpg") 43 | f.close() 44 | print "GNU Image Size:", im.size() 45 | 46 | simple() 47 | 48 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Python GD Module README 2 | 3 | -------------------------------------------------------------------------- 4 | This module is 5 | 6 | Copyright 1995 Richard Jones 7 | Bureau of Meteorology Australia. 8 | richard@bofh.asn.au 9 | 10 | With Richard's blessing, I have taken over support for this module; 11 | so, send all bug reports, etc. to chris.gonnerman@newcenturycomputers.net 12 | -------------------------------------------------------------------------- 13 | 14 | GD module is an interface to the GD library written by Thomas Boutell. 15 | 16 | gd is a graphics library. It allows your code to quickly draw images 17 | complete with lines, arcs, text, multiple colors, cut and paste from 18 | other images, and flood fills, and write out the result as a PNG or 19 | JPEG file. This is particularly useful in World Wide Web applications, 20 | where PNG and JPEG are two of the formats accepted for inline images 21 | by most browsers. 22 | 23 | The GD library must be version 2.0.23 or higher (or you must choose an 24 | earlier version of this module). 25 | 26 | The official home page of GD is currently: 27 | 28 | http://www.boutell.com/gd/ 29 | 30 | gdmodule has been extended in some ways from the original GD library. 31 | 32 | -------------------------------------------------------------------------- 33 | 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | gdmodule - Python GD module 2 | Copyright (c) 1995 Richard Jones 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. Redistributions in 10 | * binary form must reproduce the above copyright notice, this list of 11 | * conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. Neither the name of the Bureau 13 | * of Meteorology Australia nor the names of its contributors may be used to 14 | * endorse or promote products derived from this software without specific 15 | * prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | -------------------------------------------------------------------------------- /install_notes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | gd module install notes 5 | 9 | 10 | 11 | 12 |

gd module install notes

13 | 14 |

15 | I'm going to assume that you've got the GD library installed, which is 16 | pretty trivial to do. If you're having troubles with that, I suggest 17 | you have a look at that package's instructions. 18 | 19 |

20 | Starting with version 0.40 of gdmodule, the Setup.py script tries rather hard to 21 | identify installed libraries. Assuming you have GD installed normally, with 22 | development versions of all the libraries it uses, you are in good shape. If 23 | you have build problems or runtime errors mentioning unknown functions, you 24 | probably either (a) don't have all the supporting libraries installed as 25 | development versions, or (b) have libraries installed that weren't used to build 26 | GD! 27 | 28 |

29 | Libraries looked for are: X11, Xpm, png, z, jpeg, ttf, and/or freetype. If both 30 | libttf and libfreetype are found, the libfreetype wins. If either libpng or 31 | libz are missing, png support is not built; likewise for Xpm and X11. 32 | 33 |

34 | Installation is done via the standard Distutils. Do this (as root if necessary): 35 | 36 |

37 | python Setup.py install 38 |
39 | 40 |

41 | This should build the _gd.so extension and install it along with the gd.py 42 | module in the standard location on your system. 43 | 44 |

45 | If you have had a previous version of gdmodule installed, in particular one 46 | which creates a monolithic gdmodule.so or gd.so, please remove it before 47 | building this one. 48 | 49 |

50 | As of right now, I don't have a build for Windows. If I get time I might 51 | put one together... don't hold your breath. (If someone wants to build one for 52 | me I wouldn't cry about it...) 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /gd.py: -------------------------------------------------------------------------------- 1 | """ 2 | GD module is an interface to the GD library written by Thomas Bouttel. It 3 | allows your code to quickly draw images complete with lines, arcs, text, 4 | multiple colors, cut and paste from other images, and flood fills, and 5 | write out the result as a .GIF, .PNG, .JPEG, or .WBMP file. This is 6 | particularly useful in World Wide Web applications, where .JPEG is 7 | universally supported and PNG is the up-and-coming format used for inline 8 | images. It has been extended in some ways from the original GD library. 9 | """ 10 | 11 | import _gd 12 | from _gd import * 13 | del image 14 | 15 | # proxy the _gd.image type as a class so we can override it. 16 | 17 | class image: 18 | 19 | def __init__(self, *args): 20 | if isinstance(args[0], image): 21 | args = list(args) 22 | args[0] = args[0]._image 23 | self.__dict__["_image"] = _gd.image(*args) 24 | 25 | def __getattr__(self, name): 26 | return getattr(self._image, name) 27 | 28 | def __setattr__(self, name, value): 29 | return setattr(self._image, name, value) 30 | 31 | def lines(self, points, color): 32 | "draw a line along the sequence of points in the list or tuple using color" 33 | prev = tuple(points[0]) 34 | for p in points[1:]: 35 | p = tuple(p) 36 | self._image.line(prev, p, color) 37 | prev = p 38 | 39 | def copyTo(self, im, *args): 40 | return self._image.copyTo(im._image, *args) 41 | 42 | def copyResizedTo(self, im, *args): 43 | return self._image.copyResizedTo(im._image, *args) 44 | 45 | def copyResampledTo(self, im, *args): 46 | return self._image.copyResampledTo(im._image, *args) 47 | 48 | def copyMergeTo(self, im, *args): 49 | return self._image.copyMergeTo(im._image, *args) 50 | 51 | def copyMergeGrayTo(self, im, *args): 52 | return self._image.copyMergeGrayTo(im._image, *args) 53 | 54 | def copyPaletteTo(self, im, *args): 55 | return self._image.copyPaletteTo(im._image, *args) 56 | 57 | def compare(self, im, *args): 58 | return self._image.compare(im._image, *args) 59 | 60 | def setBrush(self, im, *args): 61 | return self._image.setBrush(im._image, *args) 62 | 63 | def setTile(self, im, *args): 64 | return self._image.setTile(im._image, *args) 65 | 66 | # end of file. 67 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Setup for gdmodule 0.50 and later 2 | 3 | from distutils.core import setup, Extension 4 | import os, glob, sys, string, commands 5 | 6 | # version of this gdmodule package 7 | this_version = "0.59" 8 | 9 | # directory existence tester 10 | 11 | def dirtest(lst): 12 | rlst = [] 13 | for d in lst: 14 | try: 15 | if os.listdir(d): 16 | rlst.append(d) 17 | except: 18 | pass 19 | return rlst 20 | 21 | def filetest(path, names): 22 | rlst = [] 23 | for d in path: 24 | for i in range(len(names)): 25 | found = glob.glob(os.path.join(d, "lib%s.*" % names[i])) 26 | if found: 27 | rlst.append(names[i]) 28 | names[i] = None 29 | names = filter(None, names) 30 | return rlst 31 | 32 | def remove(itm, lst): 33 | r = range(len(lst)) 34 | r.reverse() 35 | for i in r: 36 | if lst[i] == itm: 37 | del lst[i] 38 | 39 | # library_dirs option is rather non-portable, but since I am targetting 40 | # Unixoid OS's I will just look for the usual suspects. 41 | 42 | libdirs = dirtest([ 43 | "/usr/local/lib", "/sw/lib", "/usr/lib", 44 | "/usr/lib/i386-linux-gnu", "/usr/lib/x86_64-linux-gnu", 45 | "/usr/lib/X11", "/usr/X11R6/lib", 46 | "/opt/gnome/lib", 47 | ]) 48 | 49 | try: 50 | exotic_libdir = commands.getoutput("gdlib-config --libdir"), 51 | libdirs += exotic_libdir 52 | except: 53 | pass 54 | 55 | # include_dirs are also non-portable; same trick here. 56 | 57 | incdirs = dirtest([ 58 | "/usr/local/include", "/sw/include", "/usr/include", 59 | "/usr/include/X11", "/usr/X11R6/include", 60 | "/opt/gnome/include", 61 | ]) 62 | 63 | try: 64 | exotic_incdir = commands.getoutput("gdlib-config --includedir"), 65 | incdirs += exotic_incdir 66 | except: 67 | pass 68 | 69 | # Try to identify our libraries 70 | 71 | want_libs = [ 72 | "gd", 73 | "jpeg", "png", "gif", 74 | "X11", "Xpm", 75 | "z", "ttf", "freetype", 76 | ] 77 | 78 | libs = filetest(libdirs, want_libs) 79 | 80 | missing = [] 81 | 82 | for l in want_libs: 83 | if l and l not in libs: 84 | missing.append(l) 85 | 86 | if "ttf" in missing and "freetype" not in missing: 87 | remove("ttf", missing) 88 | 89 | if missing: 90 | print "WARNING: Missing", string.join(missing, ", "), "Libraries" 91 | 92 | # hand-clean the libs 93 | 94 | if "gd" not in libs: 95 | print "Can't find GD library." 96 | sys.exit(0) 97 | 98 | if "ttf" in libs and "freetype" in libs: 99 | remove("ttf", libs) 100 | 101 | if "Xpm" in libs and "X11" not in libs: 102 | remove("Xpm", libs) 103 | 104 | if "png" in libs and "z" not in libs: 105 | remove("png", libs) 106 | 107 | if "z" in libs and "png" not in libs: 108 | remove("png", libs) 109 | 110 | # build the macro list 111 | 112 | macros = [] 113 | 114 | for l in libs: 115 | macros.append(( "HAVE_LIB%s" % l.upper(), None )) 116 | 117 | # OK, now do it! 118 | 119 | setup(name="gdmodule", version=this_version, 120 | 121 | description="GD Package", 122 | long_description="GD Package", 123 | author="Chris Gonnerman", 124 | author_email="chris.gonnerman@newcenturycomputers.net", 125 | 126 | url="http://newcenturycomputers.net/projects/gdmodule.html", 127 | py_modules=["gd"], 128 | ext_modules=[ 129 | Extension("_gd", ["_gdmodule.c"], 130 | include_dirs=incdirs, library_dirs=libdirs, 131 | libraries=libs, define_macros=macros)], 132 | ) 133 | 134 | # end of file. 135 | -------------------------------------------------------------------------------- /demo/Pacifico SIL OFL Font License 1.1.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011, Vernon Adams (vern@newtypography.co.uk), 2 | with Reserved Font Name Pacifico. 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /gd-ref.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Python GD Module Reference 5 | 9 | 10 | 11 | 12 |

Python GD Module Reference

13 | 14 |

Description

15 | 16 | GD module is an interface to the GD library written by Thomas 18 | Boutell. 19 | 20 |
21 | 'gd is a graphics library. It allows your code to quickly draw images complete 22 | with lines, arcs, text, multiple colors, cut and paste from other images, and 23 | flood fills, and write out the result as a PNG or JPEG file. This is 24 | particularly useful in World Wide Web applications, where PNG and JPEG are two 25 | of the formats accepted for inline images by most browsers.' 26 |
27 | 28 | It has been extended in some ways from the original GD library. 29 | 30 |

31 | This documentation is slightly out of date. In particular, the patch by 32 | Mike Romberg adds a lot of methods to the image object, which may not be fully 33 | documented here. Use the Source, Luke. 34 | 35 |

Constants

36 | 37 |
38 |
gdFontGiant, gdFontLarge, gdFontMediumBold, gdFontSmall, 39 | gdFontTiny
40 | 41 |
Fonts for use with the string() and stringUp() methods.
42 | 43 |
gdMaxColors(256)
44 | 45 |
Maximum number of colors in an image; GD will likely change this 46 | figure in a future version.
47 | 48 |
gdStyled, gdStyledBrushed, gdBrushed
49 | 50 |
Draw mode for line() and lines() method.
51 | 52 |
gdTiled
53 | 54 |
Fill mode for fill(), fillToBorder()
55 | 56 |
gdTransparent, gdStyledBrushed
57 | 58 |
Special entries for setStyle()
59 |
60 | 61 |

Image Object

62 | 63 |
64 |
image(image[,(w,h)] | 65 | file | file,type | 66 | (w,h))
67 | 68 |
create GD image from 69 | 79 |
80 |
81 | 82 |

Image Object Methods

83 | 84 |
85 |
writePng(f)
86 | 87 |
write the image to f as a PNG, where f is 88 | either an open file-like object or a file name.
89 | 90 |
writeJpeg(f, [ q ])
91 | 92 |
write the image to f as a JPEG file, where f is 93 | either an open file-like object or a file name, and q is the 94 | quality value as an integer from 0 to 100. If q is 0 or 95 | omitted, a default is used.
96 | 97 |
writeGd(f)
98 | 99 |
write the image to f as a GD file, where f is 100 | either an open file-like object or a file name.
101 | 102 |
writeGd2(f, [ c, [ fmt ] ])
103 | 104 |
write the image to f as a GD2 file, where f is 105 | either an open file-like object or a file name, c is the chunksize and fmt is 106 | the format. See the GD 1.8.3 or later documentation for an explanation. 107 | Defaults will be supplied if omitted.
108 | 109 |
writeWbmp(f, [ fg ])
110 | 111 |
write the image to f as a WBMP file, where f is 112 | either an open file-like object or a file name, and fg is the 113 | index of the color to "set" in the result image (see the GD 1.8.3 or 114 | later documentation for details). fg defaults to 0 if omitted.
115 | 116 |
117 |
118 | All of the above write methods accept either a filename, file 119 | object or a python object with a write() method. Use a StringIO 120 | object if you want to get the image data without writing it to 121 | a file (useful for web scripts that return generated images to 122 | the client). 123 |
  124 |
125 | 126 |
setPixel((x,y), 127 | color)
128 | 129 |
set the pixel at (x,y) to color
130 | 131 |
line((x1,y1), 132 | (x2,y2), color)
133 | 134 |
draw a line from (x1,y1) to 135 | (x2,y2) in color
136 | 137 |
lines(((x1,y1), 138 | (x2,y2), ..., (xn, yn)), 139 | color)
140 | 141 |
draw a line along the sequence of points in the list or tuple 142 | using color
143 | 144 |
polygon(((x1,y1), 145 | (x2,y2), ..., (xn, yn)), 146 | color[, fillcolor])
147 | 148 |
draw a polygon using the list or tuple of points (minimum 3) in 149 | color, optionally filled with fillcolor
150 | 151 |
rectangle((x1,y1), 152 | (x2,y2), color[, 153 | fillcolor])
154 | 155 |
draw a rectangle with upper corner (x1,y1), 156 | lower corner (x2,y2) in color, 157 | optionally filled with fillcolor
158 | 159 |
filledPolygon(((x1,y1), 160 | (x2,y2), ..., (xn, yn)), 161 | color)
162 | 163 |
draw a filled polygon using the list or tuple of points 164 | (minimum 3) in color
165 | 166 |
filledRectangle((x1,y1), 167 | (x2,y2), color)
168 | 169 |
draw a rectangle with upper corner (x1,y1), 170 | lower corner (x2,y2) in color
171 | 172 |
arc((x,y), 173 | (w,h), start, end, 174 | color)
175 | 176 |
draw an ellipse centered at (x,y) with width 177 | w, height h from start degrees to 178 | end degrees in color.
179 | 180 |
fillToBorder((x,y), 181 | border, color)
182 | 183 |
flood from point (x,y) to border 184 | color in color
185 | 186 |
fill((x,y), color)
187 | 188 |
flood from point (x,y) in color for 189 | those pixels with the same color as the starting point
190 | 191 |
setBrush(image)
192 | 193 |
set the drawing brush to image (use 194 | gdBrushed when drawing)
195 | 196 |
setTile(image)
197 | 198 |
set the fill tile to image (use 199 | gdTiled when filling)
200 | 201 |
setStyle(tuple|list)
202 | 203 |
set the line bit-style to tuple or list of 204 | colors (use gdStyled when drawing)
205 | 206 |
getPixel((x,y))
207 | 208 |
color index of image at (x,y)
209 | 210 |
boundsSafe((x,y))
211 | 212 |
returns true if (x,y) is within image
213 | 214 |
size()
215 | 216 |
return the 2-tuple size of image
217 | 218 |
string(font, (x,y), 219 | s, color)
220 | 221 |
draw string s at (x,y) using one of 222 | the pre-defined gdmodule fonts
223 | 224 |
stringUp(font, (x,y), 225 | s, color)
226 | 227 |
vertically draw string s at (x,y) 228 | using one of the pre-defined gdmodule fonts
229 | 230 |
get_bounding_rect(font, 231 | pointsize, angle, 232 | (x,y), s)
233 | 234 |
Get bounding rect of string s using the TrueType font 235 | at the given pointsize and angle. 236 | Returns 237 | the bounding box of the given text as an eight-tuple: lower left X, 238 | lower left Y, lower right X, lower right Y, upper right X, 239 | upper right Y, upper left X, upper left Y. 240 | 241 |
string_ttf(font, pointsize, angle, 242 | (x,y), s, color)
243 | 244 |
draw string s at (x,y) using 245 | the TrueType font at the given pointsize and angle. 246 | Returns 247 | the bounding box of the given text as an eight-tuple: lower left X, 248 | lower left Y, lower right X, lower right Y, upper right X, 249 | upper right Y, upper left X, upper left Y. 250 | 251 |
252 | 253 |
string_ft(font, pointsize, angle, 254 | (x,y), s, color)
255 | 256 |
257 | Functional equivalent of string_ttf, which may be deprecated. 258 |
259 | 260 |
261 | colorAllocate((r,g,b))
262 | 263 |
allocate a color index to (r,g,b) 264 | (returns -1 if unable to)
265 | 266 |
267 | colorClosest((r,g,b))
268 | 269 |
return the color index closest to 270 | (r,g,b) (returns -1 if unable to)
271 | 272 |
273 | colorExact((r,g,b))
274 | 275 |
return an exact color index match for 276 | (r,g,b) (returns -1 if unable to)
277 | 278 |
colorsTotal()
279 | 280 |
returns the number of colors currently allocated
281 | 282 |
colorComponents(color)
283 | 284 |
returns a 3-tulple of the (r,g,b) components of color
285 | 286 |
getInterlaced()
287 | 288 |
returns true if the image is interlaced
289 | 290 |
getTransparent()
291 | 292 |
returns transparent color index or -1
293 | 294 |
colorDeallocate(color)
295 | 296 |
deallocate color from the image palette
297 | 298 |
colorTransparent(color)
299 | 300 |
set the transparent color to color
301 | 302 |
copyTo(image[, (dx,dy)[, (sx,sy)[, (w,h)]]])
303 | 304 |
copy from (sx,sy), width sw and 305 | height sh to destination image 306 | (dx,dy)
307 | 308 |
copyResizedTo(image[, 309 | (dx,dy)[, (sx,sy)[, 310 | (dw,dh)[, (sw,sh)]]]])
311 | 312 |
copy from (sx,sy), width sw and 313 | height sh to destination image 314 | (dx,dy), width dw and height 315 | dh
316 | 317 |
interlace()
318 | 319 |
set the interlace bit
320 | 321 |
322 | origin((x,y)[,xmult,ymult])
323 | 324 |
set the origin of the image to (x,y) and 325 | multiply all x, y, width and height factors by xmult and 326 | ymult (typically either 1 or -1)
327 | 328 |
getOrigin()
329 | 330 |
returns the origin parameters ((x,y),xmult,ymult)
331 |
332 | 333 |

Other Module-level functions

334 | 335 |
336 |
fontstrsize(font, string)
337 | 338 |
return a tuple containing the size in pixels of the given 339 | string in the given font
340 |
341 | 342 |
343 | 344 | Copyright © 1995 Richard Jones, Bureau of Meteorology Australia.
345 | richard@bofh.asn.au 346 | 347 |

348 | With Richard's blessing, I have taken over support for this module; 349 | so, send all bug reports, etc. to 350 | 351 | chris.gonnerman@newcenturycomputers.net 352 | 353 |

354 | 355 | This module is a python wrapper for the GD library (version 1.1.1 and later) 356 | 357 |

358 | From the GD docs:
359 | "COPYRIGHT 1994 BY THE QUEST CENTER AT COLD SPRING HARBOR LABS.
360 | Permission granted for unlimited use, provided that 361 | the Quest Center at Cold Spring Harbor Labs is given 362 | credit for the library in the user-visible documentation of 363 | your software. If you modify gd, we ask that you share the 364 | modifications with us so they can be added to the 365 | distribution. See gd.html for details. 366 | 367 |

368 | 369 | 370 | 371 |

531 | 532 | 533 | 534 | 535 | 536 | 537 | -------------------------------------------------------------------------------- /_gdmodule.c: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | Copyright 1995 Richard Jones, Bureau of Meteorology Australia. 3 | richard@bofh.asn.au 4 | 5 | Current maintainer is 6 | Chris Gonnerman 7 | Please direct all questions and problems to me. 8 | 9 | This module is a python wrapper for the GD library (version 1.8.3) 10 | 11 | version 0.56 12 | Revised 03/10/2005 by Chris Gonnerman 13 | -- added support for GIF files. 14 | -- the minimum gd library version for this gdmodule version is 15 | 2.0.23. 16 | 17 | version 0.55 18 | Revised 03/10/2005 by Chris Gonnerman 19 | -- corrected error in the gd.image() constructor, pointed out 20 | by Betty Li. maybe this time I got it right. 21 | -- the minimum gd library version for this gdmodule version is 22 | 2.0.22. 23 | 24 | version 0.54 25 | Revised 03/03/2005 by Chris Gonnerman 26 | -- corrected error in the gd.image() constructor, pointed out 27 | by Betty Li. 28 | -- corrected yet another obvious error reported by Greg Hewgill, 29 | regarding an incorrect call to gdImagePolygon when fillcolor 30 | is not equal to 1. 31 | -- implemented the saveAlpha and alphaBlending features as 32 | suggested by Christopher Stone. 33 | -- fixed memory management issue regarding image deallocation 34 | reported by Matti Jagula. 35 | -- fixed memory management issue in image_filledpolygon 36 | reported by Sadruddin Rejeb. 37 | -- the minimum gd library version for this gdmodule version is 38 | 2.0.22. 39 | 40 | version 0.53 41 | Revised 06/10/2004 by Chris Gonnerman 42 | -- corrected obvious error in image_settile(), as pointed out 43 | by Dan Mosedale 44 | -- applied some patches provided by John Hunter. Several are 45 | for Windows compatibility, but this should be considered 46 | a "work in progress" in this version. 47 | -- corrected another obvious error (and an ancient one too) 48 | reported by Greg Hewgill, regarding the foreground color 49 | being used rather than the fill color in the image_polygon 50 | function. 51 | -- the minimum gd library version for this gdmodule version is 52 | 2.0.22. 53 | 54 | version 0.52 55 | Revised 02/03/2004 by Chris Gonnerman 56 | -- incorporated new functions from the matplotlib project 57 | (provided by John Hunter) 58 | -- corrected error in PyObject_HEAD_INIT() call noted by 59 | Stefan R Kuzminski (thanks!) 60 | 61 | version 0.51 62 | Revised 09/24/2003 by Chris Gonnerman 63 | -- fixed memory management bug reported by Jack Diederich. 64 | 65 | version 0.50 66 | Revised 09/13/2003 by Chris Gonnerman 67 | -- documentation change only: the GD library must be version 68 | 2.0.8 or higher (or you must choose version 0.40 or earlier 69 | of this module, which supports GD 1.8.3 or higher). 70 | 71 | version 0.42 72 | Revised 06/10/2003 by Chris Gonnerman 73 | -- implemented patch by Gregory P. Smith to support writing to 74 | arbitrary objects, superceding the patch in 0.41 from 75 | Andreas Rottman. gddemo.py contains Rottman's example 76 | (which works with Smith's patched version) as well as an 77 | example (by me) of reading an image from a URL. The 78 | documentation was updated to reflect these changes. 79 | 80 | version 0.41 81 | Revised 05/29/2003 by Chris Gonnerman 82 | -- implemented big patch by Andreas Rottmann to support writing 83 | images to memory via StringIO/CStringIO. Currently the only 84 | documentation is an example in gddemo.py. 85 | -- implemented patch by Bob Galloway to remove the "specialness" 86 | of negative coordinates in the string_ttf/string_ft methods. 87 | -- implemented patch by Nathan Robertson to enable MacOSX fink 88 | builds. 89 | -- fixed bugs in the proxy class with regard to passing of 90 | _gd.image types. 91 | 92 | version 0.40 93 | Revised 09/18/2002 by Chris Gonnerman 94 | -- updated to deal with incomplete library installs 95 | 96 | version 0.30 97 | Revised 06/12/2002 by Chris Gonnerman 98 | -- initial conversion to two-tier design 99 | 100 | version 0.26 101 | Revised 12/10/2001 by Chris Gonnerman 102 | -- made unicode optional via define Py_UNICODEOBJECT_H 103 | 104 | version 0.25 105 | Revised 09/15/2001 by Chris Gonnerman 106 | -- implemented patch by Mike Romberg: 107 | adds additional public functions, available 108 | only if GD 2.0.1+ is installed. 109 | 110 | version 0.24 111 | Revised 08/08/2001 by Chris Gonnerman 112 | -- implemented patch by Mike Romberg: 113 | supports GCC 3.0 and GD 2.0.1 114 | adds public C function makeGDImage() 115 | It allows C or C++ code which uses the gd library 116 | directly to make an imageobject instance. 117 | 118 | version 0.23 119 | Revised 11/22/2000 by Chris Gonnerman 120 | -- included the patch from Tanimoto Osamu 121 | -- updated support to GD version 1.8.3 122 | -- cleaned up code, added ANSI prototypes 123 | 124 | ******************************************************************/ 125 | 126 | #include 127 | #include 128 | #include 129 | #include 130 | #include 131 | #include 132 | #include 133 | #include 134 | #include 135 | 136 | #ifdef HAVE_LIBTTF 137 | #define HAVE_LIBFREETYPE 138 | #endif 139 | 140 | /* missing from gd.h */ 141 | /* gdImagePtr gdImageCreateFromXpm(char *filename); */ 142 | 143 | #ifdef WIN32 144 | #define DLLEXPORT __declspec(dllexport) 145 | #else 146 | #define DLLEXPORT 147 | #endif 148 | 149 | 150 | 151 | static PyObject *ErrorObject; 152 | 153 | /* 154 | ** Declarations for objects of type image 155 | */ 156 | 157 | typedef struct i_o { 158 | PyObject_HEAD 159 | gdImagePtr imagedata; 160 | int multiplier_x,origin_x; 161 | int multiplier_y,origin_y; 162 | struct i_o *current_brush; 163 | struct i_o *current_tile; 164 | } imageobject; 165 | 166 | 167 | // 2.0.22 replaces gdFontTinyRep with gdFontGetTiny, and so on 168 | typedef gdFontPtr (*ptrGetFontFunction)(); 169 | typedef struct { 170 | char *name; 171 | ptrGetFontFunction func; 172 | } fontstruct; 173 | 174 | static fontstruct fonts[] = { 175 | {"gdFontTiny",&gdFontGetTiny}, 176 | {"gdFontSmall",&gdFontGetSmall}, 177 | {"gdFontMediumBold",&gdFontGetMediumBold}, 178 | {"gdFontLarge",&gdFontGetLarge}, 179 | {"gdFontGiant",&gdFontGetGiant}, 180 | {NULL,NULL} 181 | }; 182 | 183 | staticforward PyTypeObject Imagetype; 184 | 185 | #define is_imageobject(v) ((v)->ob_type == &Imagetype) 186 | 187 | #define MIN(x,y) ((x)<(y)?(x):(y)) 188 | #define X(x) ((x)*self->multiplier_x+self->origin_x) 189 | #define Y(y) ((y)*self->multiplier_y+self->origin_y) 190 | #define W(x) ((x)*self->multiplier_x) 191 | #define H(y) ((y)*self->multiplier_y) 192 | 193 | static imageobject *newimageobject(PyObject *args); 194 | 195 | /* 196 | ** Support Functions 197 | */ 198 | 199 | static PyObject *write_file(imageobject *img, PyObject *args, char fmt) 200 | { 201 | char *filename; 202 | PyObject *fileobj; 203 | FILE *fp = NULL; 204 | int closeme = 0, use_fileobj_write = 0; 205 | int arg1 = -1, arg2 = -1; 206 | int filesize = 0; 207 | void *filedata = NULL; 208 | 209 | if(PyArg_ParseTuple(args, "O!|ii", &PyFile_Type, &fileobj, &arg1, &arg2)) { 210 | fp = PyFile_AsFile(fileobj); 211 | } else if(PyErr_Clear(), PyArg_ParseTuple(args, "z|ii", &filename, &arg1, &arg2)) { 212 | if((fp = fopen(filename, "wb"))) { 213 | closeme = 1; 214 | } else { 215 | PyErr_SetFromErrno(PyExc_IOError); 216 | return NULL; 217 | } 218 | } else if (PyErr_Clear(), PyArg_ParseTuple(args, "O|ii", &fileobj, &arg1, &arg2)) { 219 | /* if we're passed a random object that has a write method we will 220 | * attempt to call object.write(filedata) */ 221 | if (!PyObject_HasAttrString(fileobj, "write")) { 222 | PyErr_SetString(ErrorObject, "first argument must be a file, string or object with a write method"); 223 | return NULL; 224 | } 225 | use_fileobj_write = 1; 226 | } 227 | else 228 | return NULL; 229 | 230 | switch(fmt) { 231 | case 'f' : /* gif */ 232 | #ifdef HAVE_LIBGIF 233 | if (use_fileobj_write) { 234 | filedata = gdImageGifPtr(img->imagedata, &filesize); 235 | } else { 236 | gdImageGif(img->imagedata, fp); 237 | } 238 | #else 239 | PyErr_SetString(PyExc_NotImplementedError, 240 | "GIF Support Not Available"); 241 | return NULL; 242 | #endif 243 | break; 244 | case 'p' : /* png */ 245 | #ifdef HAVE_LIBPNG 246 | if (use_fileobj_write) { 247 | filedata = gdImagePngPtr(img->imagedata, &filesize); 248 | } else { 249 | gdImagePng(img->imagedata, fp); 250 | } 251 | #else 252 | PyErr_SetString(PyExc_NotImplementedError, 253 | "PNG Support Not Available"); 254 | return NULL; 255 | #endif 256 | break; 257 | case 'j' : /* jpeg */ 258 | #ifdef HAVE_LIBJPEG 259 | if (use_fileobj_write) { 260 | filedata = gdImageJpegPtr(img->imagedata, &filesize, arg1); 261 | } else { 262 | gdImageJpeg(img->imagedata, fp, arg1); 263 | } 264 | #else 265 | PyErr_SetString(PyExc_NotImplementedError, 266 | "JPEG Support Not Available"); 267 | return NULL; 268 | #endif 269 | break; 270 | case 'g' : /* gd */ 271 | if (use_fileobj_write) { 272 | filedata = gdImageGdPtr(img->imagedata, &filesize); 273 | } else { 274 | gdImageGd(img->imagedata, fp); 275 | } 276 | break; 277 | case 'G' : /* gd2 */ 278 | if(arg1 == -1) arg1 = 0; 279 | if(arg2 != GD2_FMT_RAW && arg2 != GD2_FMT_COMPRESSED) 280 | arg2 = GD2_FMT_COMPRESSED; 281 | if (use_fileobj_write) { 282 | filedata = gdImageGd2Ptr(img->imagedata, arg1, arg2, &filesize); 283 | } else { 284 | gdImageGd2(img->imagedata, fp, arg1, arg2); 285 | } 286 | break; 287 | case 'w' : /* wbmp */ 288 | if(arg1 == -1) 289 | arg1 = 0; 290 | if (use_fileobj_write) { 291 | //filedata = gdImageWBMPPtr(img->imagedata, &filesize, arg1); 292 | } else { 293 | gdImageWBMP(img->imagedata, arg1, fp); 294 | } 295 | break; 296 | } 297 | 298 | if (use_fileobj_write || filedata) { 299 | PyObject *noerr; 300 | noerr = PyObject_CallMethod(fileobj, "write", "s#", filedata, filesize); 301 | gdFree(filedata); 302 | if (noerr == NULL) 303 | return NULL; 304 | } else if (closeme) { 305 | fclose(fp); 306 | } 307 | 308 | Py_INCREF(Py_None); 309 | return Py_None; 310 | } 311 | 312 | /* 313 | ** Methods for the image type 314 | */ 315 | 316 | imageobject *makeGDImage(gdImagePtr imagedata) 317 | { 318 | gdImagePtr newimg = gdImageCreate(gdImageSX(imagedata), 319 | gdImageSY(imagedata)); 320 | imageobject *rval = 0; 321 | gdImageCopy(newimg, imagedata, 0, 0, 0, 0, gdImageSX(imagedata), 322 | gdImageSY(imagedata)); 323 | 324 | if (!(rval = PyObject_NEW(imageobject, &Imagetype))) 325 | return NULL; 326 | 327 | rval->current_tile = rval->current_brush = NULL; 328 | rval->origin_x = rval->origin_y = 0; 329 | rval->multiplier_x = rval->multiplier_y = 1; 330 | rval->imagedata = newimg; 331 | return rval; 332 | } 333 | 334 | 335 | /*** I/O Methods ***/ 336 | 337 | static PyObject *image_writegif(imageobject *self, PyObject *args) 338 | { 339 | return write_file(self, args, 'f'); 340 | } 341 | 342 | 343 | static PyObject *image_writepng(imageobject *self, PyObject *args) 344 | { 345 | return write_file(self, args, 'p'); 346 | } 347 | 348 | 349 | static PyObject *image_writejpeg(imageobject *self, PyObject *args) 350 | { 351 | return write_file(self, args, 'j'); 352 | } 353 | 354 | 355 | static PyObject *image_writegd(imageobject *self, PyObject *args) 356 | { 357 | return write_file(self, args, 'g'); 358 | } 359 | 360 | 361 | static PyObject *image_writegd2(imageobject *self, PyObject *args) 362 | { 363 | return write_file(self, args, 'G'); 364 | } 365 | 366 | 367 | static PyObject *image_writewbmp(imageobject *self, PyObject *args) 368 | { 369 | return write_file(self, args, 'w'); 370 | } 371 | 372 | 373 | /*** Drawing Methods ***/ 374 | 375 | static PyObject *image_setpixel(imageobject *self, PyObject *args) 376 | { 377 | int x,y,color; 378 | 379 | if(!PyArg_ParseTuple(args, "(ii)i", &x, &y, &color)) 380 | return NULL; 381 | 382 | gdImageSetPixel(self->imagedata, X(x), Y(y), color); 383 | 384 | Py_INCREF(Py_None); 385 | return Py_None; 386 | } 387 | 388 | 389 | static PyObject *image_line(imageobject *self, PyObject *args) 390 | { 391 | int sx,sy,ex,ey,color; 392 | 393 | if(!PyArg_ParseTuple(args, "(ii)(ii)i", &sx, &sy, &ex, &ey, &color)) 394 | return NULL; 395 | gdImageLine(self->imagedata, X(sx), Y(sy), X(ex), Y(ey), color); 396 | 397 | Py_INCREF(Py_None); 398 | return Py_None; 399 | } 400 | 401 | static PyObject *image_lines(imageobject *self, PyObject *args) 402 | { 403 | int color,i,N; 404 | long sx,sy,ex,ey; 405 | PyObject *seq; 406 | PyObject *lastTup, *thisTup; 407 | 408 | if(!PyArg_ParseTuple(args, "Oi", &seq, &color)) 409 | return NULL; 410 | 411 | seq = PySequence_Fast(seq, NULL); 412 | N = PySequence_Length(seq); 413 | if (N<2) { 414 | PyErr_SetString(PyExc_ValueError, 415 | "lines() requires sequence of len(2) or greater"); 416 | return NULL; 417 | } 418 | 419 | lastTup = PySequence_GetItem(seq, 0); 420 | sx = X(PyInt_AsLong(PySequence_GetItem(lastTup, 0))); 421 | sy = Y(PyInt_AsLong(PySequence_GetItem(lastTup, 1))); 422 | 423 | for (i=0; iimagedata, sx, sy, ex, ey, color); 428 | sx = ex; 429 | sy = ey; 430 | } 431 | 432 | Py_INCREF(Py_None); 433 | return Py_None; 434 | } 435 | 436 | 437 | static PyObject *image_polygon(imageobject *self, PyObject *args) 438 | { 439 | PyObject *point, *points; 440 | gdPointPtr gdpoints; 441 | int size, color, i, fillcolor = -1; 442 | 443 | if(!PyArg_ParseTuple(args, "O!i|i", &PyTuple_Type, &points, &color, &fillcolor)) { 444 | PyErr_Clear(); 445 | if(PyArg_ParseTuple(args, "O!i|i", &PyList_Type, &points, &color, &fillcolor)) 446 | points=PyList_AsTuple(points); 447 | else 448 | return NULL; 449 | } 450 | 451 | size = PyTuple_Size(points); 452 | 453 | gdpoints = (gdPointPtr)calloc(size,sizeof(gdPoint)); 454 | 455 | for(i=0; iimagedata, gdpoints, size, fillcolor); 463 | 464 | gdImagePolygon(self->imagedata, gdpoints, size, color); 465 | 466 | free(gdpoints); 467 | 468 | Py_INCREF(Py_None); 469 | return Py_None; 470 | } 471 | 472 | 473 | static PyObject *image_rectangle(imageobject *self, PyObject *args) 474 | { 475 | int tx,ty,bx,by,t,color,fillcolor,fill=0; 476 | 477 | if(PyArg_ParseTuple(args, "(ii)(ii)ii", &tx, &ty, &bx, &by, &color, &fillcolor)) 478 | fill=1; 479 | else if(PyErr_Clear(), !PyArg_ParseTuple(args, "(ii)(ii)i", &tx, &ty, &bx, &by, &color)) 480 | return NULL; 481 | 482 | tx = X(tx); ty = Y(ty); 483 | bx = X(bx); by = Y(by); 484 | 485 | if(tx > bx) { 486 | t = tx; 487 | tx = bx; 488 | bx = t; 489 | } 490 | 491 | if(ty > by) { 492 | t = ty; 493 | ty = by; 494 | by = t; 495 | } 496 | 497 | if(fill) 498 | gdImageFilledRectangle(self->imagedata, tx, ty, bx, by, fillcolor); 499 | 500 | gdImageRectangle(self->imagedata, tx, ty, bx, by, color); 501 | 502 | Py_INCREF(Py_None); 503 | return Py_None; 504 | } 505 | 506 | 507 | static PyObject *image_filledpolygon(imageobject *self, PyObject *args) 508 | { 509 | PyObject *point, *points; 510 | gdPointPtr gdpoints; 511 | int size, color, i; 512 | 513 | if(!PyArg_ParseTuple(args, "O!i", &PyTuple_Type, &points, &color)) { 514 | PyErr_Clear(); 515 | if(PyArg_ParseTuple(args, "O!i", &PyList_Type, &points, &color)) 516 | points=PyList_AsTuple(points); 517 | else 518 | return NULL; 519 | } 520 | 521 | size = PyTuple_Size(points); 522 | gdpoints = (gdPointPtr)calloc(size,sizeof(gdPoint)); 523 | 524 | for(i = 0; i < size; i++) { 525 | point = PyTuple_GET_ITEM(points,i); 526 | gdpoints[i].x = X(PyInt_AS_LONG((PyIntObject *)PyTuple_GET_ITEM(point,0))); 527 | gdpoints[i].y = Y(PyInt_AS_LONG((PyIntObject *)PyTuple_GET_ITEM(point,1))); 528 | } 529 | gdImageFilledPolygon(self->imagedata, gdpoints, size, color); 530 | free(gdpoints); 531 | 532 | Py_DECREF(points); 533 | 534 | Py_INCREF(Py_None); 535 | return Py_None; 536 | } 537 | 538 | 539 | static PyObject *image_filledrectangle(imageobject *self, PyObject *args) 540 | { 541 | int tx,ty,bx,by,t,color; 542 | 543 | if(!PyArg_ParseTuple(args, "(ii)(ii)i", &tx, &ty, &bx, &by, &color)) 544 | return NULL; 545 | tx = X(tx); ty = Y(ty); 546 | bx = X(bx); by = Y(by); 547 | if(tx > bx) {t=tx;tx=bx;bx=t;} 548 | if(ty > by) {t=ty;ty=by;by=t;} 549 | gdImageFilledRectangle(self->imagedata, tx, ty, bx, by, color); 550 | Py_INCREF(Py_None); 551 | return Py_None; 552 | } 553 | 554 | 555 | static PyObject *image_arc(imageobject *self, PyObject *args) 556 | { 557 | int cx, cy, w, h, s, e, color, i; 558 | 559 | if(!PyArg_ParseTuple(args, "(ii)(ii)iii", &cx, &cy, &w, &h, &s, &e, &color)) 560 | return NULL; 561 | if(eimagedata, X(cx), Y(cy), W(w), H(h), s, e, color); 563 | Py_INCREF(Py_None); 564 | return Py_None; 565 | } 566 | 567 | static PyObject *image_filledarc(imageobject *self, PyObject *args) 568 | { 569 | #if GD2_VERS <= 1 570 | PyErr_SetString(PyExc_NotImplementedError, 571 | "filledArc() requires gd 2.0 or later"); 572 | return NULL; 573 | #else 574 | int cx, cy, w, h, s, e, color, i, style; 575 | 576 | if(!PyArg_ParseTuple(args, "(ii)(ii)iiii", &cx, &cy, &w, &h, &s, 577 | &e, &color, &style)) 578 | return NULL; 579 | if(eimagedata, X(cx), Y(cy), W(w), H(h), s, e, 581 | color, style); 582 | Py_INCREF(Py_None); 583 | return Py_None; 584 | #endif 585 | } 586 | 587 | static PyObject *image_filledellipse(imageobject *self, PyObject *args) 588 | { 589 | #if GD2_VERS <= 1 590 | PyErr_SetString(PyExc_NotImplementedError, 591 | "filledEllipse() requires gd 2.0 or later"); 592 | return NULL; 593 | #else 594 | int cx, cy, w, h, color; 595 | 596 | if(!PyArg_ParseTuple(args, "(ii)(ii)i", &cx, &cy, &w, &h, &color)) 597 | return NULL; 598 | gdImageFilledEllipse(self->imagedata, X(cx), Y(cy), W(w), H(h), color); 599 | Py_INCREF(Py_None); 600 | return Py_None; 601 | #endif 602 | } 603 | 604 | static PyObject *image_filltoborder(imageobject *self, PyObject *args) 605 | { 606 | int x,y,border,color; 607 | 608 | if(!PyArg_ParseTuple(args, "(ii)ii", &x,&y,&border,&color)) 609 | return NULL; 610 | gdImageFillToBorder(self->imagedata, X(x),Y(y),border,color); 611 | Py_INCREF(Py_None); 612 | return Py_None; 613 | } 614 | 615 | 616 | static PyObject *image_fill(imageobject *self, PyObject *args) 617 | { 618 | int x,y,color; 619 | 620 | if(!PyArg_ParseTuple(args, "(ii)i", &x,&y,&color)) 621 | return NULL; 622 | gdImageFill(self->imagedata, X(x),Y(y),color); 623 | Py_INCREF(Py_None); 624 | return Py_None; 625 | } 626 | 627 | 628 | static PyObject *image_setbrush(imageobject *self, PyObject *args) 629 | { 630 | imageobject *brush; 631 | char *filename, *type; /* dummies */ 632 | 633 | if(PyArg_ParseTuple(args, "z|z", &filename, &type)) 634 | brush = (imageobject *)newimageobject(args); 635 | else if(PyErr_Clear(), PyArg_ParseTuple(args, "O!", &Imagetype, &brush)) 636 | Py_INCREF(brush); 637 | else 638 | return NULL; 639 | if(self->current_brush){ 640 | Py_DECREF(self->current_brush); 641 | } 642 | self->current_brush = brush; 643 | gdImageSetBrush(self->imagedata, brush->imagedata); 644 | 645 | Py_INCREF(Py_None); 646 | return Py_None; 647 | } 648 | 649 | 650 | static PyObject *image_setantialiased(imageobject *self, PyObject *args) 651 | { 652 | int c; 653 | 654 | if(!PyArg_ParseTuple(args, "i", &c)) 655 | return NULL; 656 | 657 | gdImageSetAntiAliased(self->imagedata, c); 658 | 659 | Py_INCREF(Py_None); 660 | return Py_None; 661 | } 662 | 663 | 664 | 665 | static PyObject *image_setclip(imageobject *self, PyObject *args) 666 | { 667 | int tx,ty,bx,by,t; 668 | 669 | if(!PyArg_ParseTuple(args, "(ii)(ii)", &tx, &ty, &bx, &by)) 670 | return NULL; 671 | 672 | tx = X(tx); ty = Y(ty); 673 | bx = X(bx); by = Y(by); 674 | 675 | if(tx > bx) { 676 | t = tx; 677 | tx = bx; 678 | bx = t; 679 | } 680 | 681 | if(ty > by) { 682 | t = ty; 683 | ty = by; 684 | by = t; 685 | } 686 | 687 | gdImageSetClip(self->imagedata, tx, ty, bx, by); 688 | 689 | Py_INCREF(Py_None); 690 | return Py_None; 691 | } 692 | 693 | 694 | static PyObject *image_settile(imageobject *self, PyObject *args) 695 | { 696 | imageobject *tile; 697 | char *filename, *type; /* dummies */ 698 | 699 | if(PyArg_ParseTuple(args, "z|z", &filename, &type)) 700 | tile = (imageobject *)newimageobject(args); 701 | else 702 | if(PyErr_Clear(), PyArg_ParseTuple(args, "O!", &Imagetype, &tile)) 703 | Py_INCREF(tile); 704 | else 705 | return NULL; 706 | 707 | if(self->current_tile) { 708 | Py_DECREF(self->current_tile); 709 | } 710 | 711 | self->current_tile = tile; 712 | gdImageSetTile(self->imagedata, tile->imagedata); 713 | 714 | Py_INCREF(Py_None); 715 | return Py_None; 716 | } 717 | 718 | 719 | static PyObject *image_setstyle(imageobject *self, PyObject *args) 720 | { 721 | PyObject *style; 722 | int size, i, *stylearray; 723 | 724 | if(!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &style)) { 725 | PyErr_Clear(); 726 | if(PyArg_ParseTuple(args, "O!", &PyList_Type, &style)) 727 | style=PyList_AsTuple(style); 728 | else 729 | return NULL; 730 | } 731 | 732 | size = PyTuple_Size(style); 733 | 734 | stylearray = (int *)calloc(size,sizeof(int)); 735 | 736 | for(i=0; iimagedata, stylearray, size); 740 | free(stylearray); 741 | 742 | Py_INCREF(Py_None); 743 | return Py_None; 744 | } 745 | 746 | static PyObject *image_setthickness(imageobject *self, PyObject *args) 747 | { 748 | #if GD2_VERS <= 1 749 | PyErr_SetString(PyExc_NotImplementedError, 750 | "setThickness() requires gd 2.0 or later"); 751 | return NULL; 752 | #else 753 | int t; 754 | 755 | if(!PyArg_ParseTuple(args, "i", &t)) 756 | return NULL; 757 | gdImageSetThickness(self->imagedata, t); 758 | Py_INCREF(Py_None); 759 | return Py_None; 760 | #endif 761 | } 762 | 763 | static PyObject *image_alphablending(imageobject *self, PyObject *args) 764 | { 765 | #if GD2_VERS <= 1 766 | PyErr_SetString(PyExc_NotImplementedError, 767 | "alphaBlending() requires gd 2.0 or later"); 768 | return NULL; 769 | #else 770 | int blending; 771 | 772 | if(!PyArg_ParseTuple(args, "i", &blending)) 773 | return NULL; 774 | gdImageAlphaBlending(self->imagedata, blending); 775 | Py_INCREF(Py_None); 776 | return Py_None; 777 | #endif 778 | } 779 | 780 | static PyObject *image_alpha(imageobject *self, PyObject *args) 781 | { 782 | #if GD2_VERS <= 1 783 | PyErr_SetString(PyExc_NotImplementedError, 784 | "alpha() requires gd 2.0 or later"); 785 | return NULL; 786 | #else 787 | int color; 788 | 789 | if(!PyArg_ParseTuple(args, "i", &color)) 790 | return NULL; 791 | return Py_BuildValue("i", gdImageAlpha(self->imagedata, color)); 792 | #endif 793 | } 794 | 795 | 796 | static PyObject *image_getpixel(imageobject *self, PyObject *args) 797 | { 798 | int x,y; 799 | 800 | if(!PyArg_ParseTuple(args, "(ii)", &x,&y)) 801 | return NULL; 802 | return Py_BuildValue("i",gdImageGetPixel(self->imagedata, X(x),Y(y))); 803 | } 804 | 805 | 806 | static PyObject *image_boundssafe(imageobject *self, PyObject *args) 807 | { 808 | int x,y; 809 | 810 | if(!PyArg_ParseTuple(args, "(ii)", &x,&y)) 811 | return NULL; 812 | return Py_BuildValue("i",gdImageBoundsSafe(self->imagedata, X(x),Y(y))); 813 | } 814 | 815 | 816 | static PyObject *image_blue(imageobject *self, PyObject *args) 817 | { 818 | int c; 819 | 820 | if(!PyArg_ParseTuple(args, "i", &c)) 821 | return NULL; 822 | return Py_BuildValue("i",gdImageBlue(self->imagedata,c)); 823 | } 824 | 825 | 826 | static PyObject *image_green(imageobject *self, PyObject *args) 827 | { 828 | int c; 829 | 830 | if(!PyArg_ParseTuple(args, "i", &c)) 831 | return NULL; 832 | return Py_BuildValue("i",gdImageGreen(self->imagedata,c)); 833 | } 834 | 835 | 836 | static PyObject *image_red(imageobject *self, PyObject *args) 837 | { 838 | int c; 839 | 840 | if(!PyArg_ParseTuple(args, "i", &c)) 841 | return NULL; 842 | return Py_BuildValue("i",gdImageRed(self->imagedata,c)); 843 | } 844 | 845 | 846 | static PyObject *image_size(imageobject *self) 847 | { 848 | return Py_BuildValue("(ii)",gdImageSX(self->imagedata),gdImageSY(self->imagedata)); 849 | } 850 | 851 | 852 | static PyObject *image_char(imageobject *self, PyObject *args) 853 | { 854 | int x,y,font,color; 855 | char c; 856 | 857 | if(!PyArg_ParseTuple(args, "i(ii)ii", &font,&x,&y,&c,&color)) 858 | return NULL; 859 | gdImageChar(self->imagedata, fonts[font].func(), X(x), Y(y), c, color); 860 | 861 | Py_INCREF(Py_None); 862 | return Py_None; 863 | } 864 | 865 | 866 | static PyObject *image_charup(imageobject *self, PyObject *args) 867 | { 868 | int x,y,font,color; 869 | char c; 870 | 871 | if(!PyArg_ParseTuple(args, "i(ii)si", &font,&x,&y,&c,&color)) 872 | return NULL; 873 | gdImageCharUp(self->imagedata, fonts[font].func(), X(x), Y(y), c, color); 874 | 875 | Py_INCREF(Py_None); 876 | return Py_None; 877 | } 878 | 879 | 880 | static PyObject *image_get_bounding_rect(imageobject *self, PyObject *args) 881 | { 882 | #ifndef HAVE_LIBFREETYPE 883 | PyErr_SetString(PyExc_NotImplementedError, 884 | "Freetype Support Not Available"); 885 | return NULL; 886 | #else 887 | double ptsize, angle; 888 | char *fontname, *str, *rc; 889 | int x, y, brect[8]; 890 | 891 | if(!PyArg_ParseTuple(args, "sdd(ii)s", 892 | &fontname, &ptsize, &angle, &x, &y, &str)) 893 | return NULL; 894 | 895 | rc = gdImageStringTTF(NULL, brect, 0, 896 | fontname, ptsize, angle, x, y, str); 897 | 898 | if(rc != NULL){ 899 | PyErr_SetString(PyExc_ValueError, rc); 900 | return NULL; 901 | } 902 | 903 | return Py_BuildValue("(iiiiiiii)",brect[0],brect[1],brect[2],brect[3], 904 | brect[4],brect[5],brect[6],brect[7]); 905 | #endif 906 | } 907 | 908 | 909 | static PyObject *image_string_ft(imageobject *self, PyObject *args) 910 | { 911 | #ifndef HAVE_LIBFREETYPE 912 | PyErr_SetString(PyExc_NotImplementedError, 913 | "Freetype Support Not Available"); 914 | return NULL; 915 | #else 916 | #if GD2_VERS <= 1 917 | PyErr_SetString(PyExc_NotImplementedError, 918 | "string_ft() requires gd 2.0 or later"); 919 | return NULL; 920 | #else 921 | int x,y,fg; 922 | double ptsize,angle; 923 | char *fontname,*str,*rc; 924 | int brect[8]; 925 | 926 | if(!PyArg_ParseTuple(args, "sdd(ii)si", 927 | &fontname, &ptsize, &angle, &x,&y,&str,&fg)) 928 | return NULL; 929 | rc = gdImageStringFT(NULL, brect, 0, fontname, ptsize, angle, 930 | 0, 0, str); /* calculate the bounding rect */ 931 | if(rc != NULL){ 932 | PyErr_SetString(PyExc_ValueError, rc); 933 | return NULL; 934 | } 935 | rc = gdImageStringTTF(self->imagedata, brect, fg, fontname, 936 | ptsize, angle, x, y, str); 937 | if(rc != NULL){ 938 | PyErr_SetString(PyExc_ValueError, rc); 939 | return NULL; 940 | } 941 | 942 | return Py_BuildValue("(iiiiiiii)", 943 | brect[0], brect[1], brect[2], brect[3], 944 | brect[4], brect[5], brect[6], brect[7]); 945 | #endif 946 | #endif 947 | } 948 | 949 | 950 | static PyObject *image_string_ttf(imageobject *self, PyObject *args) 951 | { 952 | #ifndef HAVE_LIBFREETYPE 953 | PyErr_SetString(PyExc_NotImplementedError, 954 | "Freetype Support Not Available"); 955 | return NULL; 956 | #else 957 | int x,y,fg; 958 | double ptsize,angle; 959 | char *fontname,*str,*rc; 960 | int brect[8]; 961 | 962 | if(!PyArg_ParseTuple(args, "sdd(ii)si", 963 | &fontname, &ptsize, &angle, &x,&y,&str,&fg)) 964 | return NULL; 965 | rc = gdImageStringTTF(NULL, brect, 0, fontname, ptsize, angle, 966 | 0, 0, str); /* calculate the bounding rect */ 967 | if(rc != NULL){ 968 | PyErr_SetString(PyExc_ValueError, rc); 969 | return NULL; 970 | } 971 | rc = gdImageStringTTF(self->imagedata, brect, fg, fontname, 972 | ptsize, angle, x, y, str); 973 | if(rc != NULL){ 974 | PyErr_SetString(PyExc_ValueError, rc); 975 | return NULL; 976 | } 977 | 978 | return Py_BuildValue("(iiiiiiii)", 979 | brect[0], brect[1], brect[2], brect[3], 980 | brect[4], brect[5], brect[6], brect[7]); 981 | #endif 982 | } 983 | 984 | 985 | static PyObject *image_string(imageobject *self, PyObject *args) 986 | { 987 | int x, y, font, color; 988 | unsigned char *str; 989 | 990 | if(!PyArg_ParseTuple(args, "i(ii)si", &font,&x,&y,&str,&color)) 991 | return NULL; 992 | gdImageString(self->imagedata, fonts[font].func(), X(x), Y(y), str, color); 993 | 994 | Py_INCREF(Py_None); 995 | return Py_None; 996 | } 997 | 998 | #ifdef Py_UNICODEOBJECT_H 999 | static PyObject *image_string16(imageobject *self, PyObject *args) 1000 | { 1001 | int x,y,font,color; 1002 | Py_UNICODE *ustr; 1003 | 1004 | if(!PyArg_ParseTuple(args, "i(ii)ui", &font,&x,&y,&ustr,&color)) 1005 | return NULL; 1006 | gdImageString16(self->imagedata, fonts[font].func(), X(x), Y(y), 1007 | (short unsigned int *)ustr, color); 1008 | 1009 | Py_INCREF(Py_None); 1010 | return Py_None; 1011 | } 1012 | #endif 1013 | 1014 | static PyObject *image_stringup(imageobject *self, PyObject *args) 1015 | { 1016 | int x, y, font, color; 1017 | unsigned char *str; 1018 | 1019 | if(!PyArg_ParseTuple(args, "i(ii)si", &font,&x,&y,&str,&color)) 1020 | return NULL; 1021 | gdImageStringUp(self->imagedata, fonts[font].func(), X(x), Y(y), str, color); 1022 | 1023 | Py_INCREF(Py_None); 1024 | return Py_None; 1025 | } 1026 | 1027 | #ifdef Py_UNICODEOBJECT_H 1028 | static PyObject *image_stringup16(imageobject *self, PyObject *args) 1029 | { 1030 | int x,y,font,color; 1031 | Py_UNICODE *ustr; 1032 | 1033 | if(!PyArg_ParseTuple(args, "i(ii)ui", &font,&x,&y,&ustr,&color)) 1034 | return NULL; 1035 | gdImageStringUp16(self->imagedata, fonts[font].func(), X(x), Y(y), 1036 | (short unsigned int *)ustr, color); 1037 | 1038 | Py_INCREF(Py_None); 1039 | return Py_None; 1040 | } 1041 | #endif 1042 | 1043 | static PyObject *image_colorallocate(imageobject *self, PyObject *args) 1044 | { 1045 | int r,g,b; 1046 | 1047 | if(!PyArg_ParseTuple(args, "(iii)", &r, &g, &b)) 1048 | return NULL; 1049 | return(Py_BuildValue("i",gdImageColorAllocate(self->imagedata, r, g, b))); 1050 | } 1051 | 1052 | static PyObject *image_colorallocatealpha(imageobject *self, PyObject *args) 1053 | { 1054 | #if GD2_VERS <= 1 1055 | PyErr_SetString(PyExc_NotImplementedError, 1056 | "colorAllocateAlpha() requires gd 2.0 or later"); 1057 | return NULL; 1058 | #else 1059 | int r,g,b,a; 1060 | 1061 | if(!PyArg_ParseTuple(args, "(iiii)", &r, &g, &b, &a)) 1062 | return NULL; 1063 | return(Py_BuildValue("i",gdImageColorAllocateAlpha(self->imagedata, 1064 | r, g, b, a))); 1065 | #endif 1066 | } 1067 | 1068 | static PyObject *image_colorclosest(imageobject *self, PyObject *args) 1069 | { 1070 | int r,g,b; 1071 | 1072 | if(!PyArg_ParseTuple(args, "(iii)", &r, &g, &b)) 1073 | return NULL; 1074 | return(Py_BuildValue("i",gdImageColorClosest(self->imagedata, r, g, b))); 1075 | } 1076 | 1077 | static PyObject *image_colorclosestalpha(imageobject *self, PyObject *args) 1078 | { 1079 | #if GD2_VERS <= 1 1080 | PyErr_SetString(PyExc_NotImplementedError, 1081 | "colorClosestAlpha() requires gd 2.0 or later"); 1082 | return NULL; 1083 | #else 1084 | int r,g,b,a; 1085 | 1086 | if(!PyArg_ParseTuple(args, "(iiii)", &r, &g, &b, &a)) 1087 | return NULL; 1088 | return(Py_BuildValue("i",gdImageColorClosestAlpha(self->imagedata, r, g, b, 1089 | a))); 1090 | #endif 1091 | } 1092 | 1093 | static PyObject *image_colorclosestHWB(imageobject *self, PyObject *args) 1094 | { 1095 | #if GD2_VERS <= 1 1096 | PyErr_SetString(PyExc_NotImplementedError, 1097 | "colorClosestHWB() requires gd 2.0 or later"); 1098 | return NULL; 1099 | #else 1100 | int r,g,b; 1101 | 1102 | if(!PyArg_ParseTuple(args, "(iii)", &r, &g, &b)) 1103 | return NULL; 1104 | return(Py_BuildValue("i",gdImageColorClosestHWB(self->imagedata, r, 1105 | g, b))); 1106 | #endif 1107 | } 1108 | 1109 | static PyObject *image_colorexact(imageobject *self, PyObject *args) 1110 | { 1111 | int r,g,b; 1112 | 1113 | if(!PyArg_ParseTuple(args, "(iii)", &r, &g, &b)) 1114 | return NULL; 1115 | return(Py_BuildValue("i",gdImageColorExact(self->imagedata, r, g, b))); 1116 | } 1117 | 1118 | static PyObject *image_colorresolve(imageobject *self, PyObject *args) 1119 | { 1120 | #if GD2_VERS <= 1 1121 | PyErr_SetString(PyExc_NotImplementedError, 1122 | "colorResolve() requires gd 2.0 or later"); 1123 | return NULL; 1124 | #else 1125 | int r,g,b; 1126 | 1127 | if(!PyArg_ParseTuple(args, "(iii)", &r, &g, &b)) 1128 | return NULL; 1129 | return(Py_BuildValue("i",gdImageColorResolve(self->imagedata, r, 1130 | g, b))); 1131 | #endif 1132 | } 1133 | 1134 | static PyObject *image_colorresolvealpha(imageobject *self, PyObject *args) 1135 | { 1136 | #if GD2_VERS <= 1 1137 | PyErr_SetString(PyExc_NotImplementedError, 1138 | "colorResolveAlpha() requires gd 2.0 or later"); 1139 | return NULL; 1140 | #else 1141 | int r,g,b,a; 1142 | 1143 | if(!PyArg_ParseTuple(args, "(iiii)", &r, &g, &b, &a)) 1144 | return NULL; 1145 | return(Py_BuildValue("i",gdImageColorResolveAlpha(self->imagedata, r, 1146 | g, b, a))); 1147 | #endif 1148 | } 1149 | 1150 | static PyObject *image_colorstotal(imageobject *self) 1151 | { 1152 | return Py_BuildValue("i",gdImageColorsTotal(self->imagedata)); 1153 | } 1154 | 1155 | 1156 | static PyObject *image_colorcomponents(imageobject *self, PyObject *args) 1157 | { 1158 | int c,r,g,b; 1159 | 1160 | if(!PyArg_ParseTuple(args, "i", &c)) 1161 | return NULL; 1162 | r=gdImageRed(self->imagedata,c); 1163 | g=gdImageGreen(self->imagedata,c); 1164 | b=gdImageBlue(self->imagedata,c); 1165 | return Py_BuildValue("(iii)",r,g,b); 1166 | } 1167 | 1168 | 1169 | static PyObject *image_getclip(imageobject *self) 1170 | { 1171 | int x1, y1, x2, y2; 1172 | gdImageGetClip(self->imagedata, &x1, &y1, &x2, &y2); 1173 | return Py_BuildValue("(ii)(ii)", x1, y1, x2, y2); 1174 | } 1175 | 1176 | static PyObject *image_getinterlaced(imageobject *self) 1177 | { 1178 | return Py_BuildValue("i",gdImageGetInterlaced(self->imagedata)); 1179 | } 1180 | 1181 | 1182 | static PyObject *image_gettransparent(imageobject *self) 1183 | { 1184 | return Py_BuildValue("i",gdImageGetTransparent(self->imagedata)); 1185 | } 1186 | 1187 | 1188 | static PyObject *image_colordeallocate(imageobject *self, PyObject *args) 1189 | { 1190 | int c; 1191 | 1192 | if(!PyArg_ParseTuple(args, "i", &c)) 1193 | return NULL; 1194 | gdImageColorDeallocate(self->imagedata, c); 1195 | 1196 | Py_INCREF(Py_None); 1197 | return Py_None; 1198 | } 1199 | 1200 | 1201 | static PyObject *image_colortransparent(imageobject *self, PyObject *args) 1202 | { 1203 | int c; 1204 | 1205 | if(!PyArg_ParseTuple(args, "i", &c)) 1206 | return NULL; 1207 | gdImageColorTransparent(self->imagedata, c); 1208 | 1209 | Py_INCREF(Py_None); 1210 | return Py_None; 1211 | } 1212 | 1213 | 1214 | static PyObject *image_copyto(imageobject *self, PyObject *args) 1215 | { 1216 | imageobject *dest; 1217 | int dx,dy,sx,sy,w,h,dw,dh; 1218 | 1219 | dx=dy=sx=sy=0; 1220 | w = gdImageSX(self->imagedata); 1221 | h = gdImageSY(self->imagedata); 1222 | if(!PyArg_ParseTuple(args, "O!|(ii)(ii)(ii)", &Imagetype, &dest, &dx, &dy, &sx, &sy, &w, &h)) 1223 | return NULL; 1224 | dw = gdImageSX(dest->imagedata); 1225 | dh = gdImageSY(dest->imagedata); 1226 | gdImageCopy(dest->imagedata, self->imagedata, X(dx), Y(dy), X(sx), Y(sy), W(w), H(h)); 1227 | 1228 | Py_INCREF(Py_None); 1229 | return Py_None; 1230 | } 1231 | 1232 | 1233 | static PyObject *image_copyresizedto(imageobject *self, PyObject *args) 1234 | { 1235 | imageobject *dest; 1236 | int dx,dy,sx,sy,dw,dh,sw,sh; 1237 | 1238 | dx=dy=sx=sy=0; 1239 | sw = gdImageSX(self->imagedata); 1240 | sh = gdImageSY(self->imagedata); 1241 | if(PyArg_ParseTuple(args, "O!|(ii)(ii)", &Imagetype, &dest, &dx, &dy, &sx, &sy)) 1242 | { 1243 | dw = gdImageSX(dest->imagedata); 1244 | dh = gdImageSY(dest->imagedata); 1245 | } 1246 | else if(PyErr_Clear(), !PyArg_ParseTuple(args, "O!|(ii)(ii)(ii)(ii)", &Imagetype, &dest, &dx, &dy, &sx, &sy, &dw, &dh, &sw, &sh)) 1247 | return NULL; 1248 | gdImageCopyResized(dest->imagedata, self->imagedata, X(dx), Y(dy), X(sx), Y(sy), W(dw), H(dh), W(sw), H(sh)); 1249 | 1250 | Py_INCREF(Py_None); 1251 | return Py_None; 1252 | } 1253 | 1254 | 1255 | static PyObject *image_copyresampledto(imageobject *self, PyObject *args) 1256 | { 1257 | #if GD2_VERS <= 1 1258 | PyErr_SetString(PyExc_NotImplementedError, 1259 | "copyResampledTo() requires gd 2.0 or later"); 1260 | return NULL; 1261 | #else 1262 | imageobject *dest; 1263 | int dx,dy,sx,sy,dw,dh,sw,sh; 1264 | 1265 | dx=dy=sx=sy=0; 1266 | sw = gdImageSX(self->imagedata); 1267 | sh = gdImageSY(self->imagedata); 1268 | if(PyArg_ParseTuple(args, "O!|(ii)(ii)", &Imagetype, &dest, &dx, &dy, 1269 | &sx, &sy)) 1270 | { 1271 | dw = gdImageSX(dest->imagedata); 1272 | dh = gdImageSY(dest->imagedata); 1273 | } 1274 | else if(PyErr_Clear(), !PyArg_ParseTuple(args, "O!|(ii)(ii)(ii)(ii)", 1275 | &Imagetype, &dest, &dx, &dy, &sx, &sy, &dw, &dh, &sw, &sh)) 1276 | return NULL; 1277 | gdImageCopyResampled(dest->imagedata, self->imagedata, X(dx), Y(dy), 1278 | X(sx), Y(sy), W(dw), H(dh), W(sw), H(sh)); 1279 | 1280 | Py_INCREF(Py_None); 1281 | return Py_None; 1282 | #endif 1283 | } 1284 | 1285 | static PyObject *image_copymergeto(imageobject *self, PyObject *args) 1286 | { 1287 | #if GD2_VERS <= 1 1288 | PyErr_SetString(PyExc_NotImplementedError, 1289 | "copyMergeTo() requires gd 2.0 or later"); 1290 | return NULL; 1291 | #else 1292 | imageobject *dest; 1293 | int dx,dy,sx,sy,w,h,dw,dh,pct; 1294 | 1295 | dx=dy=sx=sy=0; 1296 | w = gdImageSX(self->imagedata); 1297 | h = gdImageSY(self->imagedata); 1298 | pct = 100; 1299 | if(!PyArg_ParseTuple(args, "O!|(ii)(ii)(ii)i", &Imagetype, &dest, &dx, &dy, &sx, &sy, &w, &h, &pct)) 1300 | return NULL; 1301 | dw = gdImageSX(dest->imagedata); 1302 | dh = gdImageSY(dest->imagedata); 1303 | gdImageCopyMerge(dest->imagedata, self->imagedata, X(dx), Y(dy), X(sx), Y(sy), W(w), H(h), pct); 1304 | 1305 | Py_INCREF(Py_None); 1306 | return Py_None; 1307 | #endif 1308 | } 1309 | 1310 | static PyObject *image_copymergegrayto(imageobject *self, PyObject *args) 1311 | { 1312 | #if GD2_VERS <= 1 1313 | PyErr_SetString(PyExc_NotImplementedError, 1314 | "copyMergeGrayTo() requires gd 2.0 or later"); 1315 | return NULL; 1316 | #else 1317 | imageobject *dest; 1318 | int dx,dy,sx,sy,w,h,dw,dh,pct; 1319 | 1320 | dx=dy=sx=sy=0; 1321 | w = gdImageSX(self->imagedata); 1322 | h = gdImageSY(self->imagedata); 1323 | pct = 100; 1324 | if(!PyArg_ParseTuple(args, "O!|(ii)(ii)(ii)i", &Imagetype, &dest, &dx, &dy, &sx, &sy, &w, &h, &pct)) 1325 | return NULL; 1326 | dw = gdImageSX(dest->imagedata); 1327 | dh = gdImageSY(dest->imagedata); 1328 | gdImageCopyMergeGray(dest->imagedata, self->imagedata, X(dx), Y(dy), X(sx), Y(sy), W(w), H(h), pct); 1329 | 1330 | Py_INCREF(Py_None); 1331 | return Py_None; 1332 | #endif 1333 | } 1334 | 1335 | static PyObject *image_copypaletteto(imageobject *self, PyObject *args) 1336 | { 1337 | #if GD2_VERS <= 1 1338 | PyErr_SetString(PyExc_NotImplementedError, 1339 | "copyPaletteTo() requires gd 2.0 or later"); 1340 | return NULL; 1341 | #else 1342 | imageobject *dest; 1343 | if(!PyArg_ParseTuple(args, "O!", &Imagetype, &dest)) 1344 | return NULL; 1345 | 1346 | gdImagePaletteCopy(dest->imagedata, self->imagedata); 1347 | Py_INCREF(Py_None); 1348 | return Py_None; 1349 | #endif 1350 | } 1351 | 1352 | static PyObject *image_compare(imageobject *self, PyObject *args) 1353 | { 1354 | #if GD2_VERS <= 1 1355 | PyErr_SetString(PyExc_NotImplementedError, 1356 | "compare() requires gd 2.0 or later"); 1357 | return NULL; 1358 | #else 1359 | imageobject *dest; 1360 | if(!PyArg_ParseTuple(args, "O!", &Imagetype, &dest)) 1361 | return NULL; 1362 | 1363 | return Py_BuildValue("i", gdImageCompare(dest->imagedata, 1364 | self->imagedata)); 1365 | #endif 1366 | } 1367 | 1368 | static PyObject *image_interlace(imageobject *self, PyObject *args) 1369 | { 1370 | int i; 1371 | 1372 | if(!PyArg_ParseTuple(args, "i", &i)) 1373 | return NULL; 1374 | gdImageInterlace(self->imagedata, i); 1375 | 1376 | Py_INCREF(Py_None); 1377 | return Py_None; 1378 | } 1379 | 1380 | 1381 | static PyObject *image_savealpha(imageobject *self, PyObject *args) 1382 | { 1383 | int i; 1384 | 1385 | if(!PyArg_ParseTuple(args, "i", &i)) 1386 | return NULL; 1387 | gdImageSaveAlpha(self->imagedata, i); 1388 | 1389 | Py_INCREF(Py_None); 1390 | return Py_None; 1391 | } 1392 | 1393 | 1394 | static PyObject *image_origin(imageobject *self, PyObject *args) 1395 | { 1396 | if(!PyArg_ParseTuple(args, "(ii)|ii",&self->origin_x,&self->origin_y, 1397 | &self->multiplier_x,&self->multiplier_y)) 1398 | return NULL; 1399 | 1400 | Py_INCREF(Py_None); 1401 | return Py_None; 1402 | } 1403 | 1404 | 1405 | static PyObject *image_getorigin(imageobject *self) 1406 | { 1407 | return Py_BuildValue("((ii)ii)",self->origin_x,self->origin_y,self->multiplier_x,self->multiplier_y); 1408 | } 1409 | 1410 | 1411 | static struct PyMethodDef image_methods[] = { 1412 | 1413 | {"writeGif", (PyCFunction)image_writegif, 1, 1414 | "writeGif(f)\n" 1415 | "write the image to f as a GIF, where f is either an open file object or a\n" 1416 | "file name."}, 1417 | 1418 | {"writePng", (PyCFunction)image_writepng, 1, 1419 | "writePng(f)\n" 1420 | "write the image to f as a PNG, where f is either an open file object or a\n" 1421 | "file name."}, 1422 | 1423 | {"writeJpeg", (PyCFunction)image_writejpeg, 1, 1424 | "writeJpeg(f,quality)\n" 1425 | "write the image to f as a JPEG, where f is either an open file object or a\n" 1426 | "file name. quality is an optional integer value giving the JPEG quality from\n" 1427 | "0 to 95%; leave out for default quality."}, 1428 | 1429 | {"writeWbmp", (PyCFunction)image_writewbmp, 1, 1430 | "writeWbmp(f,fg)\n" 1431 | "write the image to f as a WBMP, where f is either an open file object or a\n" 1432 | "file name. fg is a foreground color index which will be set in the output\n" 1433 | "file; see the gd documentation for a further explanation of this value."}, 1434 | 1435 | {"writeGd", (PyCFunction)image_writegd, 1, 1436 | "writeGd(f)\n" 1437 | "write the image to f as a GD file, where f is either an open file object\n" 1438 | "or a file name."}, 1439 | 1440 | {"writeGd2", (PyCFunction)image_writegd2, 1, 1441 | "writeGd(f,chunksize,fmt)\n" 1442 | "write the image to f as a GD2 file, where f is either an open file object\n" 1443 | "or a file name. see the gd documentation for an explanation of the chunksize\n" 1444 | "and fmt arguments. defaults will be used if not given."}, 1445 | 1446 | {"setPixel", (PyCFunction)image_setpixel, 1, 1447 | "setPixel((x,y), color)\n" 1448 | "set the pixel at (x,y) to color"}, 1449 | 1450 | {"line", (PyCFunction)image_line, 1, 1451 | "line((x1,y1), (x2,y2), color)\n" 1452 | "draw a line from (x1,y1) to (x2,y2) in color"}, 1453 | 1454 | {"lines", (PyCFunction)image_lines, 1, 1455 | "line(seq, color)\n" 1456 | "seq is a list of x,y tuples. Draw a connected line in color"}, 1457 | 1458 | 1459 | {"polygon", (PyCFunction)image_polygon, 1, 1460 | "polygon(((x1,y1), (x2,y2), ..., (xn, yn)), color[, fillcolor])\n" 1461 | "draw a polygon using the list or tuple of points (minimum 3) in color,\n" 1462 | "optionally filled with fillcolor"}, 1463 | 1464 | {"rectangle", (PyCFunction)image_rectangle, 1, "rectangle((x1,y1), (x2,y2), color[, fillcolor])\n" 1465 | "draw a rectangle with upper corner (x1,y1), lower corner (x2,y2) in color,\n" 1466 | "optionally filled with fillcolor"}, 1467 | 1468 | {"filledPolygon", (PyCFunction)image_filledpolygon, 1, 1469 | "filledPolygon(((x1,y1), (x2,y2), ..., (xn, yn)), color)\n" 1470 | "draw a filled polygon using the list or tuple of points (minimum 3) in color"}, 1471 | 1472 | {"filledRectangle", (PyCFunction)image_filledrectangle, 1, 1473 | "filledRectangle((x1,y1), (x2,y2), color)\n" 1474 | "draw a rectangle with upper corner (x1,y1), lower corner (x2,y2) in color"}, 1475 | 1476 | {"arc", (PyCFunction)image_arc, 1, 1477 | "arc((x,y), (w,h), start, end, color)\n" 1478 | "draw an ellipse centered at (x,y) with width w, height h from start\n" 1479 | "degrees to end degrees in color."}, 1480 | 1481 | {"filledArc", (PyCFunction)image_filledarc, 1, 1482 | "filledArc((x,y), (w,h), start, end, color, style)\n" 1483 | "draw an ellipse centered at (x,y) with width w, height h from start\n" 1484 | "degrees to end degrees in color. The style argument is a bitwise OR\n" 1485 | "of the following (gdArc, gdChord, gdPie, gdNoFill, gdEdged)."}, 1486 | 1487 | {"filledEllipse", (PyCFunction)image_filledellipse, 1, 1488 | "filledEllipse((x,y), (w,h), color)\n" 1489 | "draw a filled ellipse centered at (x,y) with width w,\n" 1490 | "height h in color."}, 1491 | 1492 | {"fillToBorder", (PyCFunction)image_filltoborder, 1, 1493 | "fillToBorder((x,y), border, color)\n" 1494 | "flood from point (x,y) to border color in color"}, 1495 | 1496 | {"fill", (PyCFunction)image_fill, 1, 1497 | "fill((x,y), color)\n" 1498 | "flood from point (x,y) in color for those pixels with the same color\n" 1499 | "as the starting point"}, 1500 | 1501 | {"setBrush", (PyCFunction)image_setbrush, 1, 1502 | "setBrush(image)\n" 1503 | "set the drawing brush to (use gdBrushed when drawing)"}, 1504 | 1505 | {"setAntiAliased", (PyCFunction)image_setantialiased, 1, "setAntiAliased(color)\n" 1506 | "Set the foreground color to be used when drawing antialiased lines. Use the gdAntiAliased in place of the color when drawing"}, 1507 | 1508 | {"setClip", (PyCFunction)image_setclip, 1, "setClip((x1,y1), (x2,y2))\n" 1509 | "Set the image clipping rectangle"}, 1510 | 1511 | 1512 | {"setTile", (PyCFunction)image_settile, 1, 1513 | "setTile(image)\n" 1514 | "set the fill tile to (use gdTiled when filling)"}, 1515 | 1516 | {"setStyle", (PyCFunction)image_setstyle, 1, 1517 | "setStyle(tuple)\n" 1518 | "set the line bit-style to tuple of colors (use gdStyled when drawing)"}, 1519 | 1520 | {"setThickness", (PyCFunction)image_setthickness, 1, 1521 | "setThickness(thickness)\n" 1522 | "set the width of lines, polyons, and arcs."}, 1523 | 1524 | {"alphaBlending", (PyCFunction)image_alphablending, 1, 1525 | "alphaBlending(blending)\n" 1526 | "toggles alpha channel blending for trucolor images."}, 1527 | 1528 | {"alpha", (PyCFunction)image_alpha, 1, 1529 | "alpha(color)\n" 1530 | "returns the alpha component of the specified color."}, 1531 | 1532 | {"blue", (PyCFunction)image_blue, 1, 1533 | "blue(color)\n" 1534 | "returns the blue component of the specified color."}, 1535 | 1536 | {"green", (PyCFunction)image_green, 1, 1537 | "green(color)\n" 1538 | "returns the green component of the specified color."}, 1539 | 1540 | {"red", (PyCFunction)image_red, 1, 1541 | "red(color)\n" 1542 | "returns the red component of the specified color."}, 1543 | 1544 | {"getPixel", (PyCFunction)image_getpixel, 1, 1545 | "getPixel((x,y))\n" 1546 | "color index of image at (x,y)"}, 1547 | 1548 | {"boundsSafe", (PyCFunction)image_boundssafe, 1, 1549 | "boundsSafe((x,y))\n" 1550 | "returns true if(x,y) is within image"}, 1551 | 1552 | {"size", (PyCFunction)image_size, 1, 1553 | "size()\n" 1554 | "return the 2-tuple size of image"}, 1555 | 1556 | {"char", (PyCFunction)image_char,1, 1557 | "char(font, (x,y), c, color)\n" 1558 | "draw string c at (x,y) using one of the pre-defined gdmodule fonts (gdFont*)"}, 1559 | 1560 | {"charUp", (PyCFunction)image_charup,1, 1561 | "charUp(font, (x,y), c, color)\n" 1562 | "vertically draw string c at (x,y) using one of the pre-defined gdmodule\n" 1563 | "fonts (gdFont*)"}, 1564 | 1565 | {"get_bounding_rect", (PyCFunction)image_get_bounding_rect,1, 1566 | "get_bounding_rect(font, ptsize, angle,(x,y), s)\n" 1567 | "get bounding rect of string s using the truetype font"}, 1568 | 1569 | {"string_ttf", (PyCFunction)image_string_ttf,1, 1570 | "string_ttf(font, ptsize, angle, (x,y), s, color)\n" 1571 | "draw string s at (x,y) using the truetype font"}, 1572 | 1573 | {"string_ft", (PyCFunction)image_string_ft,1, 1574 | "string_ft(font, ptsize, angle, (x,y), s, color)\n" 1575 | "draw string s at (x,y) using the truetype font"}, 1576 | 1577 | {"string", (PyCFunction)image_string,1, 1578 | "string(font, (x,y), s, color)\n" 1579 | "draw string s at (x,y) using one of the pre-defined gdmodule fonts (gdFont*)"}, 1580 | 1581 | #ifdef Py_UNICODEOBJECT_H 1582 | {"string16", (PyCFunction)image_string16,1, 1583 | "string(font, (x,y), s, color)\n" 1584 | "draw unicode string s at (x,y) using one of the pre-defined gdmodule fonts (gdFont*)"}, 1585 | #endif 1586 | 1587 | {"stringUp", (PyCFunction)image_stringup,1, 1588 | "stringUp(font, (x,y), s, color)\n" 1589 | "vertically draw string s at (x,y) using one of the pre-defined gdmodule\n" 1590 | "fonts (gdFont*)"}, 1591 | 1592 | #ifdef Py_UNICODEOBJECT_H 1593 | {"stringUp16", (PyCFunction)image_stringup16,1, 1594 | "stringUp16(font, (x,y), s, color)\n" 1595 | "vertically draw unicode string s at (x,y) using one of the pre-defined gdmodule\n" 1596 | "fonts (gdFont*)"}, 1597 | #endif 1598 | 1599 | {"colorAllocate", (PyCFunction)image_colorallocate,1, 1600 | "colorAllocate((r,g,b))\n" 1601 | "allocate a color index to (r,g,b) (returns -1 if unable to)"}, 1602 | 1603 | {"colorAllocateAlpha", (PyCFunction)image_colorallocatealpha,1, 1604 | "colorAllocateAlpha((r,g,b,a))\n" 1605 | "allocate a color index to (r,g,b,a) (returns -1 if unable to)"}, 1606 | 1607 | {"colorClosest", (PyCFunction)image_colorclosest, 1, 1608 | "colorClosest((r,g,b))\n" 1609 | "return the color index closest to (r,g,b) (returns -1 if unable to)"}, 1610 | 1611 | {"colorClosestAlpha", (PyCFunction)image_colorclosestalpha, 1, 1612 | "colorClosestAlpha((r,g,b,a))\n" 1613 | "return the color index closest to (r,g,b,a) (returns -1 if unable to)"}, 1614 | 1615 | {"colorClosestHWB", (PyCFunction)image_colorclosestHWB, 1, 1616 | "colorClosestHWB((r,g,b))\n" 1617 | "return the color index closest in hue whiteness and blackness to (r,g,b) (returns -1 if unable to)"}, 1618 | 1619 | {"colorExact", (PyCFunction)image_colorexact, 1, 1620 | "colorExact((r,g,b))\n" 1621 | "return an exact color index match for (r,g,b) (returns -1 if unable to)"}, 1622 | 1623 | {"colorResolve", (PyCFunction)image_colorresolve, 1, 1624 | "colorResolve((r,g,b))\n" 1625 | "returns the exact color (after possibly allocating) or the closes match."}, 1626 | 1627 | {"colorResolveAlpha", (PyCFunction)image_colorresolvealpha, 1, 1628 | "colorResolve((r,g,b,a))\n" 1629 | "returns the exact color (after possibly allocating) or the closes match."}, 1630 | 1631 | {"colorsTotal", (PyCFunction)image_colorstotal, 1, 1632 | "colorsTotal()\n" 1633 | "returns the number of colors currently allocated"}, 1634 | 1635 | {"colorComponents", (PyCFunction)image_colorcomponents, 1, 1636 | "colorComponents(color)\n" 1637 | "returns a 3-tulple of the (r,g,b) components of color"}, 1638 | 1639 | {"getClip", (PyCFunction)image_getclip, 1, 1640 | "getClip()\n" 1641 | "returns (x1,y1), (x2,y2) of the image clip rectange"}, 1642 | 1643 | {"getInterlaced", (PyCFunction)image_getinterlaced, 1, 1644 | "getInterlaced()\n" 1645 | "returns true if the image is interlaced"}, 1646 | 1647 | {"getTransparent", (PyCFunction)image_gettransparent, 1, 1648 | "getTransparent()\n" 1649 | "returns transparent color index or -1"}, 1650 | 1651 | {"colorDeallocate", (PyCFunction)image_colordeallocate, 1, 1652 | "colorDeallocate(color)\n" 1653 | "deallocate color from the image palette"}, 1654 | 1655 | {"colorTransparent", (PyCFunction)image_colortransparent, 1, 1656 | "colorTransparent(color)\n" 1657 | "set the transparent color to color"}, 1658 | 1659 | {"copyTo", (PyCFunction)image_copyto, 1, 1660 | "copyTo(image[, (dx,dy)[, (sx,sy)[, (w,h)]]])\n" 1661 | "copy from (sx,sy), width sw and height sh to destination image (dx,dy)"}, 1662 | 1663 | {"copyResizedTo", (PyCFunction)image_copyresizedto,1, 1664 | "copyResizedTocopyTo(image[, (dx,dy)[, (sx,sy)[, (dw,dh)[, (sw,sh)]]]])\n" 1665 | "copy from (sx,sy), width sw and height sh to destination image (dx,dy), \n" 1666 | "width dw and height dh"}, 1667 | 1668 | {"copyResampledTo", (PyCFunction)image_copyresampledto,1, 1669 | "copyResampledTo(image[, (dx,dy)[, (sx,sy)[, (dw,dh)[, (sw,sh)]]]])\n" 1670 | "copy from (sx,sy), width sw and height sh to destination image (dx,dy), \n" 1671 | "width dw and height dh using smooth pixel interpolation."}, 1672 | 1673 | {"copyMergeTo", (PyCFunction)image_copymergeto, 1, 1674 | "copyMergeTo(image[, (dx,dy)[, (sx,sy)[, (w,h)]], pct])\n" 1675 | "copy from (sx,sy), width sw and height sh to destination image (dx,dy)\n" 1676 | "If pct is 100 then this is equivalent to copyTo(). If pct is less\n" 1677 | "than 100 the images are merged." }, 1678 | 1679 | {"copyMergeGrayTo", (PyCFunction)image_copymergegrayto, 1, 1680 | "copyMergeGrayTo(image[, (dx,dy)[, (sx,sy)[, (w,h)]], pct])\n" 1681 | "copy from (sx,sy), width sw and height sh to destination image (dx,dy)\n" 1682 | "If pct is 100 then this is equivalent to copyTo(). If pct is less\n" 1683 | "than 100 the images are merged. The hue is preserved by first\n" 1684 | "converting the destination pixels to gray." }, 1685 | 1686 | {"copyPaletteTo", (PyCFunction)image_copypaletteto, 1, 1687 | "copyPaletteTo(image)\n" 1688 | "copy the palette from one image to another."}, 1689 | 1690 | {"compare", (PyCFunction)image_compare, 1, 1691 | "compare(image)\n" 1692 | "compares this image with another. Returns a bitmask whose values\n" 1693 | "are composed of CMP_IMAGE, CMP_NUM_COLORS, CMP_COLOR, CMP_SIZE_X,\n" 1694 | "CMP_SIZE_Y, CMP_TRANSPARENT, CMP_BACKGROUND, CMP_INTERLACE, CMP_TRUECOLOR"}, 1695 | 1696 | {"interlace", (PyCFunction)image_interlace, 1, 1697 | "interlace()\n" 1698 | "set the interlace bit"}, 1699 | 1700 | {"origin", (PyCFunction)image_origin, 1, 1701 | "origin((x,y)[,xmult,ymult])\n" 1702 | "set the origin of the image to (x,y) and multiply all x, y, width and\n" 1703 | "height factors by xmult and ymult (typically either 1 or -1)"}, 1704 | 1705 | {"getOrigin", (PyCFunction)image_getorigin, 1, 1706 | "getOrigin()\n" 1707 | "returns the origin parameters ((x,y),xmult,ymult)"}, 1708 | 1709 | {"saveAlpha", (PyCFunction)image_savealpha, 1, 1710 | "saveAlpha(n)\n" 1711 | "if n = 1, alpha channel information will be saved" 1712 | " (assuming the format supports it, i.e. PNG)"}, 1713 | 1714 | {NULL, NULL} /* sentinel */ 1715 | }; 1716 | 1717 | 1718 | /* 1719 | ** Table of file types understood to gd "constructors" 1720 | */ 1721 | 1722 | static struct { 1723 | char *ext; 1724 | gdImagePtr (*func)(FILE*); 1725 | 1726 | } ext_table[] = { 1727 | 1728 | #ifdef HAVE_LIBGIF 1729 | {"gif", gdImageCreateFromGif}, 1730 | #endif 1731 | #ifdef HAVE_LIBPNG 1732 | {"png", gdImageCreateFromPng}, 1733 | #endif 1734 | #ifdef HAVE_LIBJPEG 1735 | {"jpeg", gdImageCreateFromJpeg}, 1736 | {"jpg", gdImageCreateFromJpeg}, 1737 | {"jfif", gdImageCreateFromJpeg}, 1738 | #endif 1739 | {"gd", gdImageCreateFromGd}, 1740 | {"gd2", gdImageCreateFromGd2}, 1741 | {"xbm", gdImageCreateFromXbm}, /* this is internal to gd */ 1742 | 1743 | {NULL, NULL} 1744 | }; 1745 | 1746 | static struct { 1747 | char *ext; 1748 | gdImagePtr (*func)(gdIOCtxPtr); 1749 | 1750 | } ext_table_ctx[] = { 1751 | 1752 | #ifdef HAVE_LIBPNG 1753 | {"png", gdImageCreateFromPngCtx}, 1754 | #endif 1755 | #ifdef HAVE_LIBJPEG 1756 | {"jpeg", gdImageCreateFromJpegCtx}, 1757 | {"jpg", gdImageCreateFromJpegCtx}, 1758 | {"jfif", gdImageCreateFromJpegCtx}, 1759 | #endif 1760 | {"gd", gdImageCreateFromGdCtx}, 1761 | {"gd2", gdImageCreateFromGd2Ctx}, 1762 | 1763 | {NULL, NULL} 1764 | }; 1765 | 1766 | 1767 | /* 1768 | ** Code to act as a gdIOCtx wrapper for a python file object 1769 | ** (read-only; write support would not be difficult to add) 1770 | */ 1771 | 1772 | struct PyFileIfaceObj_gdIOCtx { 1773 | gdIOCtx ctx; 1774 | PyObject *fileIfaceObj; 1775 | PyObject *strObj; // our reference to the data string we're currently 1776 | }; 1777 | 1778 | int PyFileIfaceObj_IOCtx_GetC(gdIOCtx *ctx) 1779 | { 1780 | struct PyFileIfaceObj_gdIOCtx *pctx = (struct PyFileIfaceObj_gdIOCtx *)ctx; 1781 | if (pctx->strObj) { 1782 | Py_DECREF(pctx->strObj); 1783 | pctx->strObj = NULL; 1784 | } 1785 | pctx->strObj = PyObject_CallMethod(pctx->fileIfaceObj, "read", "i", 1); 1786 | if (!pctx->strObj || !PyString_Check(pctx->strObj)) { 1787 | return EOF; 1788 | } 1789 | if (PyString_GET_SIZE(pctx->strObj) == 1) { 1790 | return (int)(unsigned char)PyString_AS_STRING(pctx->strObj)[0]; 1791 | } 1792 | return EOF; 1793 | } 1794 | 1795 | int PyFileIfaceObj_IOCtx_GetBuf(gdIOCtx *ctx, void *data, Py_ssize_t size) 1796 | { 1797 | int err; 1798 | char *value; 1799 | struct PyFileIfaceObj_gdIOCtx *pctx = (struct PyFileIfaceObj_gdIOCtx *)ctx; 1800 | if (pctx->strObj) { 1801 | Py_DECREF(pctx->strObj); 1802 | pctx->strObj = NULL; 1803 | } 1804 | pctx->strObj = PyObject_CallMethod(pctx->fileIfaceObj, "read", "i", size); 1805 | if (!pctx->strObj) { 1806 | return 0; 1807 | } 1808 | err = PyString_AsStringAndSize(pctx->strObj, &value, &size); 1809 | if (err < 0) { 1810 | /* this throws away the python exception since the gd library 1811 | * won't pass it up properly. gdmodule should create its own 1812 | * since the "file" couldn't be read properly. */ 1813 | PyErr_Clear(); 1814 | return 0; 1815 | } 1816 | memcpy(data, value, size); 1817 | return size; 1818 | } 1819 | 1820 | void PyFileIfaceObj_IOCtx_Free(gdIOCtx *ctx) 1821 | { 1822 | struct PyFileIfaceObj_gdIOCtx *pctx = (struct PyFileIfaceObj_gdIOCtx *)ctx; 1823 | if (pctx->strObj) { 1824 | Py_DECREF(pctx->strObj); 1825 | pctx->strObj = NULL; 1826 | } 1827 | if (pctx->fileIfaceObj) { 1828 | Py_DECREF(pctx->fileIfaceObj); 1829 | pctx->fileIfaceObj = NULL; 1830 | } 1831 | /* NOTE: we leave deallocation of the ctx structure itself to outside 1832 | * code for memory allocation symmetry. This function is safe to 1833 | * call multiple times (gd should call it + we call it to be safe). */ 1834 | } 1835 | 1836 | struct PyFileIfaceObj_gdIOCtx * alloc_PyFileIfaceObj_IOCtx(PyObject *fileIfaceObj) 1837 | { 1838 | struct PyFileIfaceObj_gdIOCtx *pctx; 1839 | pctx = calloc(1, sizeof(struct PyFileIfaceObj_gdIOCtx)); 1840 | if (!pctx) 1841 | return NULL; 1842 | pctx->ctx.getC = PyFileIfaceObj_IOCtx_GetC; 1843 | pctx->ctx.getBuf = PyFileIfaceObj_IOCtx_GetBuf; 1844 | pctx->ctx.gd_free = PyFileIfaceObj_IOCtx_Free; 1845 | Py_INCREF(fileIfaceObj); 1846 | pctx->fileIfaceObj = fileIfaceObj; 1847 | return pctx; 1848 | } 1849 | 1850 | void free_PyFileIfaceObj_IOCtx(struct PyFileIfaceObj_gdIOCtx *pctx) 1851 | { 1852 | if (!pctx) 1853 | return; 1854 | assert(pctx->ctx.gd_free != NULL); 1855 | pctx->ctx.gd_free((gdIOCtxPtr)pctx); // free its internal resources 1856 | free(pctx); 1857 | } 1858 | /* 1859 | ** Code to create the imageobject 1860 | */ 1861 | 1862 | static imageobject *newimageobject(PyObject *args) 1863 | { 1864 | imageobject *self, *srcimage; 1865 | int xdim=0, ydim=0, i, trueColor=0; 1866 | char *filename,*ext=0; 1867 | FILE *fp; 1868 | PyObject *readObj; 1869 | 1870 | if(!(self = PyObject_NEW(imageobject, &Imagetype))) 1871 | return NULL; 1872 | 1873 | self->current_tile = self->current_brush = NULL; 1874 | self->origin_x = self->origin_y = 0; 1875 | self->multiplier_x = self->multiplier_y = 1; 1876 | self->imagedata = NULL; 1877 | 1878 | if(PyArg_ParseTuple(args, "")) { 1879 | PyErr_SetString(PyExc_ValueError, 1880 | "image size or source filename required"); 1881 | Py_DECREF(self); 1882 | return NULL; 1883 | } else if(PyErr_Clear(), 1884 | PyArg_ParseTuple(args, "O!|(ii)i", 1885 | &Imagetype, &srcimage, &xdim, &ydim, &trueColor)) 1886 | { 1887 | if(!xdim) xdim = gdImageSX(srcimage->imagedata); 1888 | if(!ydim) ydim = gdImageSY(srcimage->imagedata); 1889 | #if GD2_VERS <= 1 1890 | trueColor = 0; 1891 | #endif 1892 | if (!trueColor){ 1893 | if(!(self->imagedata = gdImageCreate(xdim,ydim))) { 1894 | Py_DECREF(self); 1895 | return NULL; 1896 | } 1897 | } 1898 | #if GD2_VERS > 1 1899 | else 1900 | if(!(self->imagedata = gdImageCreateTrueColor(xdim,ydim))) { 1901 | Py_DECREF(self); 1902 | return NULL; 1903 | } 1904 | #endif 1905 | if(xdim == gdImageSX(srcimage->imagedata) && 1906 | ydim == gdImageSY(srcimage->imagedata)) 1907 | gdImageCopy(self->imagedata,srcimage->imagedata,0,0,0,0,xdim,ydim); 1908 | else 1909 | gdImageCopyResized(self->imagedata,srcimage->imagedata, 1910 | 0,0,0,0,xdim,ydim,gdImageSX(srcimage->imagedata), 1911 | gdImageSY(srcimage->imagedata)); 1912 | } else if(PyErr_Clear(), 1913 | PyArg_ParseTuple(args, "(ii)|i", &xdim, &ydim, &trueColor)) 1914 | { 1915 | if(!xdim || !ydim) { 1916 | PyErr_SetString(PyExc_ValueError, "dimensions cannot be 0"); 1917 | Py_DECREF(self); 1918 | return NULL; 1919 | } 1920 | #if GD2_VERS <= 1 1921 | trueColor = 0; 1922 | #endif 1923 | if (!trueColor){ 1924 | if(!(self->imagedata = gdImageCreate(xdim,ydim))) { 1925 | Py_DECREF(self); 1926 | return NULL; 1927 | } 1928 | } 1929 | #if GD2_VERS > 1 1930 | else 1931 | if(!(self->imagedata = gdImageCreateTrueColor(xdim,ydim))) { 1932 | Py_DECREF(self); 1933 | return NULL; 1934 | } 1935 | #endif 1936 | } else if(PyErr_Clear(), PyArg_ParseTuple(args, "s|s", &filename, &ext)) { 1937 | 1938 | if(!ext) { 1939 | if(!(ext = strrchr(filename,'.'))) { 1940 | PyErr_SetString(PyExc_IOError, 1941 | "need an extension to determine file type (.png|.jpeg|.jpg|.gd|.gd2|.xpm|.xbm)"); 1942 | Py_DECREF(self); 1943 | return NULL; 1944 | } 1945 | ext++; 1946 | } 1947 | 1948 | if(strcmp(ext, "xpm") == 0) { 1949 | #ifndef HAVE_LIBXPM 1950 | PyErr_SetString(PyExc_NotImplementedError, 1951 | "XPM Support Not Available"); 1952 | Py_DECREF(self); 1953 | return NULL; 1954 | #else 1955 | /* gdImageCreateFromXpm takes a filename rather than a FILE * */ 1956 | 1957 | if(!(self->imagedata = gdImageCreateFromXpm(filename))) { 1958 | PyErr_SetString(PyExc_IOError, "corrupt or invalid image file"); 1959 | Py_DECREF(self); 1960 | return(NULL); 1961 | } 1962 | 1963 | return self; 1964 | #endif 1965 | } 1966 | 1967 | if(!(fp = fopen(filename,"rb"))) { 1968 | PyErr_SetFromErrno(PyExc_IOError); 1969 | Py_DECREF(self); 1970 | return(NULL); 1971 | } 1972 | 1973 | for(i = 0; ext_table[i].ext != NULL; i++) { 1974 | 1975 | if(strcmp(ext, ext_table[i].ext) == 0) { 1976 | 1977 | if(!(self->imagedata = ext_table[i].func(fp))) { 1978 | fclose(fp); 1979 | PyErr_SetString(PyExc_IOError, 1980 | "corrupt or invalid image file (may be unsupported)"); 1981 | Py_DECREF(self); 1982 | return(NULL); 1983 | } 1984 | 1985 | fclose(fp); 1986 | return self; 1987 | } 1988 | } 1989 | 1990 | /* if we fall out, we didn't find the file type */ 1991 | 1992 | PyErr_SetString(PyExc_IOError, 1993 | "unsupported file type (only .gif|.png|.jpeg|.jpg|.gd|.gd2|.xbm|.xpm accepted)"); 1994 | 1995 | Py_DECREF(self); 1996 | return(NULL); 1997 | 1998 | } else if(PyErr_Clear(), 1999 | PyArg_ParseTuple(args, "Oz", &readObj, &ext)) 2000 | { 2001 | struct PyFileIfaceObj_gdIOCtx *ourIOCtx = NULL; 2002 | 2003 | if (!PyObject_HasAttrString(readObj, "read")) { 2004 | PyErr_SetString(ErrorObject, "non-Image objects must have a read() method"); 2005 | Py_DECREF(self); 2006 | return NULL; 2007 | } 2008 | 2009 | ourIOCtx = alloc_PyFileIfaceObj_IOCtx(readObj); 2010 | if (!ourIOCtx) { 2011 | PyErr_NoMemory(); 2012 | Py_DECREF(self); 2013 | return(NULL); 2014 | } 2015 | 2016 | for(i = 0; ext_table_ctx[i].ext != NULL; i++) { 2017 | 2018 | if(strcmp(ext, ext_table_ctx[i].ext) == 0) { 2019 | 2020 | if(!(self->imagedata = ext_table_ctx[i].func((gdIOCtxPtr)ourIOCtx))) { 2021 | free_PyFileIfaceObj_IOCtx(ourIOCtx); 2022 | PyErr_SetString(PyExc_IOError, 2023 | "corrupt or invalid image data (may be unsupported)"); 2024 | Py_DECREF(self); 2025 | return(NULL); 2026 | } 2027 | 2028 | free_PyFileIfaceObj_IOCtx(ourIOCtx); 2029 | return self; 2030 | } 2031 | } 2032 | 2033 | /* if we fall out, we didn't find the file type */ 2034 | 2035 | PyErr_SetString(PyExc_IOError, 2036 | "unsupported file type (only png, jpeg, gd, & gd2 can be read from an object)"); 2037 | 2038 | free_PyFileIfaceObj_IOCtx(ourIOCtx); 2039 | 2040 | Py_DECREF(self); 2041 | return(NULL); 2042 | } else { 2043 | PyErr_SetString(PyExc_ValueError, "invalid argument list"); 2044 | Py_DECREF(self); 2045 | return(NULL); 2046 | } 2047 | 2048 | return self; 2049 | } 2050 | 2051 | 2052 | static void image_dealloc(imageobject *self) 2053 | { 2054 | if(self->current_brush) { 2055 | Py_DECREF(self->current_brush); 2056 | } 2057 | 2058 | if(self->current_tile) { 2059 | Py_DECREF(self->current_tile); 2060 | } 2061 | 2062 | if(self->imagedata) gdImageDestroy(self->imagedata); 2063 | 2064 | PyObject_DEL(self); 2065 | } 2066 | 2067 | 2068 | static PyObject *image_getattr(PyObject *self, char *name) 2069 | { 2070 | return Py_FindMethod(image_methods, self, name); 2071 | } 2072 | 2073 | 2074 | static PyObject *image_print(PyObject *self, FILE *fp, int flags) 2075 | { 2076 | gdImagePtr im; 2077 | 2078 | im = ((imageobject *)self)->imagedata; 2079 | fprintf(fp,"<%dx%d image object at 0x%lx>",gdImageSX(im),gdImageSY(im), 2080 | (unsigned long)self); 2081 | return 0; 2082 | } 2083 | 2084 | 2085 | static PyTypeObject Imagetype = { 2086 | PyObject_HEAD_INIT(NULL) 2087 | 0, /*ob_size*/ 2088 | "image", /*tp_name*/ 2089 | sizeof(imageobject), /*tp_basicsize*/ 2090 | 0, /*tp_itemsize*/ 2091 | /* methods */ 2092 | (destructor)image_dealloc, /*tp_dealloc*/ 2093 | (printfunc)image_print, /*tp_print*/ 2094 | (getattrfunc)image_getattr, /*tp_getattr*/ 2095 | 0, /*tp_setattr*/ 2096 | 0, /*tp_compare*/ 2097 | 0, /*tp_repr*/ 2098 | 0, /*tp_as_number*/ 2099 | 0, /*tp_as_sequence*/ 2100 | 0, /*tp_as_mapping*/ 2101 | 0, /*tp_hash*/ 2102 | 0, /*tp_call */ 2103 | 0, /*tp_str */ 2104 | 0,0,0,0, /*tp_xxx1-4 */ 2105 | }; 2106 | 2107 | 2108 | static PyObject *gd_image(PyObject *self, PyObject *args) 2109 | { 2110 | return (PyObject *)newimageobject(args); 2111 | } 2112 | 2113 | 2114 | static PyObject *gd_fontSSize(PyObject *self, PyObject *args) 2115 | { 2116 | int font; 2117 | char *str; 2118 | int len; 2119 | 2120 | if(!PyArg_ParseTuple(args, "is", &font, &str)) 2121 | return NULL; 2122 | 2123 | if(font < 0 && font >= (sizeof(fonts)-1)) { 2124 | PyErr_SetString(PyExc_ValueError, "Font value not valid"); 2125 | return NULL; 2126 | } 2127 | 2128 | len = strlen(str); 2129 | 2130 | return Py_BuildValue("(ii)", len*(fonts[font].func()->w), 2131 | fonts[font].func()->h); 2132 | } 2133 | 2134 | 2135 | /* 2136 | ** List of methods defined in the module 2137 | */ 2138 | 2139 | static struct PyMethodDef gd_methods[] = { 2140 | {"image", gd_image, 1, 2141 | "image(image[,(w,h)] | file | file,type | (w,h))\n" 2142 | "create GD image from file of type gif, png, jpeg, gd, gd, gd2, xbm, or xpm.\n" 2143 | "the existing image, optionally resized to width w and height h\n" 2144 | "or blank with width w and height h"}, 2145 | {"fontstrsize", gd_fontSSize, 1, 2146 | "fontstrsize(font, string)\n" 2147 | "return a tuple containing the size in pixels of the given string in the\n" 2148 | "given font"}, 2149 | {NULL, NULL} /* sentinel */ 2150 | }; 2151 | 2152 | 2153 | /* Initialization function for the module (*must* be called init_gd) */ 2154 | 2155 | void DLLEXPORT init_gd(void) 2156 | { 2157 | PyObject *m, *d, *v; 2158 | int i=0; 2159 | 2160 | /* Create the module and add the functions */ 2161 | m = Py_InitModule("_gd", gd_methods); 2162 | 2163 | /* Add some symbolic constants to the module */ 2164 | d = PyModule_GetDict(m); 2165 | ErrorObject = PyString_FromString("gd.error"); 2166 | PyDict_SetItemString(d, "error", ErrorObject); 2167 | 2168 | /* add in the two font constants */ 2169 | while(fonts[i].name) { 2170 | v = Py_BuildValue("i", i); 2171 | PyDict_SetItemString(d, fonts[i++].name, v); 2172 | } 2173 | 2174 | /* and the standard gd constants */ 2175 | 2176 | v = Py_BuildValue("i", gdAntiAliased); 2177 | PyDict_SetItemString(d, "gdAntiAliased", v); 2178 | 2179 | v = Py_BuildValue("i", gdBrushed); 2180 | PyDict_SetItemString(d, "gdBrushed", v); 2181 | 2182 | v = Py_BuildValue("i", gdMaxColors); 2183 | PyDict_SetItemString(d, "gdMaxColors", v); 2184 | 2185 | v = Py_BuildValue("i", gdMaxColors); 2186 | PyDict_SetItemString(d, "gdMaxColors", v); 2187 | 2188 | v = Py_BuildValue("i", gdStyled); 2189 | PyDict_SetItemString(d, "gdStyled", v); 2190 | 2191 | v = Py_BuildValue("i", gdStyledBrushed); 2192 | PyDict_SetItemString(d, "gdStyledBrushed", v); 2193 | 2194 | v = Py_BuildValue("i", gdDashSize); 2195 | PyDict_SetItemString(d, "gdDashSize", v); 2196 | 2197 | v = Py_BuildValue("i", gdTiled); 2198 | PyDict_SetItemString(d, "gdTiled", v); 2199 | 2200 | v = Py_BuildValue("i", gdTransparent); 2201 | PyDict_SetItemString(d, "gdTransparent", v); 2202 | 2203 | #if GD2_VERS > 1 2204 | v = Py_BuildValue("i", gdArc); 2205 | PyDict_SetItemString(d, "gdArc", v); 2206 | 2207 | v = Py_BuildValue("i", gdChord); 2208 | PyDict_SetItemString(d, "gdChord", v); 2209 | 2210 | v = Py_BuildValue("i", gdPie); 2211 | PyDict_SetItemString(d, "gdPie", v); 2212 | 2213 | v = Py_BuildValue("i", gdNoFill); 2214 | PyDict_SetItemString(d, "gdNoFill", v); 2215 | 2216 | v = Py_BuildValue("i", gdEdged); 2217 | PyDict_SetItemString(d, "gdEdged", v); 2218 | 2219 | v = Py_BuildValue("i", GD_CMP_IMAGE); 2220 | PyDict_SetItemString(d, "CMP_IMAGE", v); 2221 | 2222 | v = Py_BuildValue("i", GD_CMP_NUM_COLORS); 2223 | PyDict_SetItemString(d, "CMP_NUM_COLORS", v); 2224 | 2225 | v = Py_BuildValue("i", GD_CMP_COLOR); 2226 | PyDict_SetItemString(d, "CMP_COLOR", v); 2227 | 2228 | v = Py_BuildValue("i", GD_CMP_SIZE_X); 2229 | PyDict_SetItemString(d, "CMP_SIZE_X", v); 2230 | 2231 | v = Py_BuildValue("i", GD_CMP_SIZE_Y); 2232 | PyDict_SetItemString(d, "CMP_SIZE_Y", v); 2233 | 2234 | v = Py_BuildValue("i", GD_CMP_TRANSPARENT); 2235 | PyDict_SetItemString(d, "CMP_TRANSPARENT", v); 2236 | 2237 | v = Py_BuildValue("i", GD_CMP_BACKGROUND); 2238 | PyDict_SetItemString(d, "CMP_BACKGROUND", v); 2239 | 2240 | v = Py_BuildValue("i", GD_CMP_INTERLACE); 2241 | PyDict_SetItemString(d, "CMP_INTERLACE", v); 2242 | 2243 | v = Py_BuildValue("i", GD_CMP_TRUECOLOR); 2244 | PyDict_SetItemString(d, "CMP_TRUECOLOR", v); 2245 | #endif 2246 | 2247 | /* Check for errors */ 2248 | if(PyErr_Occurred()) 2249 | Py_FatalError("can't initialize module gd"); 2250 | } 2251 | 2252 | 2253 | /* end of file. */ 2254 | --------------------------------------------------------------------------------