diff options
author | Romain Beauxis <toots@rastageeks.org> | 2011-10-09 15:40:04 +0200 |
---|---|---|
committer | Romain Beauxis <toots@rastageeks.org> | 2011-10-09 15:40:04 +0200 |
commit | 1949b73c539957a5c5f02e9b3fde5ed9d2401f91 (patch) | |
tree | d3c2e8c2ef3fcca7a60aff85e97e5619b5f7f7e3 |
Import gd4o_1.0~alpha5.orig.tar.gz
[dgit import orig gd4o_1.0~alpha5.orig.tar.gz]
-rw-r--r-- | BUGS | 10 | ||||
-rw-r--r-- | CHANGES | 105 | ||||
-rw-r--r-- | INSTALL | 66 | ||||
-rw-r--r-- | LICENSE | 510 | ||||
-rw-r--r-- | META | 5 | ||||
-rw-r--r-- | Makefile | 107 | ||||
-rw-r--r-- | Makefile.orig | 63 | ||||
-rw-r--r-- | README | 73 | ||||
-rw-r--r-- | README.ocamlgd | 30 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | doc/api-xref.html | 2658 | ||||
-rw-r--r-- | doc/api-xref.xml | 1626 | ||||
-rw-r--r-- | doc/manual.txt | 127 | ||||
-rw-r--r-- | font_list.txt | 7 | ||||
-rw-r--r-- | gd.ml | 650 | ||||
-rw-r--r-- | gd.mli | 232 | ||||
-rw-r--r-- | gdstubs.c | 1009 | ||||
-rw-r--r-- | gdtest.ml | 581 | ||||
-rw-r--r-- | samples/driver01-8.png | bin | 0 -> 35880 bytes | |||
-rw-r--r-- | samples/driver01-t.png | bin | 0 -> 75851 bytes | |||
-rw-r--r-- | samples/kamokamogawa04-8.png | bin | 0 -> 94536 bytes | |||
-rw-r--r-- | samples/kamokamogawa04-t.png | bin | 0 -> 235122 bytes | |||
-rw-r--r-- | samples/yotei02-8.png | bin | 0 -> 116313 bytes | |||
-rw-r--r-- | samples/yotei02-t.png | bin | 0 -> 285310 bytes |
24 files changed, 7864 insertions, 0 deletions
@@ -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. @@ -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. @@ -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. @@ -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! + + @@ -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 @@ -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 @@ -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> & + <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> & + <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> & + <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 © 2003 by + <a href="mailto:mgushee@havenrock.com"> + Matt Gushee + </a> :: Last modified: + 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> & + <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> & + <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> & + <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 @@ -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) @@ -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 Binary files differnew file mode 100644 index 0000000..d4d834e --- /dev/null +++ b/samples/driver01-8.png diff --git a/samples/driver01-t.png b/samples/driver01-t.png Binary files differnew file mode 100644 index 0000000..c672856 --- /dev/null +++ b/samples/driver01-t.png diff --git a/samples/kamokamogawa04-8.png b/samples/kamokamogawa04-8.png Binary files differnew file mode 100644 index 0000000..b7fe1b2 --- /dev/null +++ b/samples/kamokamogawa04-8.png diff --git a/samples/kamokamogawa04-t.png b/samples/kamokamogawa04-t.png Binary files differnew file mode 100644 index 0000000..d348f20 --- /dev/null +++ b/samples/kamokamogawa04-t.png diff --git a/samples/yotei02-8.png b/samples/yotei02-8.png Binary files differnew file mode 100644 index 0000000..df617da --- /dev/null +++ b/samples/yotei02-8.png diff --git a/samples/yotei02-t.png b/samples/yotei02-t.png Binary files differnew file mode 100644 index 0000000..4f74567 --- /dev/null +++ b/samples/yotei02-t.png |