summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRomain Beauxis <toots@rastageeks.org>2011-10-09 15:40:04 +0200
committerRomain Beauxis <toots@rastageeks.org>2011-10-09 15:40:04 +0200
commit1949b73c539957a5c5f02e9b3fde5ed9d2401f91 (patch)
treed3c2e8c2ef3fcca7a60aff85e97e5619b5f7f7e3
Import gd4o_1.0~alpha5.orig.tar.gz
[dgit import orig gd4o_1.0~alpha5.orig.tar.gz]
-rw-r--r--BUGS10
-rw-r--r--CHANGES105
-rw-r--r--INSTALL66
-rw-r--r--LICENSE510
-rw-r--r--META5
-rw-r--r--Makefile107
-rw-r--r--Makefile.orig63
-rw-r--r--README73
-rw-r--r--README.ocamlgd30
-rw-r--r--TODO5
-rw-r--r--doc/api-xref.html2658
-rw-r--r--doc/api-xref.xml1626
-rw-r--r--doc/manual.txt127
-rw-r--r--font_list.txt7
-rw-r--r--gd.ml650
-rw-r--r--gd.mli232
-rw-r--r--gdstubs.c1009
-rw-r--r--gdtest.ml581
-rw-r--r--samples/driver01-8.pngbin0 -> 35880 bytes
-rw-r--r--samples/driver01-t.pngbin0 -> 75851 bytes
-rw-r--r--samples/kamokamogawa04-8.pngbin0 -> 94536 bytes
-rw-r--r--samples/kamokamogawa04-t.pngbin0 -> 235122 bytes
-rw-r--r--samples/yotei02-8.pngbin0 -> 116313 bytes
-rw-r--r--samples/yotei02-t.pngbin0 -> 285310 bytes
24 files changed, 7864 insertions, 0 deletions
diff --git a/BUGS b/BUGS
new file mode 100644
index 0000000..2b2ce8b
--- /dev/null
+++ b/BUGS
@@ -0,0 +1,10 @@
+GD4O - known bugs as of Aug. 21, 2003
+=====================================
+
+* Antialiased drawing is dreadfully slow.
+
+* Antialiased lines of width > 1 appear as several overlapping lines rather
+ than a single wide line (may be a bug in GD itself).
+
+* When attempting to dump several images to an out_channel, the last one
+ is not written.
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..b05610c
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,105 @@
+Changes in version 1.0a5, 2003-11-24
+====================================
+
+* Copying and resizing
+ #image#copy <-> gdImageCopy
+ #image#copy_resized <-> gdImageCopyResized
+ #image#copy_resampled <-> gdImageCopyResampled
+ #image#copy_rotated <-> gdImageCopyRotated
+ #image#copy_merge <-> gdImageCopyMerge
+ #image#copy_merge_gray <-> gdImageCopyMergeGray
+ #image#palette_copy <-> gdImagePaletteCopy
+
+* Added tests for all above functions
+
+
+Changes in version 1.0a4, 2003-08-21
+====================================
+
+* TrueType font support
+ #image#string_ftex <-> gdImageStringFTEx
+ ftex_bbox <-> gdImageStringFTEx (with null gdImagePtr)
+ - This is a partial implementation! gdImageStringFTEx does two
+ important things: render multiline text blocks, and render multi-
+ byte character strings (e.g. Chinese & Japanese). The C wrapper
+ should support both of these functions, but the OCaml function
+ currently requires a normal OCaml string, which means ASCII. So
+ we need to figure out how to integrate Unicode support to the
+ OCaml code.
+
+* ft_bbox & ftex_bbox are now global functions, rather than methods
+ of the image class. This way you can size your text before you
+ create an image.
+
+* Added test for #image#string_ftex
+
+* Added SAFER compile flag to enable safer execution (with a potential
+ loss in performance).
+
+
+Changes in version 1.0a3, 2003-08-11
+====================================
+
+* TrueType font support
+ #image#string_ft <-> gdImageStringFT
+ #image#ft_bbox <-> gdImageStringFT (with null gdImagePtr)
+
+* Continued improvements in test program.
+
+
+Changes in version 1.0a2, 2003-08-05
+====================================
+
+* New drawing methods:
+ #image#closed_arc <-> gdImageFilledArc
+ #image#closed_chord <-> gdImageFilledArc
+* New property settings:
+ #image#set_antialiased_dont_blend
+ <-> gdImageSetAntiAliasedDontBlend
+ #image#set_brush <-> gdImageSetBrush
+ #image#set_tiled <-> gdImageSetTile
+ #image#set_thickness <-> gdImageSetThickness
+ #image#set_clip <-> gdImageSetClip
+* Truecolor images now supported:
+ create_truecolor to create new truecolor image; also,
+ open_png now tests for truecolor.
+* Changed implementation of color type from class to record.
+* More improvements in test program.
+
+
+Changes in version 1.0a1, 2003-08-04 (vs. OCamlGD 0.7)
+======================================================
+
+* Implemented new drawing methods:
+ #image#filled_ellipse <-> gdImageFilledEllipse
+ #image#polygon <-> gdImagePolygon
+ #image#filled_polygon <-> gdImageFilledPolygon
+* Corrected errors in C wrapper drawing functions:
+ ml_image_rect and ml_image_frect drew diagonal lines instead
+ of rectangles. Fixed.
+* Implemented antialiasing:
+ #image#set_antialiased to set antialias color
+ #color#allocator#antialiased to retrieve antialiased color
+* New Makefile uses Findlib
+ (saved old Makefile as Makefile.orig)
+* Added API cross-reference showing status of all API functions:
+ see 'doc/api-xref.html'.
+* New test program ('gdtest.ml') exercises the following functions:
+ create
+ #image#colors
+ #color_allocator#white
+ #color_allocator#create
+ #image#set_antialiased
+ #color_allocator#antialiased
+ #image#rectangle
+ #image#filled_rectangle
+ #image#polygon
+ #image#filled_polygon
+ #image#arc
+ #image#filled_ellipse
+ #image#string
+ #image#save_as_png
+ #image#save_as_jpeg
+ #image#out_as_png
+ #image#out_as_jpeg
+* Removed overly-obvious comments in gd.mli.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..9bf7851
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,66 @@
+How to Compile and Install GD4O
+===============================
+
+Version 1.0a5, November 24, 2003
+
+
+The following instructions are for installation with Findlib. In case
+you prefer not to use Findlib, I have included the old Makefile as
+'Makefile.orig'; it may work with little or no change.
+
+Prerequisites
+-------------
+ * Version numbers are those used in development. Earlier versions *
+ * have not been tested, and may or may not work. *
+
+OCaml 3.06/3.07
+ <http://caml.inria.fr/>
+Findlib 0.8.1/0.9
+ <http://www.ocaml-programming.de/packages/>
+GD 2.0.15
+ <http://www.boutell.com/gd/>
+
+OS: Linux (developed on Debian GNU/Linux 3.0); may work on other POSIX
+ systems. I hope to make the package portable to Windows in the future.
+
+
+Compiling and installing
+------------------------
+
+If you have properly installed the required packages, installation
+should be very easy.
+
+Edit the Makefile to reflect your configuration, then run.
+
+ make all
+ make opt # optional, but highly recommended
+ make test
+ -OR-
+ make test.opt
+ -(assuming the test was successful)
+ make install
+
+Running the test suite--"make test"--is strongly recommended. See "Test
+script" below for more information.
+
+You may also wish to
+
+ make docs
+
+which will generate OCaml API docs in the doc/ subdirectory.
+
+
+Test script
+-----------
+
+This package includes a test script that exercises most functions of the
+API in at least rudimentary fashion. You can run the script with the
+command 'make test'.
+
+At the risk of stating the obvious: the powers of automated testing are
+very limited when applied to a graphics package of this kind. A
+successful test result means simply that the test was completed with no
+exceptions; there is no guarantee that the output is correct.
+
+Therefore, to be sure that GD4O will produce the desired results, you
+should at least visually inspect all files produced by the test routine.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cf9b6b9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,510 @@
+
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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.
+^L
+ 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
+^L
+ 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!
+
+
diff --git a/META b/META
new file mode 100644
index 0000000..9846512
--- /dev/null
+++ b/META
@@ -0,0 +1,5 @@
+name = "gd"
+version = "1.0a5"
+description = "Wrapper for the GD graphics library"
+archive(byte) = "gd.cma"
+archive(native) = "gd.cmxa"
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..8ea6205
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,107 @@
+PKGNAME = gd
+
+OCAMLC=ocamlc
+OCAMLOPT=ocamlopt
+OCAMLMKLIB=ocamlmklib
+OCAMLFIND=ocamlfind
+OCAMLDOC=ocamldoc -html
+OCAMLLIB=`$(OCAMLC) -where`
+
+TASKINSTALL = $(OCAMLFIND) install $(NAME) $(TASKINSTALLOPTS)
+
+# This turns on some checks that should make the library more secure but
+# may degrade performance. If you're more concerned about performance than
+# security, comment out the next line.
+SAFETY_FLAG = -DSAFER
+# If you don't have libjpeg, comment out the 'JPEG_LIB' line.
+# Similarly for Freetype2.
+JPEG_LIB = -ljpeg
+FT2_LIB = -lfreetype
+CC=gcc
+CINCLUDES=-I$(OCAMLLIB) -I/usr/include
+LIBS=-lgd -lpng -lz $(JPEG_LIB) $(FT2_LIB)
+ifdef JPEG_LIB
+JPEG_FLAG = -DHAVE_JPEG
+endif
+ifdef FT2_LIB
+FT2_FLAG = -DHAVE_FREETYPE
+endif
+CFLAGS = $(CINCLUDES) -W -Wall -Wno-unused \
+ $(JPEG_FLAG) $(FT2_FLAG) $(SAFETY_FLAG)
+
+OCAMLCFLAGS=-labels -unsafe
+OCAMLOPTFLAGS=-labels -inline 2
+
+BYTE_OBJECTS = gd.cmi gd.cmo
+NAT_OBJECTS = gd.cmi gd.cmx
+C_OBJECTS = gdstubs.o
+STUBLIBS = dllocamlgd.so libocamlgd.a
+BYTE_ARCHIVE = gd.cma
+NAT_ARCHIVE = gd.cmxa
+
+
+.PHONY : all opt install uninstall test test.opt docs
+all : $(BYTE_ARCHIVE)
+opt : $(NAT_ARCHIVE)
+
+
+$(BYTE_ARCHIVE) : $(BYTE_OBJECTS) $(C_OBJECTS)
+ $(OCAMLMKLIB) -o gd gd.cmo gdstubs.o -oc ocamlgd $(LIBS)
+$(NAT_ARCHIVE) : $(NAT_OBJECTS) $(C_OBJECTS)
+ $(OCAMLMKLIB) -o gd gd.cmx gdstubs.o -oc ocamlgd $(LIBS)
+
+
+gd.cmx: gd.cmi gd.ml
+ $(OCAMLOPT) $(OCAMLOPTFLAGS) -c gd.ml
+
+gd.cmo: gd.cmi gd.ml
+ $(OCAMLC) $(OCAMLCFLAGS) -c gd.ml
+
+gd.cmi: gd.mli
+ $(OCAMLC) $(OCAMLCFLAGS) -c gd.mli
+
+
+gdstubs.o : gdstubs.c
+ $(CC) $(CFLAGS) -c gdstubs.c
+
+
+test : gdtest
+ ./gdtest gdtest.log
+
+test.opt : gdtest.opt
+ ./gdtest.opt gdtest.log
+
+gdtest: gdtest.cmo
+ $(OCAMLC) -o gdtest -dllpath . str.cma gd.cma gdtest.cmo
+
+gdtest.cmo: all gdtest.ml
+ $(OCAMLC) $(OCAMLCFLAGS) -c gdtest.ml
+
+gdtest.opt: gdtest.cmx
+ $(OCAMLOPT) -ccopt "-L ." -o gdtest.opt str.cmxa gd.cmxa gdtest.cmx
+
+gdtest.cmx: opt gdtest.ml
+ $(OCAMLOPT) $(OCAMLOPTFLAGS) -c gdtest.ml
+
+
+docs : gd.mli
+ $(OCAMLDOC) -d doc gd.mli
+
+
+install :
+ files=$$( \
+ for f in $(BYTE_ARCHIVE) $(NAT_ARCHIVE) $(STUBLIBS) \
+ *.mli *.cmi gd.a META; do \
+ if [ -f "$$f" ]; then echo $$f; fi; \
+ done; \
+ ) && \
+ $(TASKINSTALL) $(PKGNAME) $$files
+
+
+uninstall :
+ ocamlfind remove $(PKGNAME)
+
+
+clean :
+ -rm -f *.cmi *.cmo *.cmx *.cma *.cmxa *.a *.o *.so \
+ gdtest gdtest.opt gdtest.log
diff --git a/Makefile.orig b/Makefile.orig
new file mode 100644
index 0000000..f5463df
--- /dev/null
+++ b/Makefile.orig
@@ -0,0 +1,63 @@
+# You might have to change these.
+OCAMLC=ocamlc
+OCAMLOPT=ocamlopt
+OCAMLMKLIB=ocamlmklib
+OCAMLLIB=`$(OCAMLC) -where`
+CINCLUDES=-I$(OCAMLLIB) -I/usr/include
+CC=gcc
+
+# If you don't have libjpeg, remove the -DHAVE_JPEG and -cclib -ljpeg parts of
+# the following lines.
+CFLAGS=$(CINCLUDES) -DHAVE_JPEG -W -Wall -Wno-unused
+LIBS=-lgd -lpng -lz -ljpeg
+OCAMLCFLAGS=-labels -unsafe
+OCAMLOPTFLAGS=-inline 1
+
+OPT_FILES=gd.cmxa
+INSTALL_FILES=gd.cmi gd.cma libocamlgd.a dllocamlgd.so
+
+.PHONY : all opt install install-opt clean realclean
+
+all: gd.cma gdtest
+
+opt: gd.cmxa gdtest.opt
+
+
+install: all
+ cp -f $(INSTALL_FILES) $(OCAMLLIB)
+
+install-opt: all
+ cp -f gd.cmxa libocamlgd.a $(OCAMLLIB)
+
+gd.cma: gd.cmi gd.cmo gdstubs.o
+ ocamlmklib -o gd gd.cmo gdstubs.o -oc ocamlgd $(LIBS)
+
+gd.cmxa: gd.cmi gd.cmx gdstubs.o
+ ocamlmklib -o gd gd.cmx gdstubs.o -oc ocamlgd $(LIBS)
+
+gd.cmx: gd.cmi gd.ml
+ $(OCAMLOPT) $(OCAMLCFLAGS) -c gd.ml
+
+gd.cmo: gd.cmi gd.ml
+ $(OCAMLC) $(OCAMLCFLAGS) -c gd.ml
+
+gd.cmi: gd.mli
+ $(OCAMLC) $(OCAMLCFLAGS) -c gd.mli
+
+gdtest: gd.cma gdtest.cmo
+ $(OCAMLC) -o gdtest -dllpath . gd.cma gdtest.cmo
+
+gdtest.opt: gd.cmxa gdtest.ml
+ $(OCAMLOPT) $(OCAMLCFLAGS) -o gdtest.opt gd.cmxa gdtest.ml
+
+gdstubs.o: gdstubs.c
+ $(CC) $(CFLAGS) -c gdstubs.c
+
+gdtest.cmo: gd.cmi gdtest.ml
+ $(OCAMLC) $(OCAMLCFLAGS) -c gdtest.ml
+
+clean :
+ -rm -f *.cmi *.cmo *.cmx *.o
+
+realclean : clean
+ -rm -f *.a *.so *.cma *.cmxa
diff --git a/README b/README
new file mode 100644
index 0000000..960846f
--- /dev/null
+++ b/README
@@ -0,0 +1,73 @@
+GD4O: OCaml wrapper for the GD graphics library.
+================================================
+
+Version 1.0a5, November 24, 2003
+Copyright (c) 2002 by Shawn Wagner
+Copyright (c) 2003 by Matthew C. Gushee
+
+************************************************************************
+WARNING: This is a developer's release, and may contain serious bugs.
+ Use in a production environment is not recommended.
+************************************************************************
+
+
+What is GD4O?
+-------------
+
+GD4O is an OCaml interface to the GD graphics library. It is based on
+OCamlGD 0.7, developed by Shawn Wagner. Since that package is not
+actively maintained at present--and, to the best of my knowledge, its
+author does not intend to continue working on it--I decided to take up
+development.
+
+The goal of this project is to provide a complete and up-to-date
+interface to GD. The current version is very incomplete, but may be
+usable for very simple graphics.
+
+
+Major changes from OCamlGD
+--------------------------
+
+ * GD4O uses Findlib
+
+ * New drawing objects:
+
+ polygon
+ filled_polygon
+ filled_ellipse
+
+ * Implemented antialiased drawing
+
+ * Truecolor images
+
+ * TrueType fonts
+
+ * Created more extensive test program, which draws most available
+ shapes and tests all output methods.
+
+
+Documentation
+-------------
+
+ INSTALL
+ How to compile and install the library and test program.
+ README.ocamlgd
+ README from OCamlGD 0.7
+ doc/manual.txt
+ Partial user's manual from OCamlGD. Should be enough to help you get
+ started.
+ doc/api-xref.html
+ Cross-reference from GD C API to OCaml API. Shows status of each
+ feature in GD4O, with links to GD library docs and GD4O API docs.
+
+
+Comments, Questions, Bug reports
+--------------------------------
+
+Please send email to <gd4o@havenrock.com>
+
+Enjoy!
+
+
+November 24, 2003
+Matt Gushee <mgushee@havenrock.com>
diff --git a/README.ocamlgd b/README.ocamlgd
new file mode 100644
index 0000000..db5d4c6
--- /dev/null
+++ b/README.ocamlgd
@@ -0,0 +1,30 @@
+Ocaml-GD 0.5
+
+This is an interface to the GD graphics library for Ocaml.
+It's used to make simple graphic images, usually in the png format.
+
+The interface tends to follow the GD functions.
+
+And unlike a lot of ocaml libraries, this uses it's OO features. It
+also uses labels, though it should be possible to use it in code that
+doesn't. It uses labels because many of the functions take many int
+arguments, and the labels helps (Me, at least) to keep everything
+straight. And if you forget the order, it's no big deal.
+
+There's an image class, and color and font allocation classes, and a
+color class. Thus, drawing a red line might look like:
+
+myimage#line ~x1:0 ~y1:0 ~x2:60 ~y2:30 myimage#colors#red
+
+intead of
+
+Gd.line myimage ~x1:0 ~y1:0 ~x2:60 ~y2:30 (Gd.red myimage)
+
+See manual.txt and gd.mli for documentation.
+
+TODO:
+Interlaced images
+Serialization?
+Reading and writing more image formats.
+Brushes
+Polygons \ No newline at end of file
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..d241937
--- /dev/null
+++ b/TODO
@@ -0,0 +1,5 @@
+Implement all drawing methods.
+Implement TrueType font support.
+Improve documentation.
+Find out why antialiased curves are so bloody slow.
+Etc.
diff --git a/doc/api-xref.html b/doc/api-xref.html
new file mode 100644
index 0000000..a1022a9
--- /dev/null
+++ b/doc/api-xref.html
@@ -0,0 +1,2658 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+
+ <title>
+ Haven Rock: GD4O API Cross-reference
+ </title>
+ <body bgcolor="#ffffff">
+
+ <center>
+ <h1>GD4O API Cross-reference</h1>
+ </center>
+ <hr>
+ <hr><a name="intro"></a>
+
+ <p>
+ The following tables list all functions in the GD API. Corresponding
+ OCaml function names are shown for all functions currently implemented
+ in GD4O. The <strong>When</strong> column shows when each function
+ was implemented: [0] indicates that the function was implemented in
+ OCamlGD 0.7; [1], [2], [3], [4], and [5] stand for GD4O releases 1.0a1,
+ 1.0a2, 1.0a3, 1.0a4, and 1.0a5, respectively.
+
+ </p>
+
+
+ <ol class="PageTOC0">
+
+ <li><a href="#funcs.create">
+ Image creation, destruction, loading, and saving
+ </a></li>
+
+ <li><a href="#funcs.drawing">
+ Drawing functions
+ </a></li>
+
+ <li><a href="#funcs.query">
+ Query functions
+ </a></li>
+
+ <li><a href="#funcs.font">
+ Font and text-handling functions
+ </a></li>
+
+ <li><a href="#funcs.color">
+ Color-handling functions
+ </a></li>
+
+ <li><a href="#funcs.copying">
+ Copying and resizing functions
+ </a></li>
+
+ <li><a href="#funcs.misc">
+ Miscellaneous functions
+ </a></li>
+
+ </ol>
+ <a name="funcs.create"></a>
+
+ <h2>
+ Image creation, destruction, loading, and saving
+
+ </h2>
+
+ <table border="1" class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+
+ <tr>
+
+ <th>
+ C Function
+
+ </th>
+
+ <th>
+ When
+
+ </th>
+
+ <th>
+ OCaml Function
+
+ </th>
+
+ <th>
+ Comments
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreate">
+ gdImageCreate
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.html#VALcreate">
+ create
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateTrueColor">
+ gdImageCreateTrueColor
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.html#VALcreate_truecolor">
+ create_truecolor
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromJpeg">
+ gdImageCreateFromJpeg
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.html#VALopen_jpeg">
+ open_jpeg
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromPng">
+ gdImageCreateFromPng
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.html#VALopen_png">
+ open_png
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromPngSource">
+ gdImageCreateFromPngSource
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromGd">
+ gdImageCreateFromGd
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromGd2">
+ gdImageCreateFromGd2
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromGd2Part">
+ gdImageCreateFromGd2Part
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromXbm">
+ gdImageCreateFromXbm
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromXpm">
+ gdImageCreateFromXpm
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageDestroy">
+ gdImageDestroy
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageJpeg">
+ gdImageJpeg
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODsave_as_jpeg">
+ #image#save_as_jpeg
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageJpegPtr">
+ gdImageJpegPtr
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImagePng">
+ gdImagePng
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODsave_as_png">
+ #image#save_as_png
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngEx">
+ gdImagePngEx
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngPtr">
+ gdImagePngPtr
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngPtrEx">
+ gdImagePngPtrEx
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngToSink">
+ gdImagePngToSink
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODout_as_png">
+ #image#out_as_png
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageWBMP">
+ gdImageWBMP
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageWBMPPtr">
+ gdImageWBMPPtr
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGd">
+ gdImageGd
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGdPtr">
+ gdImageGdPtr
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGd2">
+ gdImageGd2
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGd2Ptr">
+ gdImageGd2Ptr
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageTrueColorToPalette">
+ gdImageTrueColorToPalette
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ </table>
+ <a name="funcs.drawing"></a>
+
+ <h2>
+ Drawing functions
+
+ </h2>
+
+ <table border="1" class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+
+ <tr>
+
+ <th>
+ C Function
+
+ </th>
+
+ <th>
+ When
+
+ </th>
+
+ <th>
+ OCaml Function
+
+ </th>
+
+ <th>
+ Comments
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetPixel">
+ gdImageSetPixel
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODset_pixel">
+ #image#set_pixel
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageLine">
+ gdImageLine
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODline">
+ #image#line
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageDashedLine">
+ gdImageDashedLine
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODdashed_line">
+ #image#dashed_line
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImagePolygon">
+ gdImagePolygon
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [1]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODpolygon">
+ #image#polygon
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageRectangle">
+ gdImageRectangle
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODrectangle">
+ #image#rectangle
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledPolygon">
+ gdImageFilledPolygon
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [1]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODfilled_polygon">
+ #image#filled_polygon
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledRectangle">
+ gdImageFilledRectangle
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODfilled_rectangle">
+ #image#filled_rectangle
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageArc">
+ gdImageArc
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODarc">
+ #image#arc
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledArc">
+ gdImageFilledArc
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODclosed_arc">
+ #image#closed_arc
+ </a><br> &amp;
+ <a href="Gd.image.html#METHODclosed_chord">
+ #image#closed_chord
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+ In the C library, 'FilledArc' takes a bitwise OR of several flags. But those
+ flags include one that specifies an arc, and another that specifies a chord
+ - which are in fact mutually exclusive drawing operations. Seems like rather
+ poor design to me, so I separated FilledArc into two methods. Furthermore, the
+ word 'closed' seems to me a more accurate description of what the method does.
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledEllipse">
+ gdImageFilledEllipse
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [1]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODfilled_ellipse">
+ #image#filled_ellipse
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageFillToBorder">
+ gdImageFillToBorder
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODborder_fill">
+ #image#border_fill
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+ This function works when called from a native code executable, but
+ when called from byte code, it seems to go into infinite recursion.
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageFill">
+ gdImageFill
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODfill">
+ #image#fill
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetAntiAliased">
+ gdImageSetAntiAliased
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [1]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODset_antialiased">
+ #image#set_antialiased
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+ Antialiased drawing is surprisingly slow. Must be something sub-optimal
+ in the C wrapper.
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetAntiAliasedDontBlend">
+ gdImageSetAntiAliasedDontBlend
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODset_antialiased_dontblend">
+ #image#set_antialiased_dontblend
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetBrush">
+ gdImageSetBrush
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODset_brush">
+ #image#set_brush
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetTile">
+ gdImageSetTile
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODset_tile">
+ #image#set_tile
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetStyle">
+ gdImageSetStyle
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetThickness">
+ gdImageSetThickness
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODset_thickness">
+ #image#set_thickness
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageAlphaBlending">
+ gdImageAlphaBlending
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSaveAlpha">
+ gdImageSaveAlpha
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetClip">
+ gdImageSetClip
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODset_clip">
+ #image#set_clip
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetClip">
+ gdImageGetClip
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageBlue">
+ gdImageBlue
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ </table>
+ <a name="funcs.query"></a>
+
+ <h2>
+ Query functions
+
+ </h2>
+
+ <table border="1" class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+
+ <tr>
+
+ <th>
+ C Function
+
+ </th>
+
+ <th>
+ When
+
+ </th>
+
+ <th>
+ OCaml Function
+
+ </th>
+
+ <th>
+ Comments
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageAlpha">
+ gdImageAlpha
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetPixel">
+ gdImageGetPixel
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODget_pixel">
+ #image#get_pixel
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageBoundsSafe">
+ gdImageBoundsSafe
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODin_range">
+ #image#in_range
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGreen">
+ gdImageGreen
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageRed">
+ gdImageRed
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSX">
+ gdImageSX
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODwidth">
+ #image#width
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageSY">
+ gdImageSY
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODheight">
+ #image#height
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ </table>
+ <a name="funcs.font"></a>
+
+ <h2>
+ Font and text-handling functions
+
+ </h2>
+
+ <table border="1" class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+
+ <tr>
+
+ <th>
+ C Function
+
+ </th>
+
+ <th>
+ When
+
+ </th>
+
+ <th>
+ OCaml Function
+
+ </th>
+
+ <th>
+ Comments
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageChar">
+ gdImageChar
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODletter">
+ #image#letter
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCharUp">
+ gdImageCharUp
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODletter_up">
+ #image#letter_up
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageString">
+ gdImageString
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODstring">
+ #image#string
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageString16">
+ gdImageString16
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringUp">
+ gdImageStringUp
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODstring_up">
+ #image#string_up
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringUp16">
+ gdImageStringUp16
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringFT">
+ gdImageStringFT
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [3]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODstring_ft">
+ #image#string_ft
+ </a><br> &amp;
+ <a href="Gd.image.html#METHODft_bbox">
+ ft_bbox
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+ In the C API, gdImageStringFt returns the bounding box of the
+ string. If you need the bounding box without drawing the string,
+ you pass a null gdImagePointer. Since OCaml doesn't really have
+ null pointers, the ft_bbox function simply calls a C function
+ that passes a null gdImagePtr to gdImageStringFT.
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringFTEx">
+ gdImageStringFTEx
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [4]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODstring_ftex">
+ #image#string_ftex
+ </a><br> &amp;
+ <a href="Gd.image.html#METHODftex_bbox">
+ ftex_bbox
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+ Partially implemented. Supports multiline text, but not yet
+ double-byte characters. See also notes for gdImageStringFT.
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringTTF">
+ gdImageStringTTF
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ </table>
+ <a name="funcs.color"></a>
+
+ <h2>
+ Color-handling functions
+
+ </h2>
+
+ <table border="1" class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+
+ <tr>
+
+ <th>
+ C Function
+
+ </th>
+
+ <th>
+ When
+
+ </th>
+
+ <th>
+ OCaml Function
+
+ </th>
+
+ <th>
+ Comments
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td class="XCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorAllocate">
+ gdImageColorAllocate
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODcreate">
+ #color_allocator#create
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorAllocateAlpha">
+ gdImageColorAllocateAlpha
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorClosest">
+ gdImageColorClosest
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODclosest">
+ #color_allocator#closest
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorClosestAlpha">
+ gdImageColorClosestAlpha
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorClosestHWB">
+ gdImageColorClosestHWB
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODclosest_hwb">
+ #collor_allocator#closest_hwb
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorExact">
+ gdImageColorExact
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODexact">
+ #collor_allocator#exact
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorResolve">
+ gdImageColorResolve
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODresolve">
+ #collor_allocator#resolve
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorResolveAlpha">
+ gdImageColorResolveAlpha
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorsTotal">
+ gdImageColorsTotal
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageRed">
+ gdImageRed
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODred">
+ #collor_allocator#red
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGreen">
+ gdImageGreen
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODgreen">
+ #collor_allocator#green
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageBlue">
+ gdImageBlue
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODblue">
+ #collor_allocator#blue
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetInterlaced">
+ gdImageGetInterlaced
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetTransparent">
+ gdImageGetTransparent
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [0]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODtransparent">
+ #collor_allocator#get_transparent
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+ Name changed to conform more closely to the C API. The previous name, '#transparent',
+ is now used for the method corresponding to gdImageTransparent.
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorDeallocate">
+ gdImageColorDeallocate
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorTransparent">
+ gdImageColorTransparent
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [2]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.color_allocator.html#METHODset_transparent">
+ #color_allocator#set_transparent
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageTrueColor">
+ gdImageTrueColor
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageTrueColorAlpha">
+ gdImageTrueColorAlpha
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ </table>
+ <a name="funcs.copying"></a>
+
+ <h2>
+ Copying and resizing functions
+
+ </h2>
+
+ <table border="1" class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+
+ <tr>
+
+ <th>
+ C Function
+
+ </th>
+
+ <th>
+ When
+
+ </th>
+
+ <th>
+ OCaml Function
+
+ </th>
+
+ <th>
+ Comments
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopy">
+ gdImageCopy
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [5]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODcopy">
+ #image#copy
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyResized">
+ gdImageCopyResized
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [5]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODcopy_resized">
+ #image#copy_resized
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyResampled">
+ gdImageCopyResampled
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [5]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODcopy_resized">
+ #image#copy_resampled
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyRotated">
+ gdImageCopyRotated
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [5]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODcopy_rotated">
+ #image#copy_rotated
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyMerge">
+ gdImageCopyMerge
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [5]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODcopy_merge">
+ #image#copy_merge
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyMergeGray">
+ gdImageCopyMergeGray
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [5]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODcopy_merge_gray">
+ #image#copy_merge_gray
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImagePaletteCopy">
+ gdImagePaletteCopy
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+ [5]
+
+ </td>
+
+ <td class="NameCell">
+ <a href="Gd.image.html#METHODpalette_copy">
+ #image#palette_copy
+ </a><br>
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ </table>
+ <a name="funcs.misc"></a>
+
+ <h2>
+ Miscellaneous functions
+
+ </h2>
+
+ <table border="1" class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+
+ <tr>
+
+ <th>
+ C Function
+
+ </th>
+
+ <th>
+ When
+
+ </th>
+
+ <th>
+ OCaml Function
+
+ </th>
+
+ <th>
+ Comments
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageCompare">
+ gdImageCompare
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdImageInterlace">
+ gdImageInterlace
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td class="NameCell">
+ <a href="http://www.boutell.com/gd/manual2.0.15.html#gdFree">
+ gdFree
+ </a><br>
+
+ </td>
+
+ <td class="BoolCell">
+
+ </td>
+
+ <td class="NameCell">
+
+ </td>
+
+ <td class="TextCell">
+
+ </td>
+
+ </tr>
+
+ </table>
+
+ <hr>
+ <center>
+ <p CLASS="PageInfo"><font size="-1"><em>
+ Copyright &copy; 2003 by
+ <a href="mailto:mgushee@havenrock.com">
+ Matt Gushee
+ </a>&nbsp;&nbsp;::&nbsp;&nbsp;Last modified:&nbsp;
+ Nov. 24, 2003</em></font></p>
+ </center>
+ </body>
+</html>
diff --git a/doc/api-xref.xml b/doc/api-xref.xml
new file mode 100644
index 0000000..a35089f
--- /dev/null
+++ b/doc/api-xref.xml
@@ -0,0 +1,1626 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="/std.xsl"?>
+
+<!-- ============================================================ -->
+<!-- WELCOME! Apparently your browser does not support XSLT, -->
+<!-- or you have XSLT disabled. To view the HTML version of -->
+<!-- this page, simply change 'xml' at the end of the URL to -->
+<!-- 'html'. We apologize for the inconvenience. -->
+<!-- ============================================================ -->
+
+<page page-id="software.gd4o.doc.api-xref" modified="Nov. 24, 2003">
+ <title>GD4O API Cross-reference</title>
+ <section id="intro">
+ <p>
+ The following tables list all functions in the GD API. Corresponding
+ OCaml function names are shown for all functions currently implemented
+ in GD4O. The <strong>When</strong> column shows when each function
+ was implemented: [0] indicates that the function was implemented in
+ OCamlGD 0.7; [1], [2], [3], [4], and [5] stand for GD4O releases 1.0a1,
+ 1.0a2, 1.0a3, 1.0a4, and 1.0a5, respectively.
+ </p>
+ </section>
+ <section role="PageTOC">
+ <list>
+ <item>
+ <xlink target="#funcs.create">
+ Image creation, destruction, loading, and saving
+ </xlink>
+ </item>
+ <item>
+ <xlink target="#funcs.drawing">
+ Drawing functions
+ </xlink>
+ </item>
+ <item>
+ <xlink target="#funcs.query" >
+ Query functions
+ </xlink>
+ </item>
+ <item>
+ <xlink target="#funcs.font">
+ Font and text-handling functions
+ </xlink>
+ </item>
+ <item>
+ <xlink target="#funcs.color">
+ Color-handling functions
+ </xlink>
+ </item>
+ <item>
+ <xlink target="#funcs.copying">
+ Copying and resizing functions
+ </xlink>
+ </item>
+ <item>
+ <xlink target="#funcs.misc">
+ Miscellaneous functions
+ </xlink>
+ </item>
+ </list>
+ </section>
+ <section id="funcs.create">
+ <title>
+ Image creation, destruction, loading, and saving
+ </title>
+ <table class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+ <tr>
+ <th>
+ C Function
+ </th>
+ <th>
+ When
+ </th>
+ <th>
+ OCaml Function
+ </th>
+ <th>
+ Comments
+ </th>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreate">
+ gdImageCreate
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.html#VALcreate">
+ create
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateTrueColor">
+ gdImageCreateTrueColor
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.html#VALcreate_truecolor">
+ create_truecolor
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromJpeg">
+ gdImageCreateFromJpeg
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.html#VALopen_jpeg">
+ open_jpeg
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromPng">
+ gdImageCreateFromPng
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.html#VALopen_png">
+ open_png
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromPngSource">
+ gdImageCreateFromPngSource
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromGd">
+ gdImageCreateFromGd
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromGd2">
+ gdImageCreateFromGd2
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromGd2Part">
+ gdImageCreateFromGd2Part
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromXbm">
+ gdImageCreateFromXbm
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCreateFromXpm">
+ gdImageCreateFromXpm
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageDestroy">
+ gdImageDestroy
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageJpeg">
+ gdImageJpeg
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODsave_as_jpeg">
+ #image#save_as_jpeg
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageJpegPtr">
+ gdImageJpegPtr
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImagePng">
+ gdImagePng
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODsave_as_png">
+ #image#save_as_png
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngEx">
+ gdImagePngEx
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngPtr">
+ gdImagePngPtr
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngPtrEx">
+ gdImagePngPtrEx
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImagePngToSink">
+ gdImagePngToSink
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODout_as_png">
+ #image#out_as_png
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageWBMP">
+ gdImageWBMP
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageWBMPPtr">
+ gdImageWBMPPtr
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGd">
+ gdImageGd
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGdPtr">
+ gdImageGdPtr
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGd2">
+ gdImageGd2
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGd2Ptr">
+ gdImageGd2Ptr
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageTrueColorToPalette">
+ gdImageTrueColorToPalette
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section id="funcs.drawing">
+ <title>
+ Drawing functions
+ </title>
+ <table class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+ <tr>
+ <th>
+ C Function
+ </th>
+ <th>
+ When
+ </th>
+ <th>
+ OCaml Function
+ </th>
+ <th>
+ Comments
+ </th>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetPixel">
+ gdImageSetPixel
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODset_pixel">
+ #image#set_pixel
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageLine">
+ gdImageLine
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODline">
+ #image#line
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageDashedLine">
+ gdImageDashedLine
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODdashed_line">
+ #image#dashed_line
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImagePolygon">
+ gdImagePolygon
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [1]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODpolygon">
+ #image#polygon
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageRectangle">
+ gdImageRectangle
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODrectangle">
+ #image#rectangle
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledPolygon">
+ gdImageFilledPolygon
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [1]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODfilled_polygon">
+ #image#filled_polygon
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledRectangle">
+ gdImageFilledRectangle
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODfilled_rectangle">
+ #image#filled_rectangle
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageArc">
+ gdImageArc
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODarc">
+ #image#arc
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledArc">
+ gdImageFilledArc
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODclosed_arc">
+ #image#closed_arc
+ </xlink> &amp;
+ <xlink target="Gd.image.html#METHODclosed_chord">
+ #image#closed_chord
+ </xlink>
+ </td>
+ <td class="TextCell">
+ In the C library, 'FilledArc' takes a bitwise OR of several flags. But those
+ flags include one that specifies an arc, and another that specifies a chord
+ - which are in fact mutually exclusive drawing operations. Seems like rather
+ poor design to me, so I separated FilledArc into two methods. Furthermore, the
+ word 'closed' seems to me a more accurate description of what the method does.
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageFilledEllipse">
+ gdImageFilledEllipse
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [1]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODfilled_ellipse">
+ #image#filled_ellipse
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageFillToBorder">
+ gdImageFillToBorder
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODborder_fill">
+ #image#border_fill
+ </xlink>
+ </td>
+ <td class="TextCell">
+ This function works when called from a native code executable, but
+ when called from byte code, it seems to go into infinite recursion.
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageFill">
+ gdImageFill
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODfill">
+ #image#fill
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetAntiAliased">
+ gdImageSetAntiAliased
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [1]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODset_antialiased">
+ #image#set_antialiased
+ </xlink>
+ </td>
+ <td class="TextCell">
+ Antialiased drawing is surprisingly slow. Must be something sub-optimal
+ in the C wrapper.
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetAntiAliasedDontBlend">
+ gdImageSetAntiAliasedDontBlend
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODset_antialiased_dontblend">
+ #image#set_antialiased_dontblend
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetBrush">
+ gdImageSetBrush
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODset_brush">
+ #image#set_brush
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetTile">
+ gdImageSetTile
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODset_tile">
+ #image#set_tile
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetStyle">
+ gdImageSetStyle
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetThickness">
+ gdImageSetThickness
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODset_thickness">
+ #image#set_thickness
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageAlphaBlending">
+ gdImageAlphaBlending
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSaveAlpha">
+ gdImageSaveAlpha
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSetClip">
+ gdImageSetClip
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODset_clip">
+ #image#set_clip
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetClip">
+ gdImageGetClip
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageBlue">
+ gdImageBlue
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section id="funcs.query">
+ <title>
+ Query functions
+ </title>
+ <table class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+ <tr>
+ <th>
+ C Function
+ </th>
+ <th>
+ When
+ </th>
+ <th>
+ OCaml Function
+ </th>
+ <th>
+ Comments
+ </th>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageAlpha">
+ gdImageAlpha
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetPixel">
+ gdImageGetPixel
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODget_pixel">
+ #image#get_pixel
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageBoundsSafe">
+ gdImageBoundsSafe
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODin_range">
+ #image#in_range
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGreen">
+ gdImageGreen
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageRed">
+ gdImageRed
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSX">
+ gdImageSX
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODwidth">
+ #image#width
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageSY">
+ gdImageSY
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODheight">
+ #image#height
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section id="funcs.font">
+ <title>
+ Font and text-handling functions
+ </title>
+ <table class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+ <tr>
+ <th>
+ C Function
+ </th>
+ <th>
+ When
+ </th>
+ <th>
+ OCaml Function
+ </th>
+ <th>
+ Comments
+ </th>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageChar">
+ gdImageChar
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODletter">
+ #image#letter
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCharUp">
+ gdImageCharUp
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODletter_up">
+ #image#letter_up
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageString">
+ gdImageString
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODstring">
+ #image#string
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageString16">
+ gdImageString16
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringUp">
+ gdImageStringUp
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODstring_up">
+ #image#string_up
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringUp16">
+ gdImageStringUp16
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringFT">
+ gdImageStringFT
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [3]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODstring_ft" >
+ #image#string_ft
+ </xlink> &amp;
+ <xlink target="Gd.image.html#METHODft_bbox" >
+ ft_bbox
+ </xlink>
+ </td>
+ <td class="TextCell">
+ In the C API, gdImageStringFt returns the bounding box of the
+ string. If you need the bounding box without drawing the string,
+ you pass a null gdImagePointer. Since OCaml doesn't really have
+ null pointers, the ft_bbox function simply calls a C function
+ that passes a null gdImagePtr to gdImageStringFT.
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringFTEx">
+ gdImageStringFTEx
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [4]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.image.html#METHODstring_ftex" >
+ #image#string_ftex
+ </xlink> &amp;
+ <xlink target="Gd.image.html#METHODftex_bbox" >
+ ftex_bbox
+ </xlink>
+ </td>
+ <td class="TextCell">
+ Partially implemented. Supports multiline text, but not yet
+ double-byte characters. See also notes for gdImageStringFT.
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageStringTTF">
+ gdImageStringTTF
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section id="funcs.color">
+ <title>
+ Color-handling functions
+ </title>
+ <table class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+ <tr>
+ <th>
+ C Function
+ </th>
+ <th>
+ When
+ </th>
+ <th>
+ OCaml Function
+ </th>
+ <th>
+ Comments
+ </th>
+ </tr>
+ <tr>
+ <td class="XCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorAllocate">
+ gdImageColorAllocate
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODcreate">
+ #color_allocator#create
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorAllocateAlpha">
+ gdImageColorAllocateAlpha
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorClosest">
+ gdImageColorClosest
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODclosest">
+ #color_allocator#closest
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorClosestAlpha">
+ gdImageColorClosestAlpha
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorClosestHWB">
+ gdImageColorClosestHWB
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODclosest_hwb">
+ #collor_allocator#closest_hwb
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorExact">
+ gdImageColorExact
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODexact">
+ #collor_allocator#exact
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorResolve">
+ gdImageColorResolve
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODresolve">
+ #collor_allocator#resolve
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorResolveAlpha">
+ gdImageColorResolveAlpha
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorsTotal">
+ gdImageColorsTotal
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageRed">
+ gdImageRed
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODred">
+ #collor_allocator#red
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGreen">
+ gdImageGreen
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODgreen">
+ #collor_allocator#green
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageBlue">
+ gdImageBlue
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODblue">
+ #collor_allocator#blue
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetInterlaced">
+ gdImageGetInterlaced
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageGetTransparent">
+ gdImageGetTransparent
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [0]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODtransparent">
+ #collor_allocator#get_transparent
+ </xlink>
+ </td>
+ <td class="TextCell">
+ Name changed to conform more closely to the C API. The previous name, '#transparent',
+ is now used for the method corresponding to gdImageTransparent.
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorDeallocate">
+ gdImageColorDeallocate
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageColorTransparent">
+ gdImageColorTransparent
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [2]
+ </td>
+ <td class="NameCell">
+ <xlink target="Gd.color_allocator.html#METHODset_transparent">
+ #color_allocator#set_transparent
+ </xlink>
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageTrueColor">
+ gdImageTrueColor
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageTrueColorAlpha">
+ gdImageTrueColorAlpha
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section id="funcs.copying">
+ <title>
+ Copying and resizing functions
+ </title>
+ <table class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+ <tr>
+ <th>
+ C Function
+ </th>
+ <th>
+ When
+ </th>
+ <th>
+ OCaml Function
+ </th>
+ <th>
+ Comments
+ </th>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopy">
+ gdImageCopy
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [5]
+ </td>
+ <td class="NameCell">
+ #image#copy
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyResized">
+ gdImageCopyResized
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [5]
+ </td>
+ <td class="NameCell">
+ #image#copy_resized
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyResampled">
+ gdImageCopyResampled
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [5]
+ </td>
+ <td class="NameCell">
+ #image#copy_resampled
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyRotated">
+ gdImageCopyRotated
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [5]
+ </td>
+ <td class="NameCell">
+ #image#copy_rotated
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyMerge">
+ gdImageCopyMerge
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [5]
+ </td>
+ <td class="NameCell">
+ #image#copy_merge
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCopyMergeGray">
+ gdImageCopyMergeGray
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [5]
+ </td>
+ <td class="NameCell">
+ #image#copy_merge_gray
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImagePaletteCopy">
+ gdImagePaletteCopy
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ [5]
+ </td>
+ <td class="NameCell">
+ #image#palette_copy
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section id="funcs.misc">
+ <title>
+ Miscellaneous functions
+ </title>
+ <table class="CoolTable1" width="96%" cellspacing="2" cellpadding="4">
+ <tr>
+ <th>
+ C Function
+ </th>
+ <th>
+ When
+ </th>
+ <th>
+ OCaml Function
+ </th>
+ <th>
+ Comments
+ </th>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageCompare">
+ gdImageCompare
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdImageInterlace">
+ gdImageInterlace
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ <tr>
+ <td class="NameCell">
+ <xlink target="http://www.boutell.com/gd/manual2.0.15.html#gdFree">
+ gdFree
+ </xlink>
+ </td>
+ <td class="BoolCell">
+ </td>
+ <td class="NameCell">
+ </td>
+ <td class="TextCell">
+ </td>
+ </tr>
+ </table>
+ </section>
+</page>
diff --git a/doc/manual.txt b/doc/manual.txt
new file mode 100644
index 0000000..2d387b5
--- /dev/null
+++ b/doc/manual.txt
@@ -0,0 +1,127 @@
+This is not yet complete documentation!
+
+Images:
+
+Images are objects. However, they should not be created with new
+directly. Instead, use the functions in the next section to create
+them.
+
+Creating images:
+
+Images can be created from scratch, or from an existing file.
+
+ Gd.create: ~x:int -> ~y:int -> image
+ Creates a new image with the given dimensions.
+
+ Gd.open_png: string -> image
+ Creates a new image from the given png file.
+ Gd.open_jpeg: string -> image
+ Creates a new image from the given jpeg file. Raises Gd.Not_supported
+ if jpeg operations aren't compiled in.
+
+Saving images:
+
+ Images can be saved to PNG files, or to jpeg's if Gd and OcamlGd are compiled
+ with jpeg support.
+
+ image#save_as_png: string -> unit
+ Saves a png version of the image to the file.
+
+ image:save_as_jpeg: ?quality:int -> string -> unit
+ Saves a jpeg version of the image to the file, with the given
+ image quality or a reasonable default. Quality is from 0 to 95,
+ the higher the more quality and larger the file. Raises Gd.Not_supported
+ if jpeg operations aren't compiled in.
+
+ image#out_as_png: out_channel -> unit
+ image#out_as_jpeg: ?quality:int -> out_channel -> unit
+ Dumps the image in the proper format to the out_channel. Useful for
+ things like a CGI program that wants to dump an image to stdout.
+ out_as_jpeg raises Gd.Not_supported if jpeg operations aren't compiled
+ in.
+
+Colors:
+ Each image can have up to 255 different colors. The first color assigned
+ will be the image's default background color. All colors for an object
+ are created and looked up through a color_allocator object associated with
+ the image object. This can be accessed through the colors method.
+
+ E.g: let my_colors = myimage#colors;;
+
+ Colors themselves are another class, with three public methods, for
+ getting the red, green and blue componets of the color. red_part,
+ green_part, and blue_part.
+
+ Color allocators have a number of methods for predefined color names:
+ white, black, red, green, blue and transparent.
+
+ colors#create: ~red:int -> ~green:int -> ~blue:int -> Gd.color
+ Creates a new color for the associated image. Raises Gd.Too_many_colors
+ if more than 255 colors have already been assigned.
+
+ colors#closest: ~red:int -> ~green:int -> ~blue:int -> Gd.color
+ Looks up and returns the already created color closest to the RGB
+ values. If the lookup fails, raises Gd.Color_not_found.
+
+ colors#exact: ~red:int -> ~green:int -> ~blue:int -> Gd.color
+ Looks up and returns the already created color exactly matching the RGB
+ values. If the lookup fails, raises Gd.Color_not_found.
+
+Fonts:
+
+ There are 5 different fonts available for drawing text, all in the
+ Gd.Font module. Unlike colors, they are independant of image. Listed
+ here, in order of increasing size.
+
+ Gd.Font.tiny
+ Gd.Font.small
+ Gd.Font.medium
+ Gd.Font.large
+ Gd.Font.giant
+
+Text:
+ There are four methods for drawing text - two for single characters,
+ two for strings.
+
+ image#letter: font:Gd.font -> x:int -> y:int -> c:char -> Gd.color -> unit
+ image#letter_up: font:Gd.font -> x:int -> y:int -> c:char -> Gd.color -> unit
+
+ Draw a single character. letter goes from left to right, letter_up
+ bottom to top, rotated 90 degrees.
+
+ image#string: font:Gd.font -> x:int -> y:int -> s:string -> Gd.color -> unit
+ image#string_up: font:Gd.font -> x:int -> y:int -> s:string -> Gd.color -> unit
+
+ Draw a string. Letters go from left to right in string, and
+ string_up does bottom to top, rotated 90 degrees.
+
+Lines:
+ There are two methods for drawing straight lines, and one for arcs:
+
+ image#line: x1:int -> y1:int -> x2:int -> y2:int -> color -> unit
+ image#dashed_line: x1:int -> y1:int -> x2:int -> y2:int -> color -> unit
+ image#arc: cx:int -> cy:int -> w:int -> h:int -> s:int -> e:int -> color -> unit
+
+
+Shapes and coloring:
+
+ image#rectangle: x1:int -> y1:int -> x2:int -> y2:int -> color -> unit
+ image#filled_rectangle: x1:int -> y1:int -> x2:int -> y2:int -> color -> unit
+ image#border_fill: x:int -> y:int -> border:color -> fill:color -> unit
+ image#virtual fill: x:int -> y:int -> color -> unit
+
+Individual pixels:
+
+ image#set_pixel: x:int -> y:int -> color -> unit
+ image#get_pixel: x:int -> y:int -> color
+
+Information about the image:
+ There are a few methods for finding out information about the image. They do
+ the obvious things. in_range returns true if the image is large enough to
+ have a pixel at the given coordinates.
+
+ image#width : int
+ image#height : int
+ image#in_range: x:int -> y:int -> bool
+
+
diff --git a/font_list.txt b/font_list.txt
new file mode 100644
index 0000000..b7300ab
--- /dev/null
+++ b/font_list.txt
@@ -0,0 +1,7 @@
+# This file should contain the full paths of four TrueType font files
+# that exist on your system, as shown below.
+
+/usr/local/share/fonts/ttf/ancis___.ttf
+/usr/local/share/fonts/ttf/verdanab.ttf
+/usr/local/share/fonts/ttf/wurker__.ttf
+/usr/local/share/fonts/ttf/chancy.ttf
diff --git a/gd.ml b/gd.ml
new file mode 100644
index 0000000..3fe8554
--- /dev/null
+++ b/gd.ml
@@ -0,0 +1,650 @@
+(* $Header: /home/cvs/gd4o/gd.ml,v 1.6 2003/11/25 01:02:32 matt Exp $ *)
+(*
+ * GD4O: An OCaml interface to the Gd graphics library.
+ * Based on Shawn Wagner's OCamlGD 0.7.0.
+ * Copyright (C) 2002 Shawn Wagner
+ * Copyright (C) 2003 Matthew C. Gushee
+ *
+ * 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
+ *)
+
+
+exception Too_many_colors
+exception Color_not_found
+exception Image_creation_failed
+exception Not_supported
+exception Illegal_state of string
+exception GD_Freetype_exception of string
+
+let _ = Callback.register_exception "gdopen failed" Image_creation_failed
+let _ = Callback.register_exception "gd type not supported" Not_supported
+let _ = Callback.register_exception "gd freetype exception" (GD_Freetype_exception "msg")
+
+type t (* Image type *)
+type c = int (* Color type *)
+type font (* Font type *)
+
+type ftex_flag =
+ | FTExSetSpacing
+ | FTExSetCharmap
+type ftex_charmap =
+ | FTExUnicode
+ | FTExShiftJIS
+ | FTExBig5
+
+(*
+class virtual color =
+object
+ method virtual red_part: int
+ method virtual green_part: int
+ method virtual blue_part: int
+ method virtual code: int
+ method virtual antialiased: color
+ method virtual is_aa: bool
+end
+*)
+type color = {
+ red_channel : int;
+ green_channel : int;
+ blue_channel : int;
+ alpha_channel : int;
+ index : int;
+}
+
+class virtual color_allocator =
+ object
+ method virtual create: red:int -> green:int -> blue:int -> color
+ method virtual closest: red:int -> green:int -> blue:int -> color
+ method virtual closest_hwb: red:int -> green:int -> blue:int -> color
+ method virtual resolve: red:int -> green:int -> blue:int -> color
+ method virtual exact: red:int -> green:int -> blue:int -> color
+ method virtual find: red:int -> green:int -> blue:int -> color
+ method virtual get_color_by_index: int -> color
+ method virtual white: color
+ method virtual black: color
+ method virtual blue: color
+ method virtual green: color
+ method virtual red: color
+ method virtual get_transparent: color
+ method virtual set_transparent: color -> unit
+ method virtual set_antialiased: bool -> unit
+ method virtual set_brushed: bool -> unit
+ method virtual set_styled: bool -> unit
+ method virtual set_tiled: bool -> unit
+ method virtual antialiased: unit -> int
+ method virtual brushed: unit -> int
+ method virtual styled: unit -> int
+ method virtual styled_brushed: unit -> int
+ method virtual tiled: unit -> int
+ method virtual transparent: unit -> int
+ end
+
+class virtual image =
+ object
+ method virtual get_image: t
+ method virtual colors: color_allocator
+ method virtual line: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual dashed_line: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual rectangle: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual filled_rectangle: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual polygon: pts:(int * int) array -> ?pseudo:int ->
+ color -> unit
+ method virtual filled_polygon: pts:(int * int) array -> ?pseudo:int ->
+ color -> unit
+ method virtual arc: cx:int -> cy:int -> w:int -> h:int -> s:int ->
+ e:int -> ?pseudo:int -> color -> unit
+ method virtual closed_arc:
+ cx:int -> cy:int -> w:int -> h:int -> s:int -> e:int ->
+ ?nofill:bool -> ?edged:bool -> ?pseudo:int -> color -> unit
+ method virtual closed_chord:
+ cx:int -> cy:int -> w:int -> h:int -> s:int -> e:int ->
+ ?nofill:bool -> ?edged:bool -> ?pseudo:int -> color -> unit
+ method virtual filled_ellipse: cx:int -> cy:int -> w:int -> h:int ->
+ ?pseudo:int -> color -> unit
+ method virtual border_fill: x:int -> y:int -> border:color ->
+ fill:color -> unit
+ method virtual fill: x:int -> y:int -> color -> unit
+ method virtual set_antialiased: color -> unit
+ method virtual set_antialiased_dont_blend:
+ aacolor:color -> dontblend:color -> unit
+ method virtual set_brush: image -> unit
+ method virtual set_tile: image -> unit
+ method virtual set_thickness: int -> unit
+ method virtual set_clip: x1:int -> y1:int -> x2:int -> y2:int -> unit
+ method virtual save_as_png: string -> unit
+ method virtual save_as_jpeg: ?quality:int -> string -> unit
+ method virtual out_as_png: out_channel -> unit
+ method virtual out_as_jpeg: ?quality:int -> out_channel -> unit
+ method virtual set_pixel: x:int -> y:int -> color -> unit
+ method virtual get_pixel: x:int -> y:int -> color
+ method virtual width: int
+ method virtual height: int
+ method virtual in_range: x:int -> y:int -> bool
+ method virtual letter: font:font -> x:int -> y:int -> c:char ->
+ color -> unit
+ method virtual letter_up: font:font -> x:int -> y:int -> c:char ->
+ color -> unit
+ method virtual string: font:font -> x:int -> y:int -> s:string ->
+ color -> unit
+ method virtual string_up: font:font -> x:int -> y:int -> s:string ->
+ color -> unit
+ method virtual string_ft:
+ fg:color -> fname:string -> size:float -> angle:float ->
+ x:int -> y:int -> string -> int array
+ method virtual string_ftex:
+ fg:color -> fname:string -> size:float -> angle:float ->
+ x:int -> y:int -> ?flags:ftex_flag array -> ?spacing:float ->
+ ?charmap:ftex_charmap -> string -> int array
+ method virtual copy: image -> x:int -> y:int -> src_x:int -> src_y:int ->
+ w:int -> h:int -> unit
+ method virtual copy_resized: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> src_w:int -> src_h:int -> unit
+ method virtual copy_resampled: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> src_w:int -> src_h:int -> unit
+ method virtual copy_rotated: image -> x:float -> y:float -> src_x:int ->
+ src_y:int -> w:int -> h:int -> angle:int -> unit
+ method virtual copy_merge: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> pct:int -> unit
+ method virtual copy_merge_gray: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> pct:int -> unit
+ method virtual palette_copy: image -> unit
+ end
+
+(* Private interface routines. *)
+(* Create an image *)
+external do_image_create: int -> int -> t = "ml_image_create"
+external do_image_create_truecolor: int -> int -> t
+ = "ml_image_create_truecolor"
+external do_image_open_png: string -> t = "ml_image_open_png"
+external do_image_open_jpeg: string -> t = "ml_image_open_jpeg"
+
+external do_is_truecolor: t -> bool = "ml_image_is_truecolor"
+
+(* Drawing functions *)
+external do_set_pixel: t -> int -> int -> int -> unit = "ml_set_pixel"
+
+external do_get_pixel: t -> int -> int -> int = "ml_get_pixel"
+
+external do_get_width: t -> int = "ml_get_width"
+external do_get_height: t -> int = "ml_get_height"
+
+external do_draw_line: t -> int -> int -> int -> int -> int -> int -> unit
+ = "ml_image_line" "ml_image_line_native"
+
+external do_draw_dline: t -> int -> int -> int -> int -> int -> int -> unit
+ = "ml_image_dline" "ml_image_dline_native"
+
+external do_draw_rect: t -> int -> int -> int -> int -> int -> int -> unit
+ = "ml_image_rect" "ml_image_rect_native"
+
+external do_draw_frect: t -> int -> int -> int -> int -> int -> int -> unit
+ = "ml_image_frect" "ml_image_frect_native"
+
+external do_draw_poly: t -> (int * int) array -> int -> int -> int -> unit
+ = "ml_image_poly"
+
+external do_draw_fpoly: t -> (int * int) array -> int -> int -> int -> unit
+ = "ml_image_fpoly"
+
+external do_draw_arc:
+ t -> int -> int -> int -> int -> int -> int -> int -> int -> unit
+ = "ml_image_arc" "ml_image_arc_native"
+
+external do_draw_carc:
+ t -> int -> int -> int -> int -> int -> int -> int -> int -> bool -> bool -> unit
+ = "ml_image_carc" "ml_image_carc_native"
+
+external do_draw_cchord:
+ t -> int -> int -> int -> int -> int -> int -> int -> int -> bool -> bool -> unit
+ = "ml_image_cchord" "ml_image_cchord_native"
+
+external do_draw_fell:
+ t -> int -> int -> int -> int -> int -> int -> unit
+ = "ml_image_fell" "ml_image_fell_native"
+
+external do_border_fill: t -> int -> int -> int -> int -> unit
+ = "ml_image_border_fill" "ml_image_border_fill_native"
+
+external do_fill: t -> int -> int -> int -> unit
+ = "ml_image_fill"
+
+external do_set_antialiased: t -> int -> unit
+ = "ml_image_set_antialiased"
+external do_set_antialiased_dont_blend: t -> int -> int -> unit
+ = "ml_image_set_antialiased_dont_blend"
+
+external do_set_brush: t -> t -> unit
+ = "ml_image_set_brush"
+external do_set_tile: t -> t -> unit
+ = "ml_image_set_tile"
+external do_set_thickness: t -> int -> unit
+ = "ml_image_set_thickness"
+external do_set_clip: t -> int -> int -> int -> int -> unit
+ = "ml_image_set_clip"
+
+external do_save_png: t -> string -> unit = "ml_save_png"
+external do_save_jpeg: t -> string -> int -> unit = "ml_save_jpeg"
+
+external do_dump_png: t -> out_channel -> unit = "ml_dump_png"
+external do_dump_jpeg: t -> out_channel -> int -> unit = "ml_dump_jpeg"
+
+
+(* External functions related to colors *)
+external do_color_create: t -> red:int -> green:int -> blue:int -> c
+ = "ml_image_color_alloc"
+
+external do_find_closest: t -> red:int -> green:int -> blue:int -> c
+ = "ml_image_color_closest"
+
+external do_find_closest_hwb: t -> red:int -> green:int -> blue:int -> c
+ = "ml_image_color_closest_hwb"
+
+external do_find_exact: t -> red:int -> green:int -> blue:int -> c
+ = "ml_image_color_exact"
+
+external do_resolve: t -> red:int -> green:int -> blue:int -> c
+ = "ml_image_color_resolve"
+
+external do_green_channel: t -> int -> int = "ml_image_green_channel"
+external do_red_channel: t -> int -> int = "ml_image_red_channel"
+external do_blue_channel: t -> int -> int = "ml_image_blue_channel"
+external do_alpha_channel: t -> int -> int = "ml_image_alpha_channel"
+external do_get_transparent: t -> int = "ml_image_get_transparent"
+external do_set_transparent: t -> int -> unit = "ml_image_set_transparent"
+
+external do_get_font: int -> font = "ml_get_font"
+
+external do_draw_char: t -> font -> int -> int -> char -> int -> unit
+ = "ml_image_char" "ml_image_char_native"
+
+external do_draw_charu: t -> font -> int -> int -> char -> int -> unit
+ = "ml_image_charu" "ml_image_charu_native"
+
+external do_draw_str: t -> font -> int -> int -> string -> int -> unit
+ = "ml_image_str" "ml_image_str_native"
+
+external do_draw_stru: t -> font -> int -> int -> string -> int -> unit
+ = "ml_image_stru" "ml_image_stru_native"
+
+external do_draw_str_ft:
+ t -> int -> string -> float -> float -> int -> int -> string -> int array
+ = "ml_image_str_ft" "ml_image_str_ft_native"
+external do_draw_str_ftex:
+ t -> int -> string -> float -> float -> int -> int -> ftex_flag array ->
+ float -> ftex_charmap -> string -> int array
+ = "ml_image_str_ftex" "ml_image_str_ftex_native"
+
+external do_ft_bbox:
+ string -> float -> float -> int -> int -> string -> int array
+ = "ml_image_ft_bbox" "ml_image_ft_bbox_native"
+external do_ftex_bbox:
+ string -> float -> float -> int -> int -> ftex_flag array ->
+ float -> ftex_charmap -> string -> int array
+ = "ml_image_ftex_bbox" "ml_image_ftex_bbox_native"
+
+external do_copy: t -> t -> x:int -> y:int -> src_x:int -> src_y:int ->
+ w:int -> h:int -> unit
+ = "ml_image_copy" "ml_image_copy_native"
+external do_copy_resized: t -> t -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> src_w:int -> src_h:int -> unit
+ = "ml_image_copy_resized" "ml_image_copy_resized_native"
+external do_copy_resampled: t -> t -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> src_w:int -> src_h:int -> unit
+ = "ml_image_copy_resampled" "ml_image_copy_resampled_native"
+external do_copy_rotated: t -> t -> x:float -> y:float -> src_x:int ->
+ src_y:int -> w:int -> h:int -> angle:int -> unit
+ = "ml_image_copy_rotated" "ml_image_copy_rotated_native"
+external do_copy_merge: t -> t -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> pct:int -> unit
+ = "ml_image_copy_merge" "ml_image_copy_merge_native"
+external do_copy_merge_gray: t -> t -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> pct:int -> unit
+ = "ml_image_copy_merge_gray" "ml_image_copy_merge_gray_native"
+external do_palette_copy: t -> t -> unit
+ = "ml_image_palette_copy"
+
+
+module Font =
+ struct
+ let tiny = do_get_font 0
+ let small = do_get_font 1
+ let medium = do_get_font 2
+ let large = do_get_font 3
+ let giant = do_get_font 4
+ end
+
+
+(* Implementation classes *)
+(*
+class gdColor im col =
+ object(self)
+ inherit color
+ val antialias_color = false
+ method code = col
+ method blue_part = do_blue_part im col
+ method red_part = do_red_part im col
+ method green_part = do_green_part im col
+ method antialiased = ({< antialias_color = true >} :> color)
+ method is_aa = antialias_color
+ end
+*)
+
+
+class virtual gd_color_allocator im =
+ object (self)
+ inherit color_allocator
+
+ val mutable aa_pcolor = false
+ val mutable brushed_pcolor = false
+ val mutable styled_pcolor = false
+ val mutable styled_brushed_pcolor = false
+ val mutable tiled_pcolor = false
+ val mutable transparent_pcolor = true
+
+
+ method create ~red ~green ~blue =
+ let cindex = do_color_create im ~red ~green ~blue in
+ if cindex = -1 then raise Too_many_colors
+ else self#new_ml_color cindex
+
+ method closest ~red ~green ~blue =
+ let cindex = do_find_closest im ~red ~green ~blue in
+ if cindex = -1 then raise Color_not_found
+ else self#new_ml_color cindex
+
+ method closest_hwb ~red ~green ~blue =
+ let cindex = do_find_closest_hwb im ~red ~green ~blue in
+ if cindex = -1 then raise Color_not_found
+ else self#new_ml_color cindex
+
+ method exact ~red ~green ~blue =
+ let cindex = do_find_exact im ~red ~green ~blue in
+ if cindex = -1 then raise Color_not_found
+ else self#new_ml_color cindex
+
+ method resolve ~red ~green ~blue =
+ let cindex = do_resolve im ~red ~green ~blue in
+ if cindex = -1 then raise Color_not_found
+ else self#new_ml_color cindex
+
+ method find ~red ~green ~blue =
+ let cindex = do_find_exact im ~red ~green ~blue in
+ if cindex <> -1 then
+ self#new_ml_color cindex
+ else
+ let cindex = do_color_create im ~red ~blue ~green in
+ if cindex = -1 then raise Too_many_colors
+ else self#new_ml_color cindex
+
+ method black = self#find ~red:0 ~blue:0 ~green:0
+ method white = self#find ~red:255 ~blue:255 ~green:255
+ method blue = self#find ~blue:255 ~red:0 ~green:0
+ method green = self#find ~green:255 ~red:0 ~blue:0
+ method red = self#find ~red:255 ~green:0 ~blue:0
+ method get_transparent =
+ let cindex = do_get_transparent im in
+ if cindex = -1 then raise Color_not_found
+ else self#new_ml_color cindex
+ method set_transparent color =
+ do_set_transparent im color.index
+ method set_antialiased enable = aa_pcolor <- enable
+ method set_brushed enable =
+ brushed_pcolor <- enable;
+ styled_brushed_pcolor <- enable && styled_pcolor
+ method set_styled enable =
+ styled_pcolor <- enable;
+ styled_brushed_pcolor <- enable && brushed_pcolor
+ method set_tiled enable = tiled_pcolor <- enable
+ method antialiased () =
+ if aa_pcolor then 0
+ else raise (Illegal_state
+ "You must call 'set_antialiased' before calling 'antialiased'.")
+ method brushed () =
+ if brushed_pcolor then 1
+ else raise (Illegal_state
+ "You must call 'set_brushed' before calling 'brushed'.")
+ method styled () =
+ if styled_pcolor then 2
+ else raise (Illegal_state
+ "You must call 'set_styled' before calling 'styled'.")
+ method styled_brushed () =
+ if styled_brushed_pcolor then 3
+ else raise (Illegal_state
+ "You must call 'set_brushed' and 'set_styled' before calling
+ 'styled_brushed'.")
+ method tiled () =
+ if tiled_pcolor then 4
+ else raise (Illegal_state
+ "You must call 'set_tiled' before calling 'tiled'.")
+ method transparent () =
+ if transparent_pcolor then 5
+ else raise (Illegal_state
+ "Transparent pseudocolor is disabled.")
+ end
+
+class gd_8bit_color_allocator im =
+ object(self)
+ inherit gd_color_allocator im
+
+ val colors = Array.make 256
+ { index = -1; red_channel = -1; green_channel = -1;
+ blue_channel = -1; alpha_channel = -1; }
+
+ method private new_ml_color idx =
+ let mc =
+ { index = idx;
+ red_channel = (do_red_channel im idx);
+ green_channel = (do_green_channel im idx);
+ blue_channel = (do_blue_channel im idx);
+ alpha_channel = (do_alpha_channel im idx); } in
+ colors.(idx) <- mc;
+ mc
+
+ method get_color_by_index idx =
+ let c = colors.(idx) in
+ if c.index = -1 then self#new_ml_color idx
+ else c
+
+ end
+
+class gd_truecolor_allocator im =
+ object(self)
+ inherit gd_color_allocator im
+
+ val colors:((int, color) Hashtbl.t) = Hashtbl.create 1024
+
+ method private new_ml_color idx =
+ let mc =
+ { index = idx;
+ red_channel = (do_red_channel im idx);
+ green_channel = (do_green_channel im idx);
+ blue_channel = (do_blue_channel im idx);
+ alpha_channel = (do_alpha_channel im idx); } in
+ Hashtbl.replace colors idx mc;
+ mc
+
+ method get_color_by_index idx =
+ try
+ Hashtbl.find colors idx
+ with Not_found ->
+ self#new_ml_color idx
+
+ end
+
+
+
+class virtual gdImage im =
+ object(self)
+ inherit image
+
+ method get_image = im
+
+ method line ~x1 ~y1 ~x2 ~y2 ?(pseudo = -1) color =
+ do_draw_line im x1 y1 x2 y2 color.index pseudo
+
+ method dashed_line ~x1 ~y1 ~x2 ~y2 ?(pseudo = -1) color =
+ do_draw_dline im x1 y1 x2 y2 color.index pseudo
+
+ method rectangle ~x1 ~y1 ~x2 ~y2 ?(pseudo = -1) color =
+ do_draw_rect im x1 y1 x2 y2 color.index pseudo
+
+ method filled_rectangle ~x1 ~y1 ~x2 ~y2 ?(pseudo = -1) color =
+ do_draw_frect im x1 y1 x2 y2 color.index pseudo
+
+ method polygon ~pts ?(pseudo = -1) color =
+ do_draw_poly im pts (Array.length pts) color.index pseudo
+
+ method filled_polygon ~pts ?(pseudo = -1) color =
+ do_draw_fpoly im pts (Array.length pts) color.index pseudo
+
+ method arc ~cx ~cy ~w ~h ~s ~e ?(pseudo = -1) color =
+ do_draw_arc im cx cy w h s e color.index pseudo
+
+ method closed_arc
+ ~cx ~cy ~w ~h ~s ~e ?(nofill = false) ?(edged = false) ?(pseudo = -1) color =
+ do_draw_carc im cx cy w h s e color.index pseudo nofill edged
+
+ method closed_chord
+ ~cx ~cy ~w ~h ~s ~e ?(nofill = false) ?(edged = false) ?(pseudo = -1) color =
+ do_draw_cchord im cx cy w h s e color.index pseudo nofill edged
+
+ method filled_ellipse ~cx ~cy ~w ~h ?(pseudo = -1) color =
+ do_draw_fell im cx cy w h color.index pseudo
+
+ method border_fill ~x ~y ~border ~fill =
+ do_border_fill im x y (border.index) (fill.index)
+
+ method fill ~x ~y color =
+ do_fill im x y color.index
+
+ method set_antialiased col =
+ self#colors#set_antialiased true;
+ do_set_antialiased im col.index
+
+ method set_antialiased_dont_blend ~aacolor ~dontblend =
+ self#colors#set_antialiased true;
+ do_set_antialiased_dont_blend im aacolor.index dontblend.index
+
+ method set_brush br =
+ self#colors#set_brushed true;
+ do_set_brush im br#get_image
+ method set_tile ti =
+ self#colors#set_tiled true;
+ do_set_tile im ti#get_image
+ method set_thickness th = do_set_thickness im th
+ method set_clip ~x1 ~y1 ~x2 ~y2 =
+ do_set_clip im x1 y1 x2 y2
+
+ method letter ~font ~x ~y ~c color =
+ do_draw_char im font x y c color.index
+
+ method letter_up ~font ~x ~y ~c color =
+ do_draw_charu im font x y c color.index
+
+ method string ~font ~x ~y ~s color =
+ do_draw_str im font x y s color.index
+
+ method string_up ~font ~x ~y ~s color =
+ do_draw_stru im font x y s color.index
+
+ method string_ft ~fg ~fname ~size ~angle ~x ~y text =
+ do_draw_str_ft im fg.index fname size angle x y text
+ method string_ftex ~fg ~fname ~size ~angle ~x ~y ?(flags = [||])
+ ?(spacing = 1.05) ?(charmap = FTExUnicode) text =
+ do_draw_str_ftex im fg.index fname size angle x y flags spacing
+ charmap text
+
+ method save_as_png filename = do_save_png im filename
+ method save_as_jpeg ?(quality = -1) filename =
+ do_save_jpeg im filename quality
+
+ method out_as_png channel = do_dump_png im channel
+ method out_as_jpeg ?(quality = -1) channel =
+ do_dump_jpeg im channel quality
+
+ method set_pixel ~x ~y color =
+ do_set_pixel im x y color.index
+
+ method get_pixel ~x ~y =
+ self#colors#get_color_by_index (do_get_pixel im x y)
+
+ method width = do_get_width im
+ method height = do_get_height im
+
+ method in_range ~x ~y =
+ x >= 0 && x <= (do_get_width im) && y >= 0 && y <= (do_get_height im)
+
+ method copy src ~x ~y ~src_x ~src_y ~w ~h =
+ do_copy im src#get_image x y src_x src_y w h
+ method copy_resized src ~x ~y ~src_x ~src_y ~w ~h ~src_w ~src_h =
+ do_copy_resized im src#get_image x y src_x src_y w h src_w src_h
+ method copy_resampled src ~x ~y ~src_x ~src_y ~w ~h ~src_w ~src_h =
+ do_copy_resampled im src#get_image x y src_x src_y w h src_w src_h
+ method copy_rotated src ~x ~y ~src_x ~src_y ~w ~h ~angle =
+ do_copy_rotated im src#get_image x y src_x src_y w h angle
+ method copy_merge src ~x ~y ~src_x ~src_y ~w ~h ~pct =
+ do_copy_merge im src#get_image x y src_x src_y w h pct
+ method copy_merge_gray src ~x ~y ~src_x ~src_y ~w ~h ~pct =
+ do_copy_merge_gray im src#get_image x y src_x src_y w h pct
+ method palette_copy src =
+ do_palette_copy im src#get_image
+
+ end
+
+(* 8-bit (indexed-color) image *)
+class gdImage8 im =
+ object
+ inherit gdImage im
+
+ val c_a = new gd_8bit_color_allocator im
+ method colors = c_a
+ end
+
+(* Truecolor image *)
+class gdImageT im =
+ object
+ inherit gdImage im
+
+ val c_a = new gd_truecolor_allocator im
+ method colors = c_a
+ end
+
+
+let is_truecolor im = do_is_truecolor im
+
+let ft_bbox ~fname ~size ~angle ~x ~y text =
+ do_ft_bbox fname size angle x y text
+let ftex_bbox ~fname ~size ~angle ~x ~y ?(flags = [||]) ?(spacing = 1.05)
+ ?(charmap = FTExUnicode) text =
+ do_ftex_bbox fname size angle x y flags spacing charmap text
+
+(* Image creation functions *)
+let create ~(x:int) ~(y:int) =
+ new gdImage8 (do_image_create x y)
+
+let create_truecolor ~(x:int) ~(y:int) =
+ new gdImageT (do_image_create_truecolor x y)
+
+let open_png filename =
+ let im = (do_image_open_png filename) in
+ if (is_truecolor im) then new gdImageT im
+ else new gdImage8 im
+
+let open_jpeg filename =
+ new gdImageT (do_image_open_jpeg filename)
diff --git a/gd.mli b/gd.mli
new file mode 100644
index 0000000..c9039e9
--- /dev/null
+++ b/gd.mli
@@ -0,0 +1,232 @@
+(* $Header: /home/cvs/gd4o/gd.mli,v 1.6 2003/11/25 01:02:32 matt Exp $ *)
+(*
+ * GD4O: An OCaml interface to the Gd graphics library.
+ * Based on Shawn Wagner's OCamlGD 0.7.0.
+ * Copyright (C) 2002 Shawn Wagner
+ * Copyright (C) 2003 Matthew C. Gushee
+ *
+ * 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
+ *)
+
+
+type t (* image type *)
+
+(* GD images can only have 256 colors *)
+exception Too_many_colors
+
+(* Tried to find a preallocated color that wasn't *)
+exception Color_not_found
+
+(* Couldn't create or open an image. *)
+exception Image_creation_failed
+
+(* This build doesn't support some image format (Jpeg, Xpm, etc.) *)
+exception Not_supported
+
+(* An operation was attempted without having performed one or more prerequisites. *)
+exception Illegal_state of string
+
+(* All of these classes are virtual because users shouldn't be instatiating them.
+ Instead, use the creation or opening functions listed at the bottom *)
+
+(*
+class virtual color :
+object
+ (* Returns the red part (0-255) of the color *)
+ method virtual red_part : int
+ (* Returns the green part (0-255) of the color *)
+ method virtual green_part : int
+ (* Returns the blue part (0-255) of the color *)
+ method virtual blue_part : int
+ (* Returns the code of the color. Please don't use. *)
+ method virtual code : int
+ method virtual antialiased : color
+ method virtual is_aa : bool
+end
+*)
+
+type color
+type ftex_flag =
+ | FTExSetSpacing
+ | FTExSetCharmap
+type ftex_charmap =
+ | FTExUnicode
+ | FTExShiftJIS
+ | FTExBig5
+
+(* The first color allocated for an image is it's background *)
+class virtual color_allocator :
+ object
+ (* R, G, and B values are integers 0-255 *)
+ method virtual create: red:int -> green:int -> blue:int -> color
+ (* Return the closest-matching color of those already allocated *)
+ method virtual closest: red:int -> green:int -> blue:int -> color
+ method virtual closest_hwb: red:int -> green:int -> blue:int -> color
+ (* Try exact, create, closest *)
+ method virtual resolve: red:int -> green:int -> blue:int -> color
+ (* Exact match color of those already allocated *)
+ method virtual exact: red:int -> green:int -> blue:int -> color
+ (* Try an exact, create *)
+ method virtual find: red:int -> green:int -> blue:int -> color
+ method virtual get_color_by_index: int -> color
+ method virtual white: color
+ method virtual black: color
+ method virtual blue: color
+ method virtual green: color
+ method virtual red: color
+ method virtual get_transparent: color
+ method virtual set_transparent: color -> unit
+ method virtual set_antialiased: bool -> unit
+ method virtual set_brushed: bool -> unit
+ method virtual set_styled: bool -> unit
+ method virtual set_tiled: bool -> unit
+ method virtual antialiased: unit -> int
+ method virtual brushed: unit -> int
+ method virtual styled: unit -> int
+ method virtual styled_brushed: unit -> int
+ method virtual tiled: unit -> int
+ method virtual transparent: unit -> int
+ end
+
+type font
+module Font :
+ sig
+ val tiny: font
+ val small: font
+ val medium: font
+ val large: font
+ val giant: font
+ end
+
+class virtual image :
+ object
+ (* This was private, but it needs to be exposed for things like tile
+ brush images. *)
+ method virtual get_image: t
+
+ (* Return the color_allocator object associated with this image *)
+ method virtual colors : color_allocator
+
+ method virtual line: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual dashed_line: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual rectangle: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual filled_rectangle: x1:int -> y1:int -> x2:int -> y2:int ->
+ ?pseudo:int -> color -> unit
+ method virtual polygon: pts:(int * int) array -> ?pseudo:int ->
+ color -> unit
+ method virtual filled_polygon: pts:(int * int) array -> ?pseudo:int ->
+ color -> unit
+ method virtual arc: cx:int -> cy:int -> w:int -> h:int -> s:int ->
+ e:int -> ?pseudo:int -> color -> unit
+ method virtual closed_arc:
+ cx:int -> cy:int -> w:int -> h:int -> s:int -> e:int ->
+ ?nofill:bool -> ?edged:bool -> ?pseudo:int -> color -> unit
+ method virtual closed_chord:
+ cx:int -> cy:int -> w:int -> h:int -> s:int -> e:int ->
+ ?nofill:bool -> ?edged:bool -> ?pseudo:int -> color -> unit
+ method virtual filled_ellipse: cx:int -> cy:int -> w:int -> h:int ->
+ ?pseudo:int -> color -> unit
+ (* Fill an area bordered by the border color *)
+ method virtual border_fill: x:int -> y:int -> border:color ->
+ fill:color -> unit
+ (* Fill an area with the same color as the pixel *)
+ method virtual fill: x:int -> y:int -> color -> unit
+
+ (* Turn on antialiasing. *)
+ method virtual set_antialiased: color -> unit
+ method virtual set_antialiased_dont_blend:
+ aacolor:color -> dontblend:color -> unit
+
+ method virtual set_brush: image -> unit
+ method virtual set_tile: image -> unit
+ method virtual set_thickness: int -> unit
+ method virtual set_clip: x1:int -> y1:int -> x2:int -> y2:int -> unit
+
+ (* Draw one character *)
+ method virtual letter: font:font -> x:int -> y:int -> c:char -> color -> unit
+ (* Rotated 90 degrees *)
+ method virtual letter_up: font:font -> x:int -> y:int -> c:char -> color -> unit
+
+ method virtual string: font:font -> x:int -> y:int -> s:string -> color -> unit
+ (* Rotated 90 degrees *)
+ method virtual string_up: font:font -> x:int -> y:int -> s:string ->
+ color -> unit
+ (* Freetype string *)
+ method virtual string_ft:
+ fg:color -> fname:string -> size:float -> angle:float ->
+ x:int -> y:int -> string -> int array
+ method virtual string_ftex:
+ fg:color -> fname:string -> size:float -> angle:float ->
+ x:int -> y:int -> ?flags:ftex_flag array -> ?spacing:float ->
+ ?charmap:ftex_charmap -> string -> int array
+
+ method virtual set_pixel: x:int -> y:int -> color -> unit
+ method virtual get_pixel: x:int -> y:int -> color
+
+ (* Image's size *)
+ method virtual width: int
+ method virtual height: int
+
+ (* Is proposed drawing location within the drawing area? *)
+ method virtual in_range: x:int -> y:int -> bool
+
+ (* Save to file *)
+ method virtual save_as_png: string -> unit
+ method virtual save_as_jpeg: ?quality:int -> string -> unit
+
+ (* Dump to an out_channel. *)
+ method virtual out_as_png: out_channel -> unit
+ method virtual out_as_jpeg: ?quality:int -> out_channel -> unit
+
+ (* Copy a region from another image to this image. *)
+ method virtual copy: image -> x:int -> y:int -> src_x:int -> src_y:int ->
+ w:int -> h:int -> unit
+ method virtual copy_resized: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> src_w:int -> src_h:int -> unit
+ method virtual copy_resampled: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> src_w:int -> src_h:int -> unit
+ method virtual copy_rotated: image -> x:float -> y:float -> src_x:int ->
+ src_y:int -> w:int -> h:int -> angle:int -> unit
+ method virtual copy_merge: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> pct:int -> unit
+ method virtual copy_merge_gray: image -> x:int -> y:int -> src_x:int ->
+ src_y:int -> w:int -> h:int -> pct:int -> unit
+ method virtual palette_copy: image -> unit
+ end
+
+(* Create a new image with the given size *)
+val create: x:int -> y:int -> image (* Throws Gd.Image_creation_faield *)
+
+(* Create a new image with the given size *)
+val create_truecolor: x:int -> y:int -> image (* Throws Gd.Image_creation_faield *)
+
+(* Open a png file. Throws Not_found and Gd.Image_creation_failed *)
+val open_png: string -> image
+
+(* Same, but for jpeg's *)
+val open_jpeg: string -> image
+
+val is_truecolor: t -> bool
+
+(* Return the bounding box for a string rendered with FreeType *)
+val ft_bbox: fname:string -> size:float -> angle:float -> x:int ->
+ y:int -> string -> int array
+val ftex_bbox: fname:string -> size:float -> angle:float -> x:int ->
+ y:int -> ?flags:ftex_flag array -> ?spacing:float ->
+ ?charmap:ftex_charmap -> string -> int array
+
diff --git a/gdstubs.c b/gdstubs.c
new file mode 100644
index 0000000..274a6e6
--- /dev/null
+++ b/gdstubs.c
@@ -0,0 +1,1009 @@
+/* $Header: /home/cvs/gd4o/gdstubs.c,v 1.7 2003/11/25 01:02:32 matt Exp $ */
+/*
+ * GD4O: An OCaml interface to the Gd graphics library.
+ * Based on Shawn Wagner's OCamlGD 0.7.0.
+ * Copyright (C) 2002 Shawn Wagner
+ * Copyright (C) 2003 Matthew C. Gushee
+ *
+ * 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
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <caml/mlvalues.h>
+#include <caml/alloc.h>
+#include <caml/custom.h>
+#include <caml/memory.h>
+#include <caml/callback.h>
+#include <caml/fail.h>
+
+#include <gd.h>
+#include <gdfontl.h>
+#include <gdfonts.h>
+#include <gdfontt.h>
+#include <gdfontmb.h>
+#include <gdfontg.h>
+
+struct gd_wrapper {
+ gdImagePtr im;
+};
+
+typedef struct gd_wrapper GdWrapper;
+
+struct font_wrapper {
+ gdFontPtr font;
+};
+
+typedef struct font_wrapper GdFWrapper;
+
+struct points_wrapper {
+ gdPointPtr pts;
+};
+
+typedef struct points_wrapper GdPtsWrapper;
+
+#define IM_VAL(X) ((*((GdWrapper *)(Data_custom_val(X)))).im)
+#define FONT_VAL(X) ((*((GdFWrapper *)(Data_custom_val(X)))).font)
+#define PTS_VAL(X) ((*((GdPtsWrapper *)(Data_custom_val(X)))).pts)
+
+static void ml_gd_finalize(value);
+static long ml_gd_hash(value);
+static int ml_font_cmp(value, value);
+static long ml_font_hash(value);
+
+static struct custom_operations image_t_custom_operations = {
+ "GD image/0.1",
+ ml_gd_finalize,
+ NULL,
+ ml_gd_hash,
+ NULL,
+ NULL
+};
+
+static struct custom_operations font_t_custom_operations = {
+ "GD font/0.1",
+ NULL,
+ ml_font_cmp,
+ ml_font_hash,
+ NULL,
+ NULL
+};
+
+static gdFontPtr fonts[5] =
+{
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static int fonts_init = 0;
+
+static int pseudoColors[6] =
+ { gdAntiAliased, gdBrushed, gdStyled,
+ gdStyledBrushed, gdTiled, gdTransparent };
+static int ftExFlags[2] =
+ { gdFTEX_LINESPACE, gdFTEX_CHARMAP };
+static int ftExCharmaps[3] =
+ { gdFTEX_Unicode, gdFTEX_Shift_JIS, gdFTEX_Big5 };
+
+void ml_gd_finalize(value v) {
+ if (IM_VAL(v))
+ gdImageDestroy(IM_VAL(v));
+}
+
+long ml_gd_hash(value v) {
+ return gdImageSX(IM_VAL(v));
+}
+
+int ml_font_cmp(value v1, value v2) {
+ return (int)FONT_VAL(v1) - (int)FONT_VAL(v2);
+}
+
+static long ml_font_hash(value v) {
+ return (long)FONT_VAL(v);
+}
+
+value ml_get_font(value i) {
+ CAMLparam1(i);
+ CAMLlocal1(v);
+
+ v = alloc_custom(&font_t_custom_operations, sizeof(GdFWrapper), 1, 10);
+
+ if (!fonts_init) {
+ fonts[0] = gdFontTiny;
+ fonts[1] = gdFontSmall;
+ fonts[2] = gdFontMediumBold;
+ fonts[3] = gdFontLarge;
+ fonts[4] = gdFontGiant;
+ fonts_init = 1;
+ }
+
+ FONT_VAL(v) = fonts[Int_val(i)];
+
+ CAMLreturn(v);
+}
+
+value ml_image_create(value sx, value sy) {
+ CAMLparam2(sx, sy);
+ CAMLlocal1(v);
+ gdImagePtr im;
+
+ im = gdImageCreate(Int_val(sx), Int_val(sy));
+ if (!im)
+ raise_constant(*(value *)caml_named_value("gdopen failed"));
+
+ v = alloc_custom(&image_t_custom_operations, sizeof(GdWrapper),
+ (Int_val(sx) * Int_val(sy)) + sizeof(gdImage), 10000);
+ IM_VAL(v) = im;
+
+ CAMLreturn(v);
+}
+
+value ml_image_create_truecolor(value sx, value sy) {
+ CAMLparam2(sx, sy);
+ CAMLlocal1(v);
+ gdImagePtr im;
+
+ im = gdImageCreateTrueColor(Int_val(sx), Int_val(sy));
+ if (!im)
+ raise_constant(*(value *)caml_named_value("gdopen failed"));
+
+ v = alloc_custom(&image_t_custom_operations, sizeof(GdWrapper),
+ (Int_val(sx) * Int_val(sy)) + sizeof(gdImage), 10000);
+ IM_VAL(v) = im;
+
+ CAMLreturn(v);
+}
+
+value ml_image_open_png(value filename) {
+ CAMLparam1(filename);
+ CAMLlocal1(v);
+ FILE *in;
+ gdImagePtr im;
+
+ in = fopen(String_val(filename), "rb");
+ if (!in)
+ raise_not_found();
+
+ im = gdImageCreateFromPng(in);
+
+ fclose(in);
+
+ if (!im)
+ raise_constant(*(value *)caml_named_value("gdopen failed"));
+
+ v = alloc_custom(&image_t_custom_operations, sizeof(GdWrapper),
+ sizeof(gdImage) + (gdImageSX(im) * gdImageSY(im)), 100000);
+ IM_VAL(v) = im;
+
+ CAMLreturn(v);
+}
+
+/* This is useful when an image has been created from a PNG file,
+ * so it could be either truecolor or 8-bit. */
+value ml_image_is_truecolor(value gdw) {
+ gdImagePtr im;
+ im = IM_VAL(gdw);
+ if (im->trueColor) {
+ return Val_true;
+ }
+ else {
+ return Val_false;
+ }
+}
+
+value ml_image_open_jpeg(value filename) {
+#ifdef HAVE_JPEG
+ FILE *in;
+ gdImagePtr im;
+ CAMLparam1(filename);
+ CAMLlocal1(v);
+
+ in = fopen(String_val(filename), "rb");
+ if (!in)
+ raise_not_found();
+
+ im = gdImageCreateFromJpeg(in);
+
+ fclose(in);
+
+ if (!im)
+ raise_constant(*(value *)caml_named_value("gdopen failed"));
+
+ v = alloc_custom(&image_t_custom_operations, sizeof(GdWrapper),
+ sizeof(gdImage) + (gdImageSX(im) * gdImageSY(im)), 100000);
+ IM_VAL(v) = im;
+ CAMLreturn(v);
+#else
+ raise_constant(*(value *)caml_named_value("gd type not supported"));
+ return Val_unit;
+#endif
+}
+
+value ml_image_line_native(value gdw, value x1, value y1, value x2, value y2,
+ value c, value pc) {
+ int pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0)
+ gdImageLine(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2), Int_val(y2),
+ pseudoColors[pcval]);
+ else
+ gdImageLine(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2), Int_val(y2),
+ Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_line(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 7);
+#endif
+ return
+ ml_image_line_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6]);
+}
+
+value ml_image_dline_native(value gdw, value x1, value y1, value x2, value y2,
+ value c, value pc) {
+ int pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0)
+ gdImageDashedLine(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2),
+ Int_val(y2), pseudoColors[pcval]);
+ else
+ gdImageDashedLine(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2),
+ Int_val(y2), Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_dline(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 7);
+#endif
+ return
+ ml_image_line_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6]);
+}
+
+value ml_image_rect_native(value gdw, value x1, value y1, value x2, value y2,
+ value c, value pc) {
+ int pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0)
+ gdImageRectangle(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2),
+ Int_val(y2), pseudoColors[pcval]);
+ else
+ gdImageRectangle(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2),
+ Int_val(y2), Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_rect(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 7);
+#endif
+ return
+ ml_image_rect_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6]);
+}
+
+value ml_image_frect_native(value gdw, value x1, value y1, value x2, value y2,
+ value c, value pc) {
+ int pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0)
+ gdImageFilledRectangle(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2),
+ Int_val(y2), pseudoColors[pcval]);
+ else
+ gdImageFilledRectangle(IM_VAL(gdw), Int_val(x1), Int_val(y1), Int_val(x2),
+ Int_val(y2), Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_frect(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 7);
+#endif
+ return
+ ml_image_frect_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6]);
+}
+
+/* Draw a polygon. */
+value ml_image_poly(value gdw, value points, value numpts, value c, value pc) {
+ gdPoint gd_points[numpts];
+ int i, n, pcval;
+ pcval = Int_val(pc);
+
+ n = Int_val(numpts);
+ for (i = 0; i < n; i++) {
+ gd_points[i].x = Int_val(Field(Field(points, i), 0));
+ gd_points[i].y = Int_val(Field(Field(points, i), 1));
+ }
+
+ if (pcval >= 0)
+ gdImagePolygon(IM_VAL(gdw), gd_points, Int_val(numpts), pseudoColors[pcval]);
+ else
+ gdImagePolygon(IM_VAL(gdw), gd_points, Int_val(numpts), Int_val(c));
+
+ return Val_unit;
+}
+
+/* Draw a filled polygon. */
+value ml_image_fpoly(value gdw, value points, value numpts, value c, value pc) {
+ gdPoint gd_points[numpts];
+ int i, n, pcval;
+ pcval = Int_val(pc);
+
+ n = Int_val(numpts);
+ for (i = 0; i < n; i++) {
+ gd_points[i].x = Int_val(Field(Field(points, i), 0));
+ gd_points[i].y = Int_val(Field(Field(points, i), 1));
+ }
+
+ if (pcval >= 0)
+ gdImageFilledPolygon(IM_VAL(gdw), gd_points, Int_val(numpts), pseudoColors[pcval]);
+ else
+ gdImageFilledPolygon(IM_VAL(gdw), gd_points, Int_val(numpts), Int_val(c));
+
+ return Val_unit;
+}
+
+value ml_image_fell_native(value gdw, value cx, value cy, value w, value h,
+ value c, value pc) {
+ int pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0)
+ gdImageFilledEllipse(IM_VAL(gdw), Int_val(cx), Int_val(cy), Int_val(w),
+ Int_val(h), pseudoColors[pcval]);
+ else
+ gdImageFilledEllipse(IM_VAL(gdw), Int_val(cx), Int_val(cy), Int_val(w),
+ Int_val(h), Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_fell(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 7);
+#endif
+ return
+ ml_image_fell_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6]);
+}
+
+value ml_image_arc_native(value gdw, value cx, value cy, value w, value h,
+ value s, value e, value c, value pc) {
+ int pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0)
+ gdImageArc(IM_VAL(gdw), Int_val(cx), Int_val(cy), Int_val(w), Int_val(h),
+ Int_val(s), Int_val(e), pseudoColors[pcval]);
+ else
+ gdImageArc(IM_VAL(gdw), Int_val(cx), Int_val(cy), Int_val(w), Int_val(h),
+ Int_val(s), Int_val(e), Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_arc(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 9);
+#endif
+ return
+ ml_image_arc_native(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8]);
+}
+
+value ml_image_carc_native(value gdw, value cx, value cy, value w,
+ value h, value s, value e, value c,
+ value pc, value nofill, value edged) {
+ int color, style, pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0) color = pseudoColors[pcval];
+ else color = Int_val(c);
+ style = gdArc;
+ if (Bool_val(nofill)) style |= gdNoFill;
+ if (Bool_val(edged)) style |= gdEdged;
+
+ gdImageFilledArc(IM_VAL(gdw), Int_val(cx), Int_val(cy), Int_val(w),
+ Int_val(h), Int_val(s), Int_val(e), color, style);
+
+ return Val_unit;
+}
+
+value ml_image_carc(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 11);
+#endif
+ return
+ ml_image_carc_native(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8], argv[9], argv[10]);
+}
+
+value ml_image_cchord_native(value gdw, value cx, value cy, value w,
+ value h, value s, value e, value c,
+ value pc, value nofill, value edged) {
+ int color, style, pcval;
+ pcval = Int_val(pc);
+
+ if (pcval >= 0) color = pseudoColors[pcval];
+ else color = Int_val(c);
+ style = gdChord;
+ if (Bool_val(nofill)) style |= gdNoFill;
+ if (Bool_val(edged)) style |= gdEdged;
+
+ gdImageFilledArc(IM_VAL(gdw), Int_val(cx), Int_val(cy), Int_val(w),
+ Int_val(h), Int_val(s), Int_val(e), color, style);
+
+ return Val_unit;
+}
+
+value ml_image_cchord(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 11);
+#endif
+ return
+ ml_image_cchord_native(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8], argv[9], argv[10]);
+}
+
+value ml_image_border_fill_native(value gdw, value x, value y, value b,
+ value c) {
+ gdImageFillToBorder(IM_VAL(gdw), Int_val(x), Int_val(y), Int_val(b),
+ Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_border_fill(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 5);
+#endif
+ return
+ ml_image_border_fill_native(argv[0], argv[1], argv[2], argv[3], argv[4]);
+}
+
+value ml_image_fill(value gdw, value x, value y, value c) {
+ gdImageFill(IM_VAL(gdw), Int_val(x), Int_val(y), Int_val(c));
+ return Val_unit;
+}
+
+
+value ml_image_char_native(value gdw, value font, value x, value y, value c,
+ value color) {
+ gdImageChar(IM_VAL(gdw), FONT_VAL(font), Int_val(x), Int_val(y), Int_val(c),
+ Int_val(color));
+ return Val_unit;
+}
+
+value ml_image_char(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 6);
+#endif
+ return ml_image_char_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5]);
+}
+
+value ml_image_charu_native(value gdw, value font, value x, value y, value c,
+ value color) {
+ gdImageCharUp(IM_VAL(gdw), FONT_VAL(font), Int_val(x), Int_val(y), Int_val(c),
+ Int_val(color));
+ return Val_unit;
+}
+
+value ml_image_charu(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 6);
+#endif
+ return ml_image_charu_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5]);
+}
+
+value ml_image_str_native(value gdw, value font, value x, value y, value s,
+ value color) {
+ gdImageString(IM_VAL(gdw), FONT_VAL(font), Int_val(x), Int_val(y),
+ String_val(s), Int_val(color));
+ return Val_unit;
+}
+
+value ml_image_str(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 6);
+#endif
+ return ml_image_str_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5]);
+}
+
+value ml_image_stru_native(value gdw, value font, value x, value y, value s,
+ value color) {
+ gdImageStringUp(IM_VAL(gdw), FONT_VAL(font), Int_val(x), Int_val(y),
+ String_val(s), Int_val(color));
+ return Val_unit;
+}
+
+value ml_image_stru(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 6);
+#endif
+ return ml_image_stru_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5]);
+}
+
+
+void raise_freetype_exception(char *msg) {
+ raise_with_string(*caml_named_value("gd freetype exception"), msg);
+}
+
+
+value ml_image_str_ft_base(gdImagePtr im, value fg, value fname, value size,
+ value angle, value x, value y, value string) {
+
+#ifdef HAVE_FREETYPE
+ CAMLparam5(fg, fname, size, angle, x);
+ CAMLxparam2(y, string);
+
+ int brect[8];
+ int i;
+ char *rc;
+
+ CAMLlocal1(ml_brect);
+ ml_brect = alloc (8, 0);
+
+ rc = gdImageStringFT(im, brect, Int_val(fg), String_val(fname),
+ Double_val(size), Double_val(angle), Int_val(x),
+ Int_val(y), String_val(string));
+
+ if (rc != NULL) {
+ raise_freetype_exception (rc);
+ }
+
+ for (i = 0; i < 8; i++)
+ Store_field(ml_brect, i, Val_int(brect[i]));
+
+ CAMLreturn(ml_brect);
+#else
+ raise_constant(*(value *)caml_named_value("gd type not supported"));
+ return Val_unit;
+#endif
+}
+
+value ml_image_str_ft_native(value gdw, value fg, value fname, value size,
+ value angle, value x, value y, value string) {
+ CAMLparam5(gdw, fg, fname, size, angle);
+ CAMLxparam3(x, y, string);
+
+ CAMLreturn(ml_image_str_ft_base(IM_VAL(gdw), fg, fname, size, angle,
+ x, y, string));
+}
+
+value ml_image_str_ft(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 8);
+#endif
+ return ml_image_str_ft_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7]);
+}
+
+value ml_image_ft_bbox_native(value fname, value size, value angle,
+ value x, value y, value string) {
+ CAMLparam5(fname, size, angle, x, y);
+ CAMLxparam1(string);
+
+ CAMLreturn(ml_image_str_ft_base(NULL, 0, fname, size, angle,
+ x, y, string));
+}
+
+
+value ml_image_ft_bbox(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 6);
+#endif
+ return ml_image_ft_bbox_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5]);
+}
+
+
+value ml_image_str_ftex_base(gdImagePtr im, value fg, value fname, value size,
+ value angle, value x, value y, value flags,
+ value spacing, value charmap, value string) {
+#ifdef HAVE_FREETYPE
+ int numflags, i;
+ int brect[8];
+ char *rc;
+ gdFTStringExtra extra;
+
+ CAMLparam5(fg, fname, size, angle, x);
+ CAMLxparam5(y, flags, spacing, charmap, string);
+ CAMLlocal1(ml_brect);
+
+ numflags = Wosize_val(flags);
+
+ for (i = 0; i < numflags; i++)
+ extra.flags |= ftExFlags[Int_val(Field(flags, i))];
+ extra.linespacing = Double_val(spacing);
+ extra.charmap = ftExCharmaps[Int_val(charmap)];
+
+ ml_brect = alloc (8, 0);
+
+ rc = gdImageStringFTEx(im, brect, Int_val(fg), String_val(fname),
+ Double_val(size), Double_val(angle), Int_val(x),
+ Int_val(y), String_val(string), &extra);
+
+ if (rc != NULL) {
+ raise_freetype_exception (rc);
+ }
+
+ for (i = 0; i < 8; i++)
+ Store_field(ml_brect, i, Val_int(brect[i]));
+
+ CAMLreturn(ml_brect);
+#else
+ raise_constant(*(value *)caml_named_value("gd type not supported"));
+ return Val_unit;
+#endif
+}
+
+value ml_image_str_ftex_native(value gdw, value fg, value fname, value size,
+ value angle, value x, value y, value flags,
+ value spacing, value charmap, value string) {
+ CAMLparam5(gdw, fg, fname, size, angle);
+ CAMLxparam5(x, y, flags, spacing, charmap);
+ CAMLxparam1(string);
+
+ CAMLreturn(ml_image_str_ftex_base(IM_VAL(gdw), fg, fname, size, angle,
+ x, y, flags, spacing, charmap, string));
+}
+
+value ml_image_str_ftex(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 11);
+#endif
+ return ml_image_str_ftex_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7],
+ argv[8], argv[9], argv[10]);
+}
+
+value ml_image_ftex_bbox_native(value fname, value size, value angle,
+ value x, value y, value flags, value spacing,
+ value charmap, value string) {
+ CAMLparam5(fname, size, angle, x, y);
+ CAMLxparam4(flags, spacing, charmap, string);
+
+ CAMLreturn(ml_image_str_ftex_base(NULL, 0, fname, size, angle,
+ x, y, flags, spacing, charmap,
+ string));
+}
+
+
+value ml_image_ftex_bbox(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 9);
+#endif
+ return ml_image_ftex_bbox_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7],
+ argv[8]);
+}
+
+
+value ml_set_pixel(value gdw, value x, value y, value c) {
+ gdImageSetPixel(IM_VAL(gdw), Int_val(x), Int_val(y), Int_val(c));
+ return Val_unit;
+}
+
+value ml_get_pixel(value gdw, value x, value y) {
+ return Val_int(gdImageGetPixel(IM_VAL(gdw), Int_val(x), Int_val(y)));
+}
+
+value ml_get_width(value gdw) {
+ return Val_int(gdImageSX(IM_VAL(gdw)));
+}
+
+value ml_get_height(value gdw) {
+ return Val_int(gdImageSY(IM_VAL(gdw)));
+}
+
+value ml_save_png(value gdw, value filename) {
+ FILE *out;
+
+ out = fopen(String_val(filename), "wb");
+ gdImagePng(IM_VAL(gdw), out);
+ fclose(out);
+
+ return Val_unit;
+}
+
+value ml_save_jpeg(value gdw, value filename, value quality) {
+#ifdef HAVE_JPEG
+ FILE *out;
+
+ out = fopen(String_val(filename), "wb");
+ gdImageJpeg(IM_VAL(gdw), out, Int_val(quality));
+ fclose(out);
+#else
+ raise_constant(*(value*)caml_named_value("gd type not supported"));
+#endif
+ return Val_unit;
+}
+
+/* Taken from the ocaml source... */
+struct channel;
+void really_putblock (struct channel *, char *, long);
+
+/* Extract a struct channel * from the heap object representing it */
+#define Channel(v) (*((struct channel **) (Data_custom_val(v))))
+
+value ml_dump_png(value gdw, value chan) {
+ int size;
+ void* dat;
+
+ dat = gdImagePngPtr(IM_VAL(gdw), &size);
+ really_putblock(Channel(chan), dat, size);
+ free(dat);
+
+ return Val_unit;
+}
+
+value ml_dump_jpeg(value gdw, value chan, value quality) {
+#ifdef HAVE_JPEG
+ int size;
+ void* dat;
+
+ dat = gdImageJpegPtr(IM_VAL(gdw), &size, Int_val(quality));
+ really_putblock(Channel(chan), dat, size);
+ free(dat);
+
+#else
+ raise_constant(*(value*)caml_named_value("gd type not supported"));
+#endif
+ return Val_unit;
+}
+
+
+value ml_image_set_antialiased(value gdw, value c) {
+ gdImageSetAntiAliased(IM_VAL(gdw), Int_val(c));
+ return Val_unit;
+}
+
+value ml_image_set_antialiased_dont_blend(value gdw, value aa, value db) {
+ gdImageSetAntiAliasedDontBlend(IM_VAL(gdw), Int_val(aa), Int_val(db));
+ return Val_unit;
+}
+
+value ml_image_set_brush(value gdw, value br) {
+ gdImageSetBrush(IM_VAL(gdw), IM_VAL(br));
+ return Val_unit;
+}
+
+value ml_image_set_tile(value gdw, value t) {
+ gdImageSetTile(IM_VAL(gdw), IM_VAL(t));
+ return Val_unit;
+}
+
+value ml_image_set_thickness(value gdw, value t) {
+ gdImageSetThickness(IM_VAL(gdw), Int_val(t));
+ return Val_unit;
+}
+
+value ml_image_set_clip(value gdw, value x1, value y1, value x2, value y2) {
+ gdImageSetClip(IM_VAL(gdw), Int_val(x1), Int_val(y1),
+ Int_val(x2), Int_val(y2));
+
+ return Val_unit;
+}
+
+value ml_image_color_alloc(value gdw, value r, value g, value b) {
+ int color;
+
+ color = gdImageColorAllocate(IM_VAL(gdw), Int_val(r), Int_val(g), Int_val(b));
+
+ return Val_int(color);
+}
+
+value ml_image_color_closest(value gdw, value r, value g, value b) {
+ int color;
+
+ color = gdImageColorClosest(IM_VAL(gdw), Int_val(r), Int_val(g), Int_val(b));
+
+ return Val_int(color);
+}
+
+value ml_image_color_closest_hwb(value gdw, value r, value g, value b) {
+ int color;
+
+ color =
+ gdImageColorClosestHWB(IM_VAL(gdw), Int_val(r), Int_val(g), Int_val(b));
+ return Val_int(color);
+}
+
+value ml_image_color_exact(value gdw, value r, value g, value b) {
+ int color;
+
+ color = gdImageColorExact(IM_VAL(gdw), Int_val(r), Int_val(g), Int_val(b));
+
+ return Val_int(color);
+}
+
+value ml_image_color_resolve(value gdw, value r, value g, value b) {
+ int color;
+
+ color = gdImageColorResolve(IM_VAL(gdw), Int_val(r), Int_val(g), Int_val(b));
+
+ return Val_int(color);
+}
+
+value ml_image_red_channel(value gdw, value c) {
+ return Val_int(gdImageRed(IM_VAL(gdw), Int_val(c)));
+}
+
+value ml_image_green_channel(value gdw, value c) {
+ return Val_int(gdImageGreen(IM_VAL(gdw), Int_val(c)));
+}
+
+value ml_image_blue_channel(value gdw, value c) {
+ return Val_int(gdImageBlue(IM_VAL(gdw), Int_val(c)));
+}
+
+value ml_image_alpha_channel(value gdw, value c) {
+ return Val_int(gdImageAlpha(IM_VAL(gdw), Int_val(c)));
+}
+
+value ml_image_get_transparent(value gdw) {
+ return Val_int(gdImageGetTransparent(IM_VAL(gdw)));
+}
+
+value ml_image_set_transparent(value gdw, value c) {
+ gdImageColorTransparent(IM_VAL(gdw), Int_val(c));
+ return Val_unit;
+}
+
+/* ================================================================== */
+/* ============ Image Copying and Resizing Functions ================ */
+/* ================================================================== */
+
+value ml_image_copy_native(value dst, value src, value dst_x, value dst_y,
+ value src_x, value src_y, value w, value h) {
+ gdImageCopy(IM_VAL(dst), IM_VAL(src), Int_val(dst_x), Int_val(dst_y),
+ Int_val(src_x), Int_val(src_y), Int_val(w), Int_val(h));
+ return Val_unit;
+}
+
+value ml_image_copy(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 8);
+#endif
+ return
+ ml_image_copy_native(argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7]);
+}
+
+
+value ml_image_copy_resized_native(value dst, value src, value dst_x,
+ value dst_y, value src_x, value src_y,
+ value dst_w, value dst_h, value src_w,
+ value src_h) {
+ gdImageCopyResized(IM_VAL(dst), IM_VAL(src), Int_val(dst_x),
+ Int_val(dst_y), Int_val(src_x), Int_val(src_y),
+ Int_val(dst_w), Int_val(dst_h), Int_val(src_w),
+ Int_val(src_h));
+ return Val_unit;
+}
+
+value ml_image_copy_resized(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 10);
+#endif
+ return
+ ml_image_copy_resized_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7],
+ argv[8], argv[9]);
+}
+
+
+value ml_image_copy_resampled_native(value dst, value src, value dst_x,
+ value dst_y, value src_x, value src_y,
+ value dst_w, value dst_h, value src_w,
+ value src_h) {
+ gdImageCopyResampled(IM_VAL(dst), IM_VAL(src), Int_val(dst_x),
+ Int_val(dst_y), Int_val(src_x), Int_val(src_y),
+ Int_val(dst_w), Int_val(dst_h), Int_val(src_w),
+ Int_val(src_h));
+ return Val_unit;
+}
+
+value ml_image_copy_resampled(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 10);
+#endif
+ return
+ ml_image_copy_resampled_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7],
+ argv[8], argv[9]);
+}
+
+
+value ml_image_copy_rotated_native(value dst, value src, value dst_x,
+ value dst_y, value src_x, value src_y,
+ value w, value h, value angle) {
+ gdImageCopyRotated(IM_VAL(dst), IM_VAL(src), Double_val(dst_x),
+ Double_val(dst_y), Int_val(src_x), Int_val(src_y),
+ Int_val(w), Int_val(h), Int_val(angle));
+ return Val_unit;
+}
+
+value ml_image_copy_rotated(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 9);
+#endif
+ return
+ ml_image_copy_rotated_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7],
+ argv[8]);
+}
+
+
+value ml_image_copy_merge_native(value dst, value src, value dst_x,
+ value dst_y, value src_x, value src_y,
+ value w, value h, value pct) {
+ gdImageCopyMerge(IM_VAL(dst), IM_VAL(src), Int_val(dst_x), Int_val(dst_y),
+ Int_val(src_x), Int_val(src_y), Int_val(w), Int_val(h),
+ Int_val(pct));
+ return Val_unit;
+}
+
+value ml_image_copy_merge(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 9);
+#endif
+ return
+ ml_image_copy_merge_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7],
+ argv[8]);
+}
+
+
+value ml_image_copy_merge_gray_native(value dst, value src, value dst_x,
+ value dst_y, value src_x, value src_y,
+ value w, value h, value pct) {
+ gdImageCopyMergeGray(IM_VAL(dst), IM_VAL(src), Int_val(dst_x),
+ Int_val(dst_y), Int_val(src_x), Int_val(src_y),
+ Int_val(w), Int_val(h), Int_val(pct));
+ return Val_unit;
+}
+
+value ml_image_copy_merge_gray(value *argv, int argc) {
+#ifdef SAFER
+ assert (argc == 9);
+#endif
+ return
+ ml_image_copy_merge_gray_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5], argv[6], argv[7],
+ argv[8]);
+}
+
+
+value ml_image_palette_copy(value dst, value src) {
+ gdImagePaletteCopy(IM_VAL(dst), IM_VAL(src));
+ return Val_unit;
+}
diff --git a/gdtest.ml b/gdtest.ml
new file mode 100644
index 0000000..3cdae75
--- /dev/null
+++ b/gdtest.ml
@@ -0,0 +1,581 @@
+(* $Header: /home/cvs/gd4o/gdtest.ml,v 1.7 2003/11/25 01:02:32 matt Exp $ *)
+(*
+ * GD4O: An OCaml interface to the Gd graphics library.
+ * Based on Shawn Wagner's OCamlGD 0.7.0.
+ * Copyright (C) 2002 Shawn Wagner
+ * Copyright (C) 2003 Matthew C. Gushee
+ *
+ * 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
+ *)
+
+open Gd;;
+
+
+let write_header ch title desc =
+ output_string ch ("************************************" ^
+ "************************************\n\n");
+ output_string ch (title ^ ":\n");
+ output_string ch (desc ^ "\n\n");
+ output_string ch ("------------------------------------" ^
+ "------------------------------------\n\n\n")
+
+let write_footer ch msg =
+ output_string ch ("\n\n" ^ msg ^ "\n");
+ output_string ch ("====================================" ^
+ "====================================\n\n\n")
+
+let ok n msg = " " ^ string_of_int n ^ ": [--OK--]: " ^ msg ^ "\n"
+let failed n msg = " " ^ string_of_int n ^ ": [FAILED]: " ^ msg ^ "\n"
+
+let skiplineRE = Str.regexp "^\\([ \t]*#.*\\|[ \t]*\\)$"
+
+let deg2rad = ( *. ) (3.1415926535 /. 180.)
+
+let tempdir =
+ try
+ Sys.getenv "TMP"
+ with Not_found ->
+ begin
+ try
+ Sys.getenv "TEMP"
+ with Not_found ->
+ if Sys.file_exists "/tmp" then "/tmp"
+ else if Sys.file_exists "/var/tmp" then "/var/tmp"
+ else Sys.getcwd ()
+ end;;
+
+
+let shapes_test msg_ch =
+ write_header msg_ch "SHAPES"
+ ( "Create an image displaying various interesting shapes.\n" ^
+ "Save output as 'shapes_test.png'.");
+ let msg = output_string msg_ch in
+ let img =
+ try
+ let i = create 512 384 in
+ msg (ok 1 "created image");
+ i
+ with _ -> failwith "Failed to create image." in
+ let ca =
+ try
+ let c = img#colors in
+ msg (ok 2 "obtained color allocator instance");
+ c
+ with _ -> failwith "Failed to get color allocator." in
+ let white =
+ try
+ let w = ca#white in
+ msg (ok 3 "allocated white");
+ w
+ with _ -> failwith "Failed to get white."
+ and ltblue, maroon, orange, aqua, grey, brown =
+ try
+ let more =
+ ca#create 127 127 255, ca#create 127 0 0, ca#create 191 127 0,
+ ca#create 0 153 204, ca#create 153 153 153, ca#create 127 127 0 in
+ msg (ok 4 "allocated additional colors");
+ more
+ with _ -> failwith "Failed to create additional colors." in
+ begin
+ try
+ img#rectangle 10 10 180 140 maroon;
+ msg (ok 5 "drew outline rectangle")
+ with _ -> msg (failed 5 "Failed to draw outline rectangle.")
+ end;
+ begin
+ try
+ img#filled_rectangle 50 40 220 170 ltblue;
+ msg (ok 6 "drew filled rectangle")
+ with _ -> msg (failed 6 "Failed to draw filled rectangle.")
+ end;
+ begin
+ try
+ img#set_antialiased aqua;
+ begin
+ try
+ img#arc ~cx:108 ~cy:276 ~w:192 ~h:128 ~s:0 ~e:270
+ ~pseudo:(ca#antialiased ()) aqua;
+ msg (ok 7 "drew partial outline arc with antialiased pseudocolor")
+ with _ -> msg (failed 7 "Failed to draw partial outline arc.")
+ end
+ with _ -> msg (failed 7 "Failed to set antialiased color.")
+ end;
+ begin
+ try
+ img#filled_ellipse 144 300 192 128 grey;
+ msg (ok 8 "drew filled ellipse")
+ with _ -> msg (failed 8 "Failed to draw filled ellipse.")
+ end;
+ begin
+ try
+ img#set_antialiased brown;
+ begin
+ try
+ img#polygon
+ ~pts:[|280,80;340,32;440,48;440,144;360,144;280,108;280,80|]
+ ~pseudo:(ca#antialiased ()) brown;
+ msg (ok 9 "drew outline polygon with antialiased pseudocolor")
+ with _ -> msg (failed 9 "Failed to draw polygon.")
+ end
+ with _ -> msg (failed 9 "Failed to set antialiased color.")
+ end;
+ begin
+ try
+ img#filled_polygon
+ [|320,110;380,62;480,78;480,174;400,174;320,138;320,110|] orange;
+ msg (ok 10 "drew filled polyon")
+ with _ -> msg (failed 10 "Failed to draw filled polygon.")
+ end;
+ begin
+ try
+ img#string
+ ~x:244 ~y:228 ~font:Gd.Font.giant
+ ~s:"As I was coming up the stair," orange;
+ msg (ok 11 "drew string 1")
+ with _ -> msg (failed 11 "Failed to draw string 1.")
+ end;
+ begin
+ try
+ img#string
+ ~x:254 ~y:260 ~font:Gd.Font.large
+ ~s:"I met a man who wasn't there." grey;
+ msg (ok 12 "drew string 2")
+ with _ -> msg (failed 12 "Failed to draw string 2.")
+ end;
+ begin
+ try
+ img#string
+ ~x:264 ~y:290 ~font:Gd.Font.medium
+ ~s:"He wasn't there again today!" aqua;
+ msg (ok 13 "drew string 3")
+ with _ -> msg (failed 13 "Failed to draw string 3.")
+ end;
+ begin
+ try
+ img#string
+ ~x:274 ~y:318 ~font:Gd.Font.small
+ ~s:"I wish, I wish, he'd go away." maroon;
+ msg (ok 14 "drew string 4")
+ with _ -> msg (failed 14 "Failed to draw string 4.")
+ end;
+ img#save_as_png (Filename.concat tempdir "shapes_test.png");
+ write_footer msg_ch "END SHAPES"
+
+
+let color_allocation_test msg_ch =
+ write_header msg_ch "COLOR ALLOCATION"
+ ("Create an 8-bit image and a truecolor image, and attempt to allocate\n"^
+ "a large number of colors in each. The test should fail at index 256 \n"^
+ "for the 8-bit image, and should *not* fail for the truecolor image.");
+ let msg = output_string msg_ch in
+ let rgbvals = [|0; 31; 63; 95; 127; 159; 191; 223; 255|] in
+ let numvals = Array.length rgbvals in
+ let last = numvals - 1 in
+ let do_colors img is_tc testno =
+ let (ca : color_allocator) = img#colors
+ and index = ref 0 in
+ try
+ for r = 0 to last do
+ for g = 0 to last do
+ for b = 0 to last do
+ index := (r * numvals * numvals + g * numvals + b);
+ ignore (ca#create rgbvals.(r) rgbvals.(g) rgbvals.(b))
+ done;
+ done;
+ done;
+ if is_tc then
+ msg (ok testno "Truecolor - all colors successfully allocated.")
+ else
+ msg (failed testno "8bit - too many colors allocated without error.")
+ with
+ | Too_many_colors ->
+ if is_tc then
+ msg (failed testno ("Truecolor - failed at index " ^
+ string_of_int !index ^ ".")) else
+ if !index = 256 then
+ msg (ok testno "8bit - failed at index 256.")
+ else
+ msg (failed testno ("8bit - failed at index " ^
+ string_of_int !index ^ "."))
+ | _ ->
+ if is_tc then msg (failed testno ("Truecolor - unknown exception " ^
+ "at index " ^
+ string_of_int !index ^ "."))
+ else msg (failed testno ("8bit - unknown exception at index " ^
+ string_of_int !index ^ ".")) in
+ do_colors (create 256 256) false 1;
+ do_colors (create_truecolor 256 256) true 2;
+ write_footer msg_ch "END COLOR ALLOCATION"
+
+
+let copy_resize_test msg_ch =
+ write_header msg_ch "COPYING AND RESIZING"
+ ( "Test copying and resizing functions.\n" ^
+ "1. Copy a small image into a larger image with 'copy'.\n" ^
+ "2. Copy a portion of an image into a larger image with 'copy'.\n" ^
+ "3. Copy a small image into a larger image with 'copy_resized'.\n" ^
+ "4. Copy a small image into a larger image with 'copy_resampled'.\n" ^
+ " Compare the output with that of test #2; details should be\n" ^
+ " smoother.\n" ^
+ "5. Copy a small image into a larger image with 'copy_rotated'.\n" ^
+ "6. Copy a small image into a larger image with 'copy_merge'.\n" ^
+ "7. Copy a small image into a larger image with 'copy_merge_gray'.\n" ^
+ "8. Create a new image, copy the palette from an existing image,\n" ^
+ " then copy the contents of the second image. If the palette is\n" ^
+ " copied correctly, this should produce a copy whose colors and\n" ^
+ " dimensions are identical to the original.\n");
+ let msg = output_string msg_ch in
+ let indexed_img1 = "yotei02-8.png"
+ and truecolor_img1 = "yotei02-t.png"
+ and indexed_img2 = "driver01-8.png"
+ and truecolor_img2 = "driver01-t.png"
+ and indexed_img3 = "kamokamogawa04-8.png"
+ and truecolor_img3 = "kamokamogawa04-t.png" in
+ let img_path name =
+ Filename.concat "." (Filename.concat "samples" name) in
+
+ let get_dims dst src = dst#width, dst#height, src#width, src#height in
+
+ let test1 img1 img2 =
+ let dst = open_png (img_path img1)
+ and src = open_png (img_path img2) in
+ try
+ let outfile = "copy.png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ dst#copy src ~x:((dw - sw) / 2) ~y:((dh - sh) / 2)
+ ~src_x:0 ~src_y:0 ~w:sw ~h:sh;
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 1 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 1 "image#copy test failed.")
+
+ and test2 img1 img2 =
+ let dst = open_png (img_path img1)
+ and src = open_png (img_path img2) in
+ try
+ let outfile = "copy(crop).png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ let crop_x = int_of_float ((float_of_int sw) *. 0.35)
+ and crop_y = int_of_float ((float_of_int sh) *. 0.35) in
+ dst#copy src ~x:(dw / 2) ~y:(dh / 2)
+ ~src_x:crop_x ~src_y:crop_y ~w:(sw / 2) ~h:(sh / 2);
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 2 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 2 "image#copy cropping test failed.")
+
+ and test3 img1 img2 =
+ let dst = open_png (img_path img1)
+ and src = open_png (img_path img2) in
+ try
+ let outfile = "copy_resized.png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ let new_w = (int_of_float ((float_of_int sw) *. 0.75))
+ and new_h = (int_of_float ((float_of_int sh) *. 1.1)) in
+ dst#copy_resized src ~x:((dw - new_w) / 2) ~y:((dh - new_h) / 2)
+ ~src_x:0 ~src_y:0 ~src_w:sw ~src_h:sh ~w:new_w ~h:new_h;
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 3 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 3 "image#copy_resized test failed.")
+
+ and test4 img1 img2 =
+ let dst = open_png (img_path img1)
+ and src = open_png (img_path img2) in
+ try
+ let outfile = "copy_resampled.png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ let new_w = (int_of_float ((float_of_int sw) *. 0.75))
+ and new_h = (int_of_float ((float_of_int sh) *. 1.1)) in
+ dst#copy_resampled src ~x:((dw - new_w) / 2) ~y:((dh - new_h) / 2)
+ ~src_x:0 ~src_y:0 ~src_w:sw ~src_h:sh ~w:new_w ~h:new_h;
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 4 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 4 "image#copy_resampled test failed.")
+
+ and test5 img1 img2 =
+ let dst = open_png (img_path img1)
+ and src = open_png (img_path img2) in
+ try
+ let outfile = "copy_rotated.png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ let cx = (float_of_int dw) /. 2.
+ and cy = (float_of_int dh) /. 2. in
+ dst#copy src ~x:((dw - sw) / 2) ~y:((dh - sh) / 2)
+ ~src_x:0 ~src_y:0 ~w:sw ~h:sh;
+ dst#copy_rotated src ~x:cx ~y:cy
+ ~src_x:0 ~src_y:0 ~w:sw ~h:sh ~angle:30;
+ dst#copy_rotated src ~x:cx ~y:cy
+ ~src_x:0 ~src_y:0 ~w:sw ~h:sh ~angle:60;
+ dst#copy_rotated src ~x:cx ~y:cy
+ ~src_x:0 ~src_y:0 ~w:sw ~h:sh ~angle:90;
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 5 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 5 "image#copy_rotated test failed.")
+
+ and test6 img =
+ let src = open_png (img_path img) in
+ let sw = src#width
+ and sh = src#height in
+ let dw = sw * 2
+ and dh = sh * 2 in
+ let dst = create ~x:dw ~y:dh in
+ try
+ let outfile = "copy_merge.png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ let ca = dst#colors in
+ ignore (ca#create 0 204 153);
+ dst#copy_merge src ~x:((dw - sw) / 2) ~y:((dh - sh) / 2)
+ ~src_x:0 ~src_y:0 ~w:sw ~h:sh ~pct:50;
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 6 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 6 "image#copy_merge test failed.")
+
+ and test7 img =
+ let src = open_png (img_path img) in
+ let sw = src#width
+ and sh = src#height in
+ let dw = sw * 2
+ and dh = sh * 2 in
+ let dst = create ~x:dw ~y:dh in
+ try
+ let outfile = "copy_merge_gray.png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ let ca = dst#colors in
+ ignore (ca#create 0 204 153);
+ dst#copy_merge_gray src ~x:((dw - sw) / 2) ~y:((dh - sh) / 2)
+ ~src_x:0 ~src_y:0 ~w:sw ~h:sh ~pct:50;
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 7 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 7 "image#copy_merge_gray test failed.")
+
+ and test8 img =
+ let src = open_png (img_path img) in
+ let sw = src#width
+ and sh = src#height in
+ let dw = sw
+ and dh = sh in
+ let dst = create ~x:dw ~y:dh in
+ try
+ let outfile = "palette_copy.png" in
+ let dw, dh, sw, sh = get_dims dst src in
+ dst#palette_copy src;
+ dst#copy src ~x:0 ~y:0 ~src_x:0 ~src_y:0 ~w:sw ~h:sh;
+ dst#save_as_png (Filename.concat tempdir outfile);
+ msg (ok 8 ("Saved " ^ outfile ^ "."))
+ with _ ->
+ msg (failed 8 "image#palette_copy test failed.") in
+
+ test1 indexed_img1 indexed_img2;
+ test2 indexed_img1 indexed_img2;
+ test3 truecolor_img1 indexed_img2;
+ test4 truecolor_img1 indexed_img2;
+ test5 truecolor_img1 truecolor_img2;
+ test6 indexed_img2;
+ test7 indexed_img2;
+ test8 indexed_img3;
+
+ write_footer msg_ch "END COPYING AND RESIZING"
+
+
+let io_test msg_ch =
+ write_header msg_ch "INPUT/OUTPUT"
+ ( "Test loading and saving functions.\n" ^
+ "1. Save to PNG with 'save_to_png'.\n" ^
+ "2. Save to JPEG with 'save_to_jpeg,' quality 100.\n" ^
+ "3. Save to JPEG with 'save_to_jpeg,' quality 60.\n" ^
+ "4. Save to PNG with 'open_out' -> 'out_as_png'.\n" ^
+ "5. Save to JPEG with 'open_out' -> 'out_as_jpeg'.\n");
+ let msg = output_string msg_ch in
+ let draw () =
+ let img = create 256 256 in
+ let ca = img#colors in
+ let white = ca#white
+ and red = ca#create 255 0 0
+ and black = ca#black in
+ img#filled_ellipse 64 64 100 100 red;
+ img#filled_ellipse 192 64 100 100 black;
+ img#filled_ellipse 64 192 100 100 black;
+ img#filled_ellipse 192 192 100 100 red;
+ img in
+ let fname = (Filename.concat tempdir "io_test-d.png")
+ and im = draw () in
+ begin
+ try
+ im#save_as_png fname;
+ msg (ok 1 "Saved " ^ fname)
+ with _ -> msg (failed 1 "Failed to save " ^ fname)
+ end;
+
+ let fname = Filename.concat tempdir "io_test-d-100.jpg"
+ and im = draw () in
+ begin
+ try
+ im#save_as_jpeg ~quality:100 fname;
+ msg (ok 2 "Saved " ^ fname);
+ with _ -> msg (failed 2 "Failed to save " ^ fname)
+ end;
+
+ let fname = Filename.concat tempdir "io_test-d-60.jpg"
+ and im = draw () in
+ begin
+ try
+ im#save_as_jpeg ~quality:60 fname;
+ msg (ok 3 "Saved " ^ fname);
+ with _ -> msg (failed 3 "Failed to save " ^ fname)
+ end;
+
+ let fname = Filename.concat tempdir "io_test-i.png"
+ and im = draw ()
+ and oc = open_out fname in
+ begin
+ try
+ im#out_as_png oc;
+ msg (ok 4 "Saved " ^ fname);
+ with _ -> msg (failed 4 "Failed to save " ^ fname)
+ end;
+ close_out oc;
+
+ let fname = Filename.concat tempdir "io_test-i.jpg"
+ and im = draw ()
+ and oc = open_out fname in
+ begin
+ try
+ im#out_as_jpeg oc;
+ msg (ok 5 "Saved " ^ fname);
+ with _ -> msg (failed 5 "Failed to save " ^ fname)
+ end;
+ close_out oc;
+ write_footer msg_ch "END INPUT/OUTPUT"
+
+
+let ft_test msg_ch fonts =
+ try
+ let [ f1; f2; f3; f4 ] = fonts in
+ write_header msg_ch "TRUETYPE FONT RENDERING"
+ ( "Test of #image#string_ft. Create an image with a white\n" ^
+ "background and four strings with the following properties:\n" ^
+ " 1. 24pt, blue, start at x:60,y:236, slopes upward 30 deg.\n" ^
+ " 2. 18pt, grey, start at x:60,y:272\n" ^
+ " 3. 12pt, red, start at x:60,y:96\n" ^
+ " 4. 8pt, black, start at x:60,y:316\n" ^
+ "Save output as 'ft_test.png'.");
+ let msg = output_string msg_ch in
+ let im = create 512 384 in
+ let ca = im#colors in
+ let white = ca#white
+ and black = ca#black
+ and grey = ca#create 153 153 153
+ and red = ca#create 204 0 0
+ and blue = ca#create 47 47 255 in
+ ignore (im#string_ft blue f1 24.0 (deg2rad 30.) 60 236
+ "As I was coming up the stair,");
+ msg (ok 1 "Rendered first string.");
+ ignore (im#string_ft grey f2 18.0 0.0 60 272
+ "I met a man who wasn't there.");
+ msg (ok 2 "Rendered second string.");
+ ignore (im#string_ft red f3 12.0 0.0 60 296
+ "He wasn't there again today!");
+ msg (ok 3 "Rendered third string.");
+ ignore (im#string_ft black f4 8.0 0.0 60 316
+ "I wish, I wish, he'd go away.");
+ msg (ok 4 "Rendered fourth string.");
+ im#save_as_png (Filename.concat tempdir "ft_test.png");
+ write_footer msg_ch "END TRUETYPE FONT RENDERING"
+ with Match_failure _ ->
+ prerr_endline
+ "The TrueType font test requires a list of four font files."
+
+
+let ftex_test msg_ch fonts =
+ try
+ let fnt = List.hd fonts in
+ write_header msg_ch "TRUETYPE FONT EXTENDED RENDERING"
+ ( "Test of #image#string_ftex. Create an image with a white\n" ^
+ "background and a four-line poem in black 14pt type, widely\n" ^
+ "spaced (2.5 * line height); save output as 'ftex_test.png'.");
+ let msg = output_string msg_ch in
+ let im = create 512 384 in
+ let ca = im#colors in
+ let white = ca#white
+ and black = ca#black in
+ let poem = ( "As I was coming up the stair,\n" ^
+ "I met a man who wasn't there.\n" ^
+ "He wasn't there again today!\n" ^
+ "I wish, I wish he'd go away." ) in
+ ignore (im#string_ftex ~fg:black ~fname:fnt ~size:14.0 ~angle:0.0
+ ~x:100 ~y:80 ~flags:[|FTExSetSpacing|] ~spacing:2.5 poem);
+ msg (ok 1 "Rendered poem.");
+ im#save_as_png (Filename.concat tempdir "ftex_test.png");
+ msg (ok 2 "Saved to 'ftex_test.png'");
+ write_footer msg_ch "END TRUETYPE FONT EXTENDED RENDERING"
+ with Match_failure _ ->
+ prerr_endline
+ "The TrueType font test requires a list of four font files."
+
+let ft_tests msg_ch =
+ let rec getfonts ch fnts =
+ if List.length fnts >= 4 then fnts
+ else
+ ( try
+ let line = input_line ch in
+ if Str.string_match skiplineRE line 0 then
+ getfonts ch fnts
+ else
+ getfonts ch (line :: fnts)
+ with End_of_file -> fnts ) in
+ if Sys.file_exists "font.list" then
+ let ic = open_in "font.list" in
+ let fonts = List.rev (getfonts ic []) in
+ close_in ic;
+ ft_test msg_ch fonts;
+ ftex_test msg_ch fonts
+ else
+ prerr_endline
+ ( "IMPORTANT: if you wish to run the TrueType font rendering tests,\n" ^
+ "you must have a file named 'font.list' which contains the full\n" ^
+ "pathnames of four font files that exist on your system. For an\n" ^
+ "example, see 'font_list.txt'" )
+
+
+let test msg_ch =
+ color_allocation_test msg_ch;
+ shapes_test msg_ch;
+ copy_resize_test msg_ch;
+ io_test msg_ch;
+ ft_tests msg_ch
+
+
+let _ =
+ prerr_endline ("::::::::::::::::::::::::::::::::::::" ^
+ "::::::::::::::::::::::::::::::::::::");
+ prerr_endline ("Starting tests. Files will be saved in " ^ tempdir ^ ".");
+ prerr_endline ("::::::::::::::::::::::::::::::::::::" ^
+ "::::::::::::::::::::::::::::::::::::");
+ if Array.length Sys.argv >= 2 then
+ let logfile = Sys.argv.(1) in
+ let msgchannel = open_out logfile in
+ test msgchannel;
+ prerr_endline ("Tests completed. For details, see " ^ logfile ^ ".");
+ close_out msgchannel
+ else
+ begin
+ test stderr;
+ prerr_endline "Tests completed."
+ end
diff --git a/samples/driver01-8.png b/samples/driver01-8.png
new file mode 100644
index 0000000..d4d834e
--- /dev/null
+++ b/samples/driver01-8.png
Binary files differ
diff --git a/samples/driver01-t.png b/samples/driver01-t.png
new file mode 100644
index 0000000..c672856
--- /dev/null
+++ b/samples/driver01-t.png
Binary files differ
diff --git a/samples/kamokamogawa04-8.png b/samples/kamokamogawa04-8.png
new file mode 100644
index 0000000..b7fe1b2
--- /dev/null
+++ b/samples/kamokamogawa04-8.png
Binary files differ
diff --git a/samples/kamokamogawa04-t.png b/samples/kamokamogawa04-t.png
new file mode 100644
index 0000000..d348f20
--- /dev/null
+++ b/samples/kamokamogawa04-t.png
Binary files differ
diff --git a/samples/yotei02-8.png b/samples/yotei02-8.png
new file mode 100644
index 0000000..df617da
--- /dev/null
+++ b/samples/yotei02-8.png
Binary files differ
diff --git a/samples/yotei02-t.png b/samples/yotei02-t.png
new file mode 100644
index 0000000..4f74567
--- /dev/null
+++ b/samples/yotei02-t.png
Binary files differ