Anonymous avatar Anonymous committed 4609a00

Added sdl_pgame branch for the pure SDL based C library.

Comments (0)

Files changed (28)

+PREFIX ?= /usr/local
+LIBDIR ?= $(PREFIX)/lib
+INCDIR ?= $(PREFIX)/include
+
+CC ?= gcc
+CFLAGS ?= -W -Wall -g
+INCLUDES ?= -I/usr/local/include
+LIBS ?= 
+
+INSTALL ?= install
+INSTALL_DATA ?= $(INSTALL) -c -m 444
+
+LIBTOOL ?= libtool
+LTCOMPILE ?= $(LIBTOOL) --mode=compile $(CC)
+LTLINK ?= $(LIBTOOL) --mode=link --tag=CC
+LTINSTALL ?= $(LIBTOOL) --mode=install
+LTFINISH ?= $(LIBTOOL) --finish
+
+# Changed or added interfaces: CURRENT++ and AGE++ and REVISION = 0
+# binary compatibility broken: CURRENT++, REVISION and AGE = 0
+# interfaces stay the same as before: REVISION++
+#
+# CURRENT = most recent version of the library that the library supports
+# REVISION = implementation number of the current interface
+# AGE = number of versions back this version is still backwards
+# compatible with.
+CURRENT = 0
+AGE = 0
+REVISION = 0
+
+OBJDIR = obj
+BLDDIR = lib
+SRCDIR = src
+HEADERS = src/draw.h \
+	src/filters.h \
+	src/jpg.h \
+	src/pgpng.h \
+	src/scrap.h \
+	src/surface.h \
+	src/tga.h \
+	src/transform.h
+
+SRC_DRAW = draw.c
+TGT_DRAW = libSDL_pgdraw.la
+LT_DRAW = $(SRC_DRAW:%.c=$(OBJDIR)/%.lo)
+OBJ_DRAW = $(SRC_DRAW:%.c=%.o)
+CFLAGS_DRAW ?=
+LIBS_DRAW ?=
+
+SRC_SCRAP = scrap.c scrap_win.c scrap_x11.c
+TGT_SCRAP = libSDL_pgscrap.la
+LT_SCRAP = $(SRC_SCRAP:%.c=$(OBJDIR)/%.lo)
+OBJ_SCRAP = $(SRC_SCRAP:%.c=%.o)
+CFLAGS_SCRAP ?=
+LIBS_SCRAP ?= -lX11
+
+SRC_SURFACE = jpg.c png.c surface_blit.c surface_fill.c surface_save.c tga.c
+TGT_SURFACE = libSDL_pgsurface.la
+LT_SURFACE = $(SRC_SURFACE:%.c=$(OBJDIR)/%.lo)
+OBJ_SURFACE = $(SRC_SURFACE:%.c=%.o)
+CFLAGS_SURFACE ?= -DHAVE_JPG -DHAVE_PNG `pkg-config --cflags libpng`
+LIBS_SURFACE ?= -ljpeg `pkg-config --libs libpng`
+
+SRC_TRANSFORM = filters.c transform.c
+TGT_TRANSFORM = libSDL_pgtransform.la
+LT_TRANSFORM = $(SRC_TRANSFORM:%.c=$(OBJDIR)/%.lo)
+OBJ_TRANSFORM = $(SRC_TRANSFORM:%.c=%.o)
+CFLAGS_TRANSFORM ?=
+LIBS_TRANSFORM ?=
+
+SOURCES= $(SRC_DRAW) $(SRC_SCRAP) $(SRC_SURFACE) $(SRC_TRANSFORM)
+TARGETS= $(TGT_DRAW) $(TGT_SCRAP) $(TGT_SURFACE) $(TGT_TRANSFORM)
+
+SDLFLAGS = `sdl-config --cflags`
+SDLLIBS = `sdl-config --libs`
+LIBS += $(SDLLIBS) -lm
+CFLAGS += $(SDLFLAGS) $(INCLUDES)
+
+all: clean dirs $(TARGETS)
+
+dirs:
+	@mkdir -p $(OBJDIR) $(BLDDIR)
+
+# draw library
+$(OBJ_DRAW):
+	@$(LTCOMPILE) $(CFLAGS) $(CFLAGS_DRAW) \
+		-c $(SRCDIR)/$*.c -o $(OBJDIR)/$*.o
+
+$(TGT_DRAW): $(OBJ_DRAW)
+	$(LTLINK) $(LT_DRAW) -o $(BLDDIR)/$(TGT_DRAW) -rpath $(PREFIX) \
+		$(LIBS) $(LIBS_DRAW) \
+		-version-info $(CURRENT):$(REVISION):$(AGE)
+
+# scrap library
+$(OBJ_SCRAP):
+	@$(LTCOMPILE) $(CFLAGS) $(CFLAGS_SCRAP) \
+		-c $(SRCDIR)/$*.c -o $(OBJDIR)/$*.o
+
+$(TGT_SCRAP): $(OBJ_SCRAP)
+	$(LTLINK) $(LT_SCRAP) -o $(BLDDIR)/$(TGT_SCRAP) -rpath $(PREFIX) \
+		$(LIBS) $(LIBS_SCRAP) \
+		-version-info $(CURRENT):$(REVISION):$(AGE)
+
+# surface library
+$(OBJ_SURFACE):
+	@$(LTCOMPILE) $(CFLAGS) $(CFLAGS_SURFACE) \
+		-c $(SRCDIR)/$*.c -o $(OBJDIR)/$*.o
+
+$(TGT_SURFACE): $(OBJ_SURFACE)
+	$(LTLINK) $(LT_SURFACE) -o $(BLDDIR)/$(TGT_SURFACE) -rpath $(PREFIX) \
+		$(LIBS) $(LIBS_SURFACE) \
+		-version-info $(CURRENT):$(REVISION):$(AGE)
+
+# transform library
+$(OBJ_TRANSFORM):
+	@$(LTCOMPILE) $(CFLAGS) $(CFLAGS_TRANSFORM) \
+		-c $(SRCDIR)/$*.c -o $(OBJDIR)/$*.o
+
+$(TGT_TRANSFORM): $(OBJ_TRANSFORM)
+	$(LTLINK) $(LT_TRANSFORM) -o $(BLDDIR)/$(TGT_TRANSFORM) \
+		-rpath $(PREFIX) $(LIBS) $(LIBS_TRANSFORM) \
+		-version-info $(CURRENT):$(REVISION):$(AGE)
+
+install:
+	$(INSTALL) -d $(INCDIR)/SDL/pgame
+	$(INSTALL_DATA) $(HEADERS) $(INCDIR)/SDL/pgame
+	$(INSTALL) -d $(LIBDIR)
+	for target in $(TARGETS); do \
+		$(LTINSTALL) install -c -s $(BLDDIR)/$$target \
+			 $(LIBDIR)/$$target; \
+	done
+	$(LTFINISH) $(PREFIX)
+
+clean:
+	rm -rf $(SRCDIR)/*~ *~ $(OBJDIR) $(BLDDIR) $(TARGETS) .libs
+SDL_pgame Readme
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+/*
+  pygame - Python Game Library
+  Copyright (C) 2000-2001 Pete Shinners
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public
+  License along with this library; if not, write to the Free
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+#include <math.h>
+#include "pgdefines.h"
+#include "draw.h"
+#include "surface.h"
+
+#define FRAC(z) ((z) - trunc(z))
+#define INVFRAC(z) (1 - FRAC(z))
+
+#define DRAWPIX32(pixel,colorptr,br,blend,hasalpha)                     \
+    if (blend)                                                          \
+    {                                                                   \
+        int _x;                                                         \
+        float nbr = 1.0 - br;                                           \
+        _x = colorptr[0] * br + pixel[0] * nbr;                         \
+        pixel[0]= (_x > 254) ? 255: _x;                                 \
+        _x = colorptr[1] * br + pixel[1] * nbr;                         \
+        pixel[1]= (_x > 254) ? 255: _x;                                 \
+        _x = colorptr[2] * br + pixel[2] * nbr;                         \
+        pixel[2]= (_x > 254) ? 255: _x;                                 \
+        if (hasalpha)                                                   \
+            pixel[3] = pixel[0] + (br * 255) - (pixel[3] * br);         \
+    }                                                                   \
+    else                                                                \
+    {                                                                   \
+        pixel[0] = (Uint8)(colorptr[0] * br);                           \
+        pixel[1] = (Uint8)(colorptr[1] * br);                           \
+        pixel[2] = (Uint8)(colorptr[2] *br);                            \
+        if (hasalpha)                                                   \
+            pixel[3] = br * 255;                                        \
+    }
+
+/* the line clipping based heavily off of code from
+ * http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c
+ */
+#define LEFT_EDGE   0x1
+#define RIGHT_EDGE  0x2
+#define BOTTOM_EDGE 0x4
+#define TOP_EDGE    0x8
+#define INSIDE(a)   (!a)
+#define REJECT(a,b) (a&b)
+#define ACCEPT(a,b) (!(a|b))
+
+static int _compare_int (const void *a, const void *b);
+static int _encode (int x, int y, int left, int top, int right, int bottom);
+static int _fencode (float x, float y, int left, int top, int right,
+    int bottom);
+static int _clipline (SDL_Rect *clip, int x1, int _y1, int x2, int y2,
+    int *outpts);
+static int _clipaaline (SDL_Rect *clip, float x1, float _y1, float x2, float y2,
+    float *outpts);
+static void _drawline (SDL_Surface* surface, Uint32 color, int x1, int _y1,
+    int x2, int y2);
+static void _drawhorzline (SDL_Surface* surface, Uint32 color, int startx,
+    int y, int endx);
+static void _drawvertline (SDL_Surface* surface, Uint32 color, int x,
+    int starty, int endy);
+static int _drawlinewidth (SDL_Surface* surface, SDL_Rect *cliprect,
+    Uint32 color, int *pts, int width);
+static void _drawaaline (SDL_Surface* surface, Uint32 color, int x1, int _y1,
+    int x2, int y2, int blend);
+
+static int
+_compare_int (const void *a, const void *b)
+{
+    return (*(const int *)a) - (*(const int *)b);
+}
+
+static int
+_encode (int x, int y, int left, int top, int right, int bottom)
+{
+    int code = 0;
+    if (x < left) 
+        code |= LEFT_EDGE;
+    if (x > right)
+        code |= RIGHT_EDGE;
+    if (y < top)
+        code |= TOP_EDGE;
+    if (y > bottom)
+        code |= BOTTOM_EDGE;
+    return code;
+}
+
+static int
+_fencode (float x, float y, int left, int top, int right, int bottom)
+{
+    int code = 0;
+    if (x < left) 
+        code |= LEFT_EDGE;
+    if (x > right)
+        code |= RIGHT_EDGE;
+    if (y < top)
+        code |= TOP_EDGE;
+    if (y > bottom)
+        code |= BOTTOM_EDGE;
+    return code;
+}
+
+static int
+_clipline (SDL_Rect *clip, int x1, int _y1, int x2, int y2, int *outpts)
+{
+    int left = clip->x;
+    int right = clip->x + clip->w - 1;
+    int top = clip->y;
+    int bottom = clip->y + clip->h - 1;
+    int code1, code2;
+    int draw = 0;
+    int swaptmp;
+    float m; /*slope*/
+
+    if (!outpts)
+    {
+        SDL_SetError ("outpts argument NULL");
+        return 0;
+    }
+
+    while (1)
+    {
+        code1 = _encode (x1, _y1, left, top, right, bottom);
+        code2 = _encode (x2, y2, left, top, right, bottom);
+        if (ACCEPT (code1, code2))
+        {
+            draw = 1;
+            break;
+        }
+        else if (REJECT (code1, code2))
+            break;
+        else
+        {
+            if (INSIDE (code1))
+            {
+                swaptmp = x2;
+                x2 = x1;
+                x1 = swaptmp;
+                swaptmp = y2;
+                y2 = _y1;
+                _y1 = swaptmp;
+                swaptmp = code2;
+                code2 = code1;
+                code1 = swaptmp;
+            }
+            if (x2 != x1)
+                m = (y2 - _y1) / (float)(x2 - x1);
+            else
+                m = 1.0f;
+            if (code1 & LEFT_EDGE)
+            {
+                _y1 += (int)((left - x1) * m);
+                x1 = left;
+            }
+            else if (code1 & RIGHT_EDGE)
+            {
+                _y1 += (int)((right - x1) * m);
+                x1 = right;
+            }
+            else if (code1 & BOTTOM_EDGE)
+            {
+                if (x2 != x1)
+                    x1 += (int)((bottom - _y1) / m);
+                _y1 = bottom;
+            }
+            else if (code1 & TOP_EDGE)
+            {
+                if(x2 != x1)
+                    x1 += (int)((top - _y1) / m);
+                _y1 = top;
+            }
+        }
+    }
+    
+    if (draw)
+    {
+        outpts[0] = x1;
+        outpts[1] = _y1;
+        outpts[2] = x2;
+        outpts[3] = y2;
+    }
+    return draw;
+}
+
+static int
+_clipaaline (SDL_Rect *clip, float x1, float _y1, float x2, float y2,
+    float *outpts)
+{
+    int left = clip->x + 1;
+    int right = clip->x + clip->w - 2;
+    int top = clip->y + 1;
+    int bottom = clip->y + clip->h - 2;
+    int code1, code2;
+    int draw = 0;
+    float swaptmp;
+    int intswaptmp;
+    float m; /*slope*/
+
+    if (!outpts)
+    {
+        SDL_SetError ("outpts argument NULL");
+        return 0;
+    }
+
+    while (1)
+    {
+        code1 = _fencode (x1, _y1, left, top, right, bottom);
+        code2 = _fencode (x2, y2, left, top, right, bottom);
+        if (ACCEPT (code1, code2))
+        {
+            draw = 1;
+            break;
+        }
+        else if (REJECT (code1, code2))
+            break;
+        else
+        {
+            if (INSIDE (code1))
+            {
+                swaptmp = x2;
+                x2 = x1;
+                x1 = swaptmp;
+                swaptmp = y2;
+                y2 = _y1;
+                _y1 = swaptmp;
+                intswaptmp = code2;
+                code2 = code1;
+                code1 = intswaptmp;
+            }
+            if (x2 != x1)
+                m = (y2 - _y1) / (x2 - x1);
+            else
+                m = 1.0f;
+            if (code1 & LEFT_EDGE)
+            {
+                _y1 += ((float)left - x1) * m;
+                x1 = (float)left;
+            }
+            else if (code1 & RIGHT_EDGE)
+            {
+                _y1 += ((float)right - x1) * m;
+                x1 = (float)right;
+            }
+            else if (code1 & BOTTOM_EDGE)
+            {
+                if (x2 != x1)
+                    x1 += ((float)bottom - _y1) / m;
+                _y1 = (float)bottom;
+            }
+            else if (code1 & TOP_EDGE)
+            {
+                if(x2 != x1)
+                    x1 += ((float)top - _y1) / m;
+                _y1 = (float)top;
+            }
+        }
+    }
+    
+    if (draw)
+    {
+        outpts[0] = x1;
+        outpts[1] = _y1;
+        outpts[2] = x2;
+        outpts[3] = y2;
+    }
+    return draw;
+}
+
+static void
+_drawline (SDL_Surface* surface, Uint32 color, int x1, int _y1, int x2, int y2)
+{
+    int deltax, deltay, signx, signy;
+    int pixx, pixy;
+    int x = 0, y = 0;
+    int swaptmp;
+    Uint8 *pixel;
+    Uint8 *colorptr;
+    
+    deltax = x2 - x1;
+    deltay = y2 - _y1;
+    signx = (deltax < 0) ? -1 : 1;
+    signy = (deltay < 0) ? -1 : 1;
+    deltax = signx * deltax + 1;
+    deltay = signy * deltay + 1;
+
+    pixx = surface->format->BytesPerPixel;
+    pixy = surface->pitch;
+    pixel = ((Uint8*)surface->pixels) + pixx * x1 + pixy * _y1;
+    
+    pixx *= signx;
+    pixy *= signy;
+
+    if (deltax < deltay) /*swap axis if rise > run*/
+    {
+        swaptmp = deltax;
+        deltax = deltay;
+        deltay = swaptmp;
+        swaptmp = pixx;
+        pixx = pixy;
+        pixy = swaptmp;
+    }
+
+    switch(surface->format->BytesPerPixel)
+    {
+    case 1:
+        for (; x < deltax; x++, pixel += pixx)
+        {
+            *pixel = (Uint8) color;
+            y += deltay;
+            if (y >= deltax)
+            {
+                y -= deltax;
+                pixel += pixy;
+            }
+        }
+        break;
+    case 2:
+        for (; x < deltax; x++, pixel += pixx)
+        {
+            *(Uint16*)pixel = (Uint16)color;
+            y += deltay;
+            if (y >= deltax)
+            {
+                y -= deltax;
+                pixel += pixy;
+            }
+        }
+        break;
+    case 3:
+        if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+            color <<= 8;
+        colorptr = (Uint8*)&color;
+        for (; x < deltax; x++, pixel += pixx)
+        {
+            pixel[0] = colorptr[0];
+            pixel[1] = colorptr[1];
+            pixel[2] = colorptr[2];
+            y += deltay;
+            if (y >= deltax)
+            {
+                y -= deltax;
+                pixel += pixy;
+            }
+        }
+        break;
+    default:
+        for (; x < deltax; x++, pixel += pixx)
+        {
+            *(Uint32*)pixel = (Uint32)color;
+            y += deltay;
+            if (y >= deltax)
+            {
+                y -= deltax;
+                pixel += pixy;
+            }
+        }
+        break;
+    }
+}
+
+static void
+_drawhorzline (SDL_Surface* surface, Uint32 color, int startx, int y, int endx)
+{
+    Uint8 *pixel, *end;
+    Uint8 *colorptr;
+
+    if(startx == endx)
+    {
+        SET_PIXEL_AT (surface, surface->format, startx, y, color);
+        return;
+    }
+
+    pixel = ((Uint8*)surface->pixels) + surface->pitch * y;
+    if(startx < endx)
+    {
+        end = pixel + endx * surface->format->BytesPerPixel;
+        pixel += startx * surface->format->BytesPerPixel;
+    }
+    else
+    {
+        end = pixel + startx * surface->format->BytesPerPixel;
+        pixel += endx * surface->format->BytesPerPixel;
+    }
+
+    switch (surface->format->BytesPerPixel)
+    {
+    case 1:
+        for (; pixel <= end; ++pixel)
+        {
+            *pixel = (Uint8)color;
+        }
+        break;
+    case 2:
+        for (; pixel <= end; pixel += 2)
+        {
+            *(Uint16*)pixel = (Uint16)color;
+        }
+        break;
+    case 3:
+        if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+            color <<= 8;
+        colorptr = (Uint8*)&color;
+        for (; pixel <= end; pixel += 3)
+        {
+            pixel[0] = colorptr[0];
+            pixel[1] = colorptr[1];
+            pixel[2] = colorptr[2];
+        }
+        break;
+    default: /*case 4*/
+        for (; pixel <= end; pixel += 4)
+        {
+            *(Uint32*)pixel = color;
+        }
+        break;
+    }
+}
+
+static void
+_drawvertline (SDL_Surface* surface, Uint32 color, int x, int starty, int endy)
+{
+    Uint8 *pixel, *end;
+    Uint8 *colorptr;
+    Uint32 pitch = surface->pitch;
+
+    if (starty == endy)
+    {
+        SET_PIXEL_AT (surface, surface->format, x, starty, color);
+        return;
+    }
+
+    pixel = ((Uint8*)surface->pixels) + x * surface->format->BytesPerPixel;
+    if (starty < endy)
+    {
+        end = pixel + surface->pitch * endy;
+        pixel += surface->pitch * starty;
+    }
+    else
+    {
+        end = pixel + surface->pitch * starty;
+        pixel += surface->pitch * endy;
+    }
+
+    switch (surface->format->BytesPerPixel)
+    {
+    case 1:
+        for (; pixel <= end; pixel += pitch)
+        {
+            *pixel = (Uint8)color;
+        }
+        break;
+    case 2:
+        for (; pixel <= end; pixel += pitch)
+        {
+            *(Uint16*)pixel = (Uint16)color;
+        }
+        break;
+    case 3:
+        if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+            color <<= 8;
+        colorptr = (Uint8*)&color;
+        for (; pixel <= end; pixel += pitch)
+        {
+            pixel[0] = colorptr[0];
+            pixel[1] = colorptr[1];
+            pixel[2] = colorptr[2];
+        }
+        break;
+    default: /*case 4*/
+        for (; pixel <= end; pixel += pitch)
+        {
+            *(Uint32*)pixel = color;
+        }
+        break;
+    }
+}
+
+static int
+_drawlinewidth (SDL_Surface* surface, SDL_Rect *cliprect, Uint32 color,
+    int *pts, int width)
+{
+    int loop;
+    int xinc = 0, yinc = 0;
+    int newpts[4], tmp[4], range[4];
+    int anydrawn = 0;
+    
+    if (ABS (pts[0] - pts[2]) > ABS (pts[1] - pts[3]))
+        yinc = 1;
+    else
+        xinc = 1;
+    
+    if (_clipline (cliprect, pts[0], pts[1], pts[2], pts[3], newpts))
+    {
+        if (newpts[1] == newpts[3])
+            _drawhorzline (surface, color, newpts[0], newpts[1], newpts[2]);
+        else if (pts[0] == pts[2])
+            _drawvertline (surface, color, newpts[0], newpts[1], newpts[3]);
+        else
+            _drawline (surface, color, newpts[0], newpts[1], newpts[2],
+                newpts[3]);
+        
+        anydrawn = 1;
+        memcpy (range, newpts, sizeof(int) * 4);
+    }
+    else
+    {
+        range[0] = range[1] = 10000;
+        range[2] = range[3] = -10000;
+    }
+    
+    for (loop = 1; loop < width; loop += 2)
+    {
+        newpts[0] = pts[0] + xinc*(loop/2+1);
+        newpts[1] = pts[1] + yinc*(loop/2+1);
+        newpts[2] = pts[2] + xinc*(loop/2+1);
+        newpts[3] = pts[3] + yinc*(loop/2+1);
+        
+        if(_clipline (cliprect, newpts[0], newpts[1], newpts[2], newpts[3],
+                tmp))
+        {
+            memcpy (newpts, tmp, sizeof(int)*4);
+            if (newpts[1] == newpts[3])
+                _drawhorzline (surface, color, newpts[0], newpts[1], newpts[2]);
+            else if (pts[0] == pts[2])
+                _drawvertline (surface, color, newpts[0], newpts[1], newpts[3]);
+            else
+                _drawline (surface, color, newpts[0], newpts[1], newpts[2],
+                    newpts[3]);
+            
+            anydrawn = 1;
+            range[0] = MIN(newpts[0], range[0]);
+            range[1] = MIN(newpts[1], range[1]);
+            range[2] = MAX(newpts[2], range[2]);
+            range[3] = MAX(newpts[3], range[3]);
+        }
+
+        if(loop + 1 < width)
+        {
+            newpts[0] = pts[0] - xinc*(loop/2+1);
+            newpts[1] = pts[1] - yinc*(loop/2+1);
+            newpts[2] = pts[2] - xinc*(loop/2+1);
+            newpts[3] = pts[3] - yinc*(loop/2+1);
+            if (_clipline (cliprect, newpts[0], newpts[1], newpts[2], newpts[3],
+                    tmp))
+            {
+                memcpy (newpts, tmp, sizeof(int)*4);
+                if (newpts[1] == newpts[3])
+                    _drawhorzline (surface, color, newpts[0], newpts[1],
+                        newpts[2]);
+                else if (pts[0] == pts[2])
+                    _drawvertline (surface, color, newpts[0], newpts[1],
+                        newpts[3]);
+                else
+                    _drawline (surface, color, newpts[0], newpts[1], newpts[2],
+                        newpts[3]);
+
+                anydrawn = 1;
+                range[0] = MIN(newpts[0], range[0]);
+                range[1] = MIN(newpts[1], range[1]);
+                range[2] = MAX(newpts[2], range[2]);
+                range[3] = MAX(newpts[3], range[3]);
+            }
+        }
+    }
+
+    if (anydrawn)
+        memcpy (pts, range, sizeof(int)*4);
+    return anydrawn;
+}
+
+/* Adapted from
+ * http://freespace.virgin.net/hugo.elias/graphics/x_wuline.htm
+ */
+static void
+_drawaaline (SDL_Surface* surface, Uint32 color, int x1, int _y1, int x2,
+    int y2, int blend)
+{
+    float grad, xd, yd;
+    float xgap, ygap, xend, yend, xf, yf;
+    float brightness1, brightness2;
+    float swaptmp;
+    int x, y, ix1, ix2, iy1, iy2;
+    int pixx, pixy;
+    Uint8* pixel;
+    Uint8* pm = (Uint8*)surface->pixels;
+    Uint8* colorptr = (Uint8*)&color;
+    const int hasalpha = surface->format->Amask;
+
+    pixx = surface->format->BytesPerPixel;
+    pixy = surface->pitch;
+
+    xd = x2 - x1;
+    yd = y2 - _y1;
+
+    if (xd == 0 && yd == 0)
+    {
+        /* Single point. Due to the nature of the aaline clipping, this
+         * is less exact than the normal line. */
+        SET_PIXEL_AT (surface, surface->format, x1, _y1, color);
+        return;
+    }
+
+    if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+        color <<= 8;
+
+    if (fabs (xd) > fabs (yd))
+    {
+        if (x1 > x2)
+        {
+            swaptmp = x1;
+            x1 = x2;
+            x2 = swaptmp;
+            swaptmp = _y1;
+            _y1 = y2;
+            y2 = swaptmp;
+            xd = x2 - x1;
+            yd = y2 - _y1;
+        }
+        grad = yd / xd;
+        /* This makes more sense than trunc(x1+0.5) */
+        xend = trunc ((float)x1) + 0.5;
+        yend = _y1 + grad * (xend - x1);
+        xgap = INVFRAC ((float)x1);
+        ix1 = (int)xend;
+        iy1 = (int)yend;
+        yf = yend + grad;
+        brightness1 = INVFRAC (yend) * xgap;
+        brightness2 = FRAC (yend) * xgap;
+        pixel = pm + pixx * ix1 + pixy * iy1;
+        DRAWPIX32 (pixel, colorptr, brightness1, blend, hasalpha);
+        pixel += pixy;
+        DRAWPIX32 (pixel, colorptr, brightness2, blend, hasalpha);
+        xend = trunc ((float)x2) + 0.5;
+        yend = y2 + grad * (xend - x2);
+        /* this also differs from Hugo's description. */
+        xgap = FRAC ((float)x2);
+        ix2 = (int)xend;
+        iy2 = (int)yend;
+        brightness1 = INVFRAC (yend) * xgap;
+        brightness2 = FRAC (yend) * xgap;
+        pixel = pm + pixx * ix2 + pixy * iy2;
+        DRAWPIX32 (pixel, colorptr, brightness1, blend, hasalpha);
+        pixel += pixy;
+        DRAWPIX32 (pixel, colorptr, brightness2, blend, hasalpha);
+        for (x = ix1 + 1; x < ix2; ++x)
+        {
+            brightness1 = INVFRAC (yf);
+            brightness2 = FRAC (yf);
+            pixel = pm + pixx * x + pixy * (int)yf;
+            DRAWPIX32 (pixel, colorptr, brightness1, blend, hasalpha);
+            pixel += pixy;
+            DRAWPIX32 (pixel, colorptr, brightness2, blend, hasalpha);
+            yf += grad;
+        }
+    }
+    else
+    {
+        if (_y1 > y2)
+        {
+            swaptmp = _y1;
+            _y1 = y2;
+            y2 = swaptmp;
+            swaptmp = x1;
+            x1 = x2;
+            x2 = swaptmp;
+            yd = y2 - _y1;
+            xd = x2 - x1;
+        }
+        grad = xd / yd;
+        /* This makes more sense than trunc(x1+0.5) */
+        yend = trunc ((float)_y1) + .5;
+        xend = x1 + grad * (yend - _y1);
+        ygap = INVFRAC ((float)_y1);
+        iy1 = (int)yend;
+        ix1 = (int)xend;
+        xf = xend + grad;
+        brightness1 = INVFRAC (xend) * ygap;
+        brightness2 = FRAC (xend) * ygap;
+        pixel = pm + pixx * ix1 + pixy * iy1;
+        DRAWPIX32 (pixel, colorptr, brightness1, blend, hasalpha);
+        pixel += pixx;
+        DRAWPIX32 (pixel, colorptr, brightness2, blend, hasalpha);
+        yend = trunc ((float)y2) + 0.5;
+        xend = x2 + grad * (yend - y2);
+        ygap = FRAC ((float)y2);
+        iy2 = (int)yend;
+        ix2 = (int)xend;
+        brightness1 = INVFRAC (xend) * ygap;
+        brightness2 = FRAC (xend) * ygap;
+        pixel = pm + pixx * ix2 + pixy * iy2;
+        DRAWPIX32 (pixel, colorptr, brightness1, blend, hasalpha);
+        pixel += pixx;
+        DRAWPIX32 (pixel, colorptr, brightness2, blend, hasalpha);
+        for (y = iy1 + 1; y < iy2; ++y)
+        {
+            brightness1 = INVFRAC (xf);
+            brightness2 = FRAC (xf);
+            pixel = pm + pixx * (int)xf + pixy * y;
+            DRAWPIX32 (pixel, colorptr, brightness1, blend, hasalpha);
+            pixel += pixx;
+            DRAWPIX32 (pixel, colorptr, brightness2, blend, hasalpha);
+            xf += grad;
+        }
+    }
+}
+
+int
+pyg_draw_aaline (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int x1, int _y1, int x2, int y2, int blendargs, SDL_Rect *area)
+{
+    float pts[4] = { 0 };
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+
+    LOCK_SURFACE (surface, 0);
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    if (!_clipaaline (cliprect, (float)x1, (float)_y1, (float)x2, (float)y2,
+            pts))
+    {
+        UNLOCK_SURFACE (surface);
+        return 0;
+    }
+    _drawaaline (surface, color, pts[0], pts[1], pts[2], pts[3], blendargs);
+    UNLOCK_SURFACE (surface);
+
+    if (area)
+    {
+        area->x = (int) floor (pts[0]);
+        area->y = (int) floor (pts[1]);
+        area->w = (int) ceil (pts[2] - pts[0]);
+        area->h = (int) ceil (pts[3] - pts[1]);
+    }
+    
+    return 1;
+}
+
+int
+pyg_draw_line (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int x1, int _y1, int x2, int y2, int width, SDL_Rect *area)
+{
+    int pts[4] = { 0 };
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    
+    if (width < 1)
+    {
+        SDL_SetError ("width must not be < 1");
+        return 0;
+    }
+
+    LOCK_SURFACE (surface, 0);
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    if (width == 1)
+    {
+        if (!_clipline (cliprect, x1, _y1, x2, y2, pts))
+        {
+            UNLOCK_SURFACE (surface);
+            return 0;
+        }
+
+        if (pts[1] == pts[3])
+            _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+        else if (pts[0] == pts[2])
+            _drawvertline (surface, color, pts[0], pts[1], pts[3]);
+        else
+            _drawline (surface, color, pts[0], pts[1], pts[2], pts[3]);
+    }
+    else
+    {
+        pts[0] = x1;
+        pts[1] = _y1;
+        pts[2] = x2;
+        pts[3] = y2;
+        if (!_drawlinewidth (surface, cliprect, color, pts, width))
+        {
+            UNLOCK_SURFACE (surface);
+            return 0;
+        }
+    }
+
+    if (area)
+    {
+        area->x = pts[0];
+        area->y = pts[1];
+        area->w = pts[2] - pts[0];
+        area->h = pts[3] - pts[1];
+    }
+    UNLOCK_SURFACE (surface);
+    return 1;
+}
+
+int
+pyg_draw_aalines (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int blendargs, SDL_Rect *area)
+{
+    unsigned int i;
+    float xa, ya, xb, yb;
+    float pts[4] = { 0 };
+    int drawn = 0;
+    int rpts[4] = { 0 };
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (!xpts || !ypts)
+    {
+        if (!xpts)
+            SDL_SetError ("xpts argument NULL");
+        else if (!ypts)
+            SDL_SetError ("ypts argument NULL");
+        return 0;
+    }
+    if (count == 0)
+        return 0;
+
+    LOCK_SURFACE (surface, 0);
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    for (i = 0; i < count - 1; i++)
+    {
+        xa = xpts[i];
+        ya = ypts[i];
+        xb = xpts[i + 1];
+        yb = ypts[i + 1];
+
+        rpts[0] = MIN (xa, rpts[0]);
+        rpts[1] = MIN (ya, rpts[1]);
+        rpts[2] = MAX (xb, rpts[2]);
+        rpts[3] = MAX (yb, rpts[3]);
+        
+        if (_clipaaline (cliprect, xa, ya, xb, yb, pts))
+        {
+            drawn = 1;
+            _drawaaline (surface, color, (int)pts[0], (int)pts[1], (int)pts[2],
+                (int)pts[3], blendargs);
+        }
+    }
+
+    if (area)
+    {
+        area->x = rpts[0];
+        area->y = rpts[1];
+        area->w = rpts[2] - rpts[0];
+        area->h = rpts[3] - rpts[1];
+    }
+
+    UNLOCK_SURFACE (surface);
+    return drawn;
+}
+
+int
+pyg_draw_lines (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int width, SDL_Rect *area)
+{
+    unsigned int i;
+    int xa, ya, xb, yb;
+    int pts[4] = { 0 };
+    int drawn = 0;
+    int rpts[4] = { 0 };
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (width < 1)
+    {
+        SDL_SetError ("width must not be < 1");
+        return 0;
+    }
+    if (!xpts || !ypts)
+    {
+        if (!xpts)
+            SDL_SetError ("xpts argument NULL");
+        else if (!ypts)
+            SDL_SetError ("ypts argument NULL");
+        return 0;
+    }
+    if (count == 0)
+        return 0;
+
+    LOCK_SURFACE (surface, 0);
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    for (i = 0; i < count - 1; i++)
+    {
+        xa = xpts[i];
+        ya = ypts[i];
+        xb = xpts[i + 1];
+        yb = ypts[i + 1];
+
+        rpts[0] = MIN (xa, rpts[0]);
+        rpts[1] = MIN (ya, rpts[1]);
+        rpts[2] = MAX (xb, rpts[2]);
+        rpts[3] = MAX (yb, rpts[3]);
+        
+        if (width == 1)
+        {
+            if (_clipline (cliprect, xa, ya, xb, yb, pts))
+            {
+                drawn = 1;
+                if (pts[1] == pts[3])
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                else if (pts[0] == pts[2])
+                    _drawvertline (surface, color, pts[0], pts[1], pts[3]);
+                else
+                    _drawline (surface, color, pts[0], pts[1], pts[2], pts[3]);
+            }
+        }
+        else
+        {
+            pts[0] = xa;
+            pts[1] = ya;
+            pts[2] = xb;
+            pts[3] = yb;
+            if (_drawlinewidth (surface, cliprect, color, pts, width))
+                drawn = 1;
+        }
+    }
+
+    if (area)
+    {
+        area->x = rpts[0];
+        area->y = rpts[1];
+        area->w = rpts[2] - rpts[0];
+        area->h = rpts[3] - rpts[1];
+    }
+
+    UNLOCK_SURFACE (surface);
+    return 1;
+}
+
+int
+pyg_draw_filled_ellipse (SDL_Surface *surface, SDL_Rect *cliprect,
+    Uint32 color, int x, int y, int radx, int rady, SDL_Rect *area)
+{
+    int pts[4];
+    int ix, iy;
+    int h, i, j, k;
+    int oh, oi, oj, ok;
+    
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    LOCK_SURFACE (surface, 0);
+
+    if (radx == 0 && rady == 0)
+    {
+        /* Special case - draw a single pixel */
+        SET_PIXEL_AT (surface, surface->format, x, y, color);
+        if (area)
+        {
+            area->x = x;
+            area->y = y;
+            area->w = 1;
+            area->h = 1;
+        }
+        UNLOCK_SURFACE (surface);
+        return 1;
+    }
+    if (radx == 0)
+    {
+        /* Special case for radx = 0 - draw a vline */
+        if (_clipline (cliprect, x, y - rady, x, y + rady, pts))
+        {
+            _drawvertline (surface, color, pts[0], pts[1], pts[3]);
+            if (area)
+            {
+                area->x = pts[0];
+                area->y = pts[1];
+                area->w = 1;
+                area->h = pts[3];
+            }
+            UNLOCK_SURFACE (surface);
+            return 1;
+        }
+        UNLOCK_SURFACE (surface);
+        return 0;
+    }
+    if (rady == 0)
+    {
+        /* Special case for rady = 0 - draw a hline */
+        if (_clipline (cliprect, x - radx, y, x + radx, y, pts))
+        {
+            _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+            if (area)
+            {
+                area->x = pts[0];
+                area->y = pts[1];
+                area->w = pts[2];
+                area->h = 1;
+            }
+            UNLOCK_SURFACE (surface);
+            return 1;
+        }
+        UNLOCK_SURFACE (surface);
+        return 0;
+    }
+
+
+    oh = oi = oj = ok = 0xFFFF;
+    if (radx >= rady)
+    {
+        ix = 0;
+        iy = radx * 64;
+        
+        do
+        {
+            h = (ix + 8) >> 6;
+            i = (iy + 8) >> 6;
+            j = (h * rady) / radx;
+            k = (i * rady) / radx;
+            if ((ok != k) && (oj != k) && (k < rady))
+            {
+                if (_clipline (cliprect, x-h, y-k-1, x+h-1, y-k-1, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                if (_clipline (cliprect, x-h, y+k, x+h-1, y+k, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                ok = k;
+            }
+            if ((oj != j) && (ok != j) && (k != j))
+            {
+                if (_clipline (cliprect, x-i, y+j, x+i-1, y+j, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                if (_clipline (cliprect, x-i, y-j-1, x+i-1, y-j-1, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                oj = j;
+            }
+            ix = ix + iy / radx;
+            iy = iy - ix / radx;
+        }
+        while (i > h);
+    }
+    else
+    {
+        ix = 0;
+        iy = rady * 64;
+
+        do
+        {
+            h = (ix + 8) >> 6;
+            i = (iy + 8) >> 6;
+            j = (h * radx) / rady;
+            k = (i * radx) / rady;
+
+            if ((oi != i) && (oh != i) && (i < rady))
+            {
+                if (_clipline (cliprect, x-j, y+i, x+j-1, y+i, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                if (_clipline (cliprect, x-j, y-i-1, x+j-1, y-i-i, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                oi = i;
+            }
+            if ((oh != h) && (oi != h) && (i != h))
+            {
+                if (_clipline (cliprect, x-k, y+h, x+k-1, y+h, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                if (_clipline (cliprect, x-k, y-h-1, x+k-1, y-h-1, pts))
+                    _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+                oh = h;
+            }
+
+            ix = ix + iy / rady;
+            iy = iy - ix / rady;
+
+        } while(i > h);
+    }
+
+    if (area)
+    {
+        area->x = x - radx;
+        area->y = y - rady;
+        area->w = 2 * radx;
+        area->h = 2 * rady;
+    }
+    return 1;
+}
+
+int
+pyg_draw_ellipse (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int x, int y, int radx, int rady, SDL_Rect *area)
+{
+    int ix, iy;
+    int h, i, j, k;
+    int oh, oi, oj, ok;
+    int xmh, xph, ypk, ymk;
+    int xmi, xpi, ymj, ypj;
+    int xmj, xpj, ymi, ypi;
+    int xmk, xpk, ymh, yph;
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    LOCK_SURFACE (surface, 0);
+
+    if (radx == 0 && rady == 0)
+    {
+        /* Special case - draw a single pixel */
+        SET_PIXEL_AT (surface, surface->format, x, y, color);
+        if (area)
+        {
+            area->x = x;
+            area->y = y;
+            area->w = 1;
+            area->h = 1;
+        }
+        UNLOCK_SURFACE (surface);
+        return 1;
+    }
+    if (radx == 0)
+    {
+        /* Special case for radx = 0 - draw a vline */
+        int pts[4];
+        
+        if (_clipline (cliprect, x, y - rady, x, y + rady, pts))
+        {
+            _drawvertline (surface, color, pts[0], pts[1], pts[3]);
+            if (area)
+            {
+                area->x = pts[0];
+                area->y = pts[1];
+                area->w = 1;
+                area->h = pts[3];
+            }
+            UNLOCK_SURFACE (surface);
+            return 1;
+        }
+        UNLOCK_SURFACE (surface);
+        return 0;
+    }
+    if (rady == 0)
+    {
+        /* Special case for rady = 0 - draw a hline */
+        int pts[4];
+        if (_clipline (cliprect, x - radx, y, x + radx, y, pts))
+        {
+            _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+            if (area)
+            {
+                area->x = pts[0];
+                area->y = pts[1];
+                area->w = pts[2];
+                area->h = 1;
+            }
+            UNLOCK_SURFACE (surface);
+            return 1;
+        }
+        UNLOCK_SURFACE (surface);
+        return 0;
+    }
+    
+    oh = oi = oj = ok = 0xFFFF;
+    if (radx > rady)
+    {
+        ix = 0;
+        iy = radx * 64;
+        do
+        {
+            h = (ix + 16) >> 6;
+            i = (iy + 16) >> 6;
+            j = (h * rady) / radx;
+            k = (i * rady) / radx;
+            
+            if (((ok!=k) && (oj!=k)) || ((oj != j) && (ok != j)) || (k != j))
+            {
+                xph = x + h - 1;
+                xmh = x - h;
+                if (k > 0)
+                {
+                    ypk = y + k - 1;
+                    ymk = y - k;
+                    if (h > 0)
+                    {
+                        SET_PIXEL_AT(surface, surface->format, xmh, ypk, color);
+                        SET_PIXEL_AT(surface, surface->format, xmh, ymk, color);
+                    }
+                    SET_PIXEL_AT (surface, surface->format, xph, ypk, color);
+                    SET_PIXEL_AT (surface, surface->format, xph, ymk, color);
+                }
+                ok = k;
+                xpi = x + i - 1;
+                xmi = x - i;
+                if (j > 0)
+                {
+                    ypj = y + j - 1;
+                    ymj = y - j;
+                    SET_PIXEL_AT (surface, surface->format, xmi, ypj, color);
+                    SET_PIXEL_AT (surface, surface->format, xpi, ypj, color);
+                    SET_PIXEL_AT (surface, surface->format, xmi, ymj, color);
+                    SET_PIXEL_AT (surface, surface->format, xpi, ymj, color);
+                }
+                oj = j;
+            }
+            ix = ix + iy / radx;
+            iy = iy - ix / radx;
+                        
+        }
+        while (i > h);
+    }
+    else
+    {
+        ix = 0;
+        iy = rady * 64;
+        do
+        {
+            h = (ix + 32) >> 6;
+            i = (iy + 32) >> 6;
+            j = (h * radx) / rady;
+            k = (i * radx) / rady;
+
+            if (((oi!=i) && (oh!=i)) || ((oh!=h) && (oi!=h) && (i!=h)))
+            {
+                xmj = x -j;
+                xpj = x + j - 1;
+                if (i > 0)
+                {
+                    ypi = y + i - 1;
+                    ymi = y - i;
+                    if (j > 0)
+                    {
+                        SET_PIXEL_AT(surface, surface->format, xmj, ypi, color);
+                        SET_PIXEL_AT(surface, surface->format, xmj, ymi, color);
+                    }
+                    SET_PIXEL_AT (surface, surface->format, xpj, ypi, color);
+                    SET_PIXEL_AT (surface, surface->format, xpj, ymi, color);
+                }
+                oi = i;
+                xmk = x - k;
+                xpk = x + k - 1;
+                if (h > 0)
+                {
+                    yph = y + h - 1;
+                    ymh = y - h;
+                    SET_PIXEL_AT (surface, surface->format, xmk, yph, color);
+                    SET_PIXEL_AT (surface, surface->format, xpk, yph, color);
+                    SET_PIXEL_AT (surface, surface->format, xmk, ymh, color);
+                    SET_PIXEL_AT (surface, surface->format, xpk, ymh, color);
+                }
+                oh = h;
+            }
+            ix = ix + iy / rady;
+            iy = iy - ix / rady;
+        }
+        while (i > h);
+    }
+    UNLOCK_SURFACE (surface);
+
+    if (area)
+    {
+        area->x = x - radx;
+        area->y = y - rady;
+        area->w = 2 * radx;
+        area->h = 2 * rady;
+    }
+
+    return 1;
+}
+
+int
+pyg_draw_arc (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color, int x,
+    int y, int rad1, int rad2, double anglestart, double anglestop,
+    SDL_Rect *area)
+{
+    double a, step;
+    int xlast, xnext, ylast, ynext;
+    int rpts[4] = { 0 };
+    int drawn = 0;
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+
+    if (rad1 < rad2)
+    {
+        if (rad1 < 1.0e-4)
+            step = 1.0;
+        else
+            step = asin (2.0 / rad1);
+    }
+    else
+    {
+        if (rad2 < 1.0e-4)
+            step = 1.0;
+        else
+            step = asin (2.0 / rad2);
+    }
+
+    if (step < 0.05)
+        step = 0.05;
+
+    LOCK_SURFACE (surface, 0);
+
+    xlast = x + cos (anglestart) * rad1;
+    ylast = y - sin (anglestart) * rad2;
+    for (a = anglestart + step; a <= anglestop; a += step)
+    {
+        int pts[4];
+        xnext = x + cos (a) * rad1;
+        ynext = y - sin (a) * rad2;
+        pts[0] = xlast;
+        pts[1] = ylast;
+        pts[2] = xnext;
+        pts[3] = ynext;
+
+        rpts[0] = MIN (xlast, rpts[0]);
+        rpts[1] = MIN (ylast, rpts[1]);
+        rpts[2] = MAX (xnext, rpts[2]);
+        rpts[3] = MAX (ynext, rpts[3]);
+
+        if (_clipline (cliprect, xlast, ylast, xnext, ynext, pts))
+        {
+            drawn = 1;
+            if (pts[1] == pts[3])
+                _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+            else if (pts[0] == pts[2])
+                _drawvertline (surface, color, pts[0], pts[1], pts[3]);
+            else
+                _drawline (surface, color, pts[0], pts[1], pts[2], pts[3]);
+        }
+        xlast = xnext;
+        ylast = ynext;
+    }
+
+    if (area)
+    {
+        area->x = rpts[0];
+        area->y = rpts[1];
+        area->w = rpts[2] - rpts[0];
+        area->h = rpts[3] - rpts[1];
+    }
+    UNLOCK_SURFACE (surface);
+    return 1;
+}
+
+int
+pyg_draw_aapolygon (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int blendargs, SDL_Rect *area)
+{
+    unsigned int i;
+    int anydrawn = 0;
+    float minx, maxx, miny, maxy;
+    float xa, ya, xb, yb, pts[4];
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (!xpts || !ypts)
+    {
+        if (!xpts)
+            SDL_SetError ("xpts argument NULL");
+        else if (!ypts)
+            SDL_SetError ("ypts argument NULL");
+        return 0;
+    }
+    if (count == 0)
+        return 0;
+
+    LOCK_SURFACE (surface, 0);
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    minx = maxx = miny = maxy = 0;
+    for (i = 1; i < count; i++)
+    {
+        xa = xpts[i - 1];
+        xb = xpts[i];
+        ya = ypts[i - 1];
+        yb = ypts[i];
+
+        minx = MIN (xa, MIN (xb, minx));
+        miny = MIN (ya, MIN (yb, miny));
+        maxx = MAX (xa, MAX (xb, maxx));
+        maxy = MAX (ya, MAX (yb, maxy));
+
+        if (_clipaaline (cliprect, xa, ya, xb, yb, pts))
+        {
+            printf ("pts: %f, %f, %f, %f\n", pts[0],pts[1],pts[2],pts[3]);
+            _drawaaline (surface, color, (int)pts[0], (int)pts[1], (int)pts[2],
+                (int)pts[3], blendargs);
+            anydrawn = 1;
+        }
+    }
+
+    /* Connect the first and last line */
+    xa = xpts[0];
+    ya = ypts[0];
+    xb = xpts[count - 1];
+    yb = ypts[count - 1];
+    if (_clipaaline (cliprect, xa, ya, xb, yb, pts))
+    {
+        _drawaaline (surface, color, (int)pts[0], (int)pts[1], (int)pts[2],
+            (int)pts[3], blendargs);
+        anydrawn = 1;
+    }
+    
+    UNLOCK_SURFACE (surface);
+
+    if (area)
+    {
+        area->x = (int) floor (minx);
+        area->y = (int) floor (miny);
+        area->w = (int) ceil (maxx - minx);
+        area->h = (int) ceil (maxy - miny);
+    }
+    return anydrawn;
+}
+
+int
+pyg_draw_polygon (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int width, SDL_Rect *area)
+{
+    int anydrawn = 0;
+    int minx, maxx, miny, maxy;
+    int pts[4];
+    unsigned int i;
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (width < 1)
+    {
+        SDL_SetError ("width must not be < 1");
+        return 0;
+    }
+    if (!xpts || !ypts)
+    {
+        if (!xpts)
+            SDL_SetError ("xpts argument NULL");
+        else if (!ypts)
+            SDL_SetError ("ypts argument NULL");
+        return 0;
+    }
+    if (count == 0)
+        return 0;
+
+    LOCK_SURFACE (surface, 0);
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    minx = maxx = miny = maxy = 0;
+    for (i = 1; i < count; i++)
+    {
+        pts[0] = xpts[i - 1];
+        pts[2] = xpts[i];
+        pts[1] = ypts[i - 1];
+        pts[3] = ypts[i];
+
+        minx = MIN (pts[0], MIN (pts[2], minx));
+        miny = MIN (pts[1], MIN (pts[3], miny));
+        maxx = MAX (pts[0], MAX (pts[2], maxx));
+        maxy = MAX (pts[1], MAX (pts[3], maxy));
+
+        if (_drawlinewidth (surface, cliprect, color, pts, width))
+            anydrawn = 1;
+
+    }
+
+    /* Connect the first and last line */
+    pts[0] = xpts[0];
+    pts[1] = ypts[0];
+    pts[2] = xpts[count - 1];
+    pts[3] = ypts[count - 1];
+    if (_drawlinewidth (surface, cliprect, color, pts, width))
+        anydrawn = 1;
+    
+    UNLOCK_SURFACE (surface);
+
+    if (area)
+    {
+        area->x = minx;
+        area->y = miny;
+        area->w = maxx - minx;
+        area->h = maxy - miny;
+    }
+    return anydrawn;
+}
+
+int
+pyg_draw_filled_polygon (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, SDL_Rect *area)
+{
+    unsigned int i;
+    int y;
+    int miny, maxy, minx, maxx;
+    int x1, _y1, x2, y2;
+    unsigned int ind1, ind2;
+    int ints, pts[4];
+    int *polyints;
+
+    if (!surface)
+    {
+        SDL_SetError ("surface argument NULL");
+        return 0;
+    }
+    if (!xpts || !ypts)
+    {
+        if (!xpts)
+            SDL_SetError ("xpts argument NULL");
+        else if (!ypts)
+            SDL_SetError ("ypts argument NULL");
+        return 0;
+    }
+    if (count == 0)
+        return 0;
+
+    if (!cliprect)
+        cliprect = &surface->clip_rect;
+
+    polyints = malloc (sizeof (int) * count);
+    if (!polyints)
+    {
+        SDL_SetError ("could not allocate memory");
+        return 0;
+    }
+
+    LOCK_SURFACE (surface, 0);
+
+    /* Determine X and Y maxima */
+    miny = maxy = ypts[0];
+    minx = maxx = xpts[0];
+    for (i = 1; i < count; i++)
+    {
+        minx = MIN (minx, xpts[i]);
+        maxx = MAX (maxx, xpts[i]);
+        miny = MIN (miny, ypts[i]);
+        maxy = MAX (maxy, ypts[i]);
+    }
+
+    /* Draw, scanning y */
+    for (y = miny; y <= maxy; y++)
+    {
+        ints = 0;
+        for (i = 0; i < count; i++)
+        {
+            if (i == 0)
+            {
+                ind1 = count - 1;
+                ind2 = 0;
+            }
+            else
+            {
+                ind1 = i - 1;
+                ind2 = i;
+            }
+            
+            _y1 = ypts[ind1];
+            y2 = ypts[ind2];
+            if (_y1 < y2)
+            {
+                x1 = xpts[ind1];
+                x2 = xpts[ind2];
+            }
+            else if (_y1 > y2)
+            {
+                y2 = ypts[ind1];
+                _y1 = ypts[ind2];
+                x2 = xpts[ind1];
+                x1 = xpts[ind2];
+            }
+            else
+            {
+                continue;
+            }
+            
+            if ((y >= _y1) && (y < y2))
+            {
+                polyints[ints++] = (y - _y1) * (x2 - x1) / (y2 - _y1) + x1;
+            }
+            else if ((y == maxy) && (y > _y1) && (y <= y2))
+            {
+                polyints[ints++] = (y - _y1) * (x2 - x1) / (y2 - _y1) + x1;
+            }
+        }
+
+        qsort (polyints, (size_t) ints, sizeof(int), _compare_int);
+
+        for (i = 0; i < ((unsigned int)ints); i += 2)
+        {
+            if (_clipline (cliprect, polyints[i], y, polyints[i + 1], y, pts))
+                _drawhorzline (surface, color, pts[0], pts[1], pts[2]);
+        }
+    }
+
+    free (polyints);
+    UNLOCK_SURFACE (surface);
+
+    if (area)
+    {
+        area->x = minx;
+        area->y = miny;
+        area->w = maxx - minx;
+        area->h = maxy - miny;
+    }
+    return 1;
+}
+/*
+  pygame - Python Game Library
+  Copyright (C) 2000-2001 Pete Shinners
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public
+  License along with this library; if not, write to the Free
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+#ifndef _PYGAME_DRAW_H_
+#define _PYGAME_DRAW_H_
+
+#include <SDL.h>
+
+#define LOCK_SURFACE(x,ret)                                             \
+    if (SDL_MUSTLOCK (x))                                               \
+    {                                                                   \
+        if (SDL_LockSurface (x) == -1)                                  \
+            return (ret);                                               \
+    }
+
+#define UNLOCK_SURFACE(x)                       \
+    if (SDL_MUSTLOCK (x))                       \
+        SDL_UnlockSurface (x);
+
+int
+pyg_draw_aaline (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int x1, int _y1, int x2, int y2, int blendargs, SDL_Rect *area);
+
+int
+pyg_draw_line (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int x1, int _y1, int x2, int y2, int width, SDL_Rect *area);
+
+int
+pyg_draw_aalines (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int blendargs, SDL_Rect *area);
+
+int
+pyg_draw_lines (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int width, SDL_Rect *area);
+
+int
+pyg_draw_filled_ellipse (SDL_Surface *surface, SDL_Rect *cliprect,
+    Uint32 color, int x, int y, int radx, int rady, SDL_Rect *area);
+
+int
+pyg_draw_ellipse (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int x, int y, int radx, int rady, SDL_Rect *area);
+
+int
+pyg_draw_arc (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color, int x,
+    int y, int rad1, int rad2, double anglestart, double anglestop,
+    SDL_Rect *area);
+
+int
+pyg_draw_aapolygon (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int blendargs, SDL_Rect *area);
+
+int
+pyg_draw_polygon (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, int width, SDL_Rect *area);
+
+int
+pyg_draw_filled_polygon (SDL_Surface *surface, SDL_Rect *cliprect, Uint32 color,
+    int *xpts, int *ypts, unsigned int count, SDL_Rect *area);
+
+#endif /* _PYGAME_DRAW_H_ */
+/*
+  pygame - Python Game Library
+  Copyright (C) 2000-2001  Pete Shinners
+  Copyright (C) 2007  Rene Dudfield, Richard Goedeken 
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU