Code

Removed PHPLot
authorhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Thu, 12 Aug 2010 08:55:53 +0000 (08:55 +0000)
committerhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Thu, 12 Aug 2010 08:55:53 +0000 (08:55 +0000)
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@19380 594d385d-05f5-0310-b6e9-bd551577e9d8

16 files changed:
gosa-core/include/phplot-5.1.2/COPYING [deleted file]
gosa-core/include/phplot-5.1.2/ChangeLog [deleted file]
gosa-core/include/phplot-5.1.2/HorizontalBars.txt [deleted file]
gosa-core/include/phplot-5.1.2/NEWS.txt [deleted file]
gosa-core/include/phplot-5.1.2/README.txt [deleted file]
gosa-core/include/phplot-5.1.2/contrib/README.txt [deleted file]
gosa-core/include/phplot-5.1.2/contrib/color_range.example.php [deleted file]
gosa-core/include/phplot-5.1.2/contrib/color_range.php [deleted file]
gosa-core/include/phplot-5.1.2/contrib/color_range.test1.php [deleted file]
gosa-core/include/phplot-5.1.2/contrib/color_range.test2.php [deleted file]
gosa-core/include/phplot-5.1.2/contrib/prune_labels.example.php [deleted file]
gosa-core/include/phplot-5.1.2/contrib/prune_labels.php [deleted file]
gosa-core/include/phplot-5.1.2/contrib/prune_labels.test.php [deleted file]
gosa-core/include/phplot-5.1.2/phplot.php [deleted file]
gosa-core/include/phplot-5.1.2/phplot_data.php [deleted file]
gosa-core/include/phplot-5.1.2/rgb.inc.php [deleted file]

diff --git a/gosa-core/include/phplot-5.1.2/COPYING b/gosa-core/include/phplot-5.1.2/COPYING
deleted file mode 100644 (file)
index 602bfc9..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-                 GNU LESSER GENERAL PUBLIC LICENSE
-                      Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.
-\f
-  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.
-\f
-                 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.
-\f
-  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.
-\f
-  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.
-\f
-  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.
-\f
-  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.
-\f
-  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.
-\f
-  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
-\f
-           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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/gosa-core/include/phplot-5.1.2/ChangeLog b/gosa-core/include/phplot-5.1.2/ChangeLog
deleted file mode 100644 (file)
index 9d318a2..0000000
+++ /dev/null
@@ -1,1010 +0,0 @@
-This is the Change Log for PHPlot.
-The project home page is http://sourceforge.net/projects/phplot/
------------------------------------------------------------------------------
-
-2010-06-29 (lbayuk)     ===== Released as 5.1.2 =====
-    * phplot.php: Updated version
-    * README.txt: Updated for new release
-    * NEWS.txt: Add text for new release
-
-2010-06-26
-   * Feature request 2885930 "Horizontal Bars":
-     Horizontal bar charts are implemented, as an experimental feature.
-     A new data type 'text-data-yx' was added, which works with
-     'bars' plot type to produce a horizontal bar chart from a data
-     array with X values for each Y value. Changes were made to
-     FindDataLimits, CalcMargins, CalcPlotAreaWorld, CalcBarWidths,
-     and CalcMaxDataLabelSize to handle the new data type. Other
-     changes were made to handle label position defaults and grid
-     defaults. New drawing functions were added for horizontal bars.
-
-   * HorizontalBars.txt: new documentation file for experimental feature.
-   * Makefile: List new documentation file.
-
-2010-06-25
-   * Each plot-type drawing function now checks that it is getting a data
-     type that it knows how to handle. A new internal function unifies the
-     checking and error message. (This is associated with an upcoming,
-     bigger change.)
-
-     Compatibility: If you were using an invalid data type for a plot type
-     whose function did not check, will now get an error.
-     
-   * Removed some dubious code from DrawLines() and DrawSquared() and
-     rewrote comments there. The code initialized lastx[0] and lasty[0],
-     but lasty was mapped using the X (rather than Y) function.  This was
-     obviously wrong, but closer inspection showed that the values were
-     never, used so the code was removed.
-
-2010-06-13
-   * Truecolor.txt: removed
-   * Makefile, README.txt: Removed reference to Truecolor.txt. Full
-     documentation for truecolor images is now in the Reference Manual.
-     
-2010-06-02
-   * Fix bug 3010116 "Bad rendering of title in multi-plot image
-     when using TTF":
-     Make sure the main title is drawn only once. (If drawn multiple
-     times with TrueType font text, the anti-aliasing effects result
-     in poor quality text.)
-
-2010-05-31
-   * Improvements to truecolor support (from feature request 2947679):
-     Truecolor support is now better integrated. The derived class only
-     has the constructor now, and the base class itself provides the alpha
-     color component support through the internal functions SetIndexColor(),
-     SetIndexDarkColor(), and SetRGBColor(). This means alpha channel
-     works with palette images too (in so far as GD supports this).
-
-   * Truecolor.txt: Updated per changes to truecolor support.
-
-   * Image tiling with mode 'scale' in tile_img(), used with image and
-     plot area backgrounds, now uses imagecopyresampled() rather than
-     imagecopyresized(). They are the same with palette images, but the
-     resampled copy gets better results with truecolor images.
-
-2010-05-29
-    * Feature request 3002606 "Add to plot and image border options":
-        Added options 'right', 'top', and 'bottom' to SetPlotBorderType()
-      (existing options are 'left', 'sides', 'none', and 'full'). This
-      now also accepts an array of the above options, giving complete
-      control over which sides to draw.
-        Added option 'solid' to SetImageBorderType() to use the actual
-      color set with SetImageBorderColor(), rather than the darker
-      shade as type 'plain' does (for some reason).
-        New function SetImageBorderWidth() sets the width of the image
-      border. The image border width is now accounted for in margin
-      calculations, although existing plots will not change.
-
-2010-04-04 (lbayuk)     ===== Released as 5.1.1 =====
-    * phplot.php: Updated version
-    * README.txt: Updated for new release
-    * NEWS.txt: Add text for new release
-
-2010-04-01
-    * Remove & from argument in SetDataValues(). The data array is not
-      modified and does not need to be passed by reference. (There is
-      no performance advantage, either.)
-
-2010-03-29
-    * Feature request 2947679 "Support for alpha blending/Truecolor":
-      Implemented truecolor image support with a new class
-      PHPlot_truecolor, extended color specifications to allow
-      specification of an alpha value, and added a new optional parameter
-      to SetDataColors for a default alpha value for all data colors.
-      This feature is *EXPERIMENTAL* (see next item).
-
-    * Truecolor.txt: New file, documentation for the new truecolor capability.
-      (The Truecolor feature is experimental, which means it is subject to
-      change in incompatible ways and the documentation has not yet been
-      incorporated into the PHPlot Reference Manual.)
-
-    * Makefile: Include new documentation file in release.
-
-2010-03-26
-    Fixed bug 2976735 "Improvements and fixes for 'area' plots":
-    Rewrote DrawArea() function which handles 'area' plot.
-        Part 1: This is related to feature request 2947679, Truecolor support
-    with transparency. The area plot function was filling each area from the X
-    axis up to the Y value, resulting in area overlaps. This wasn't a problem
-    with opaque colors, but with transparency, the overlapping areas resulted
-    in changed colors. The rewritten function fills the area between each line
-    instead of from each line down to the X axis. Plots with opaque colors
-    will not change.
-        Part 2: Area plots now work when the X axis is moved up with
-    SetXAxisPosition().
-        Part 3: Fixed FindDataLimits() for area (and stackedbars too) to
-    take absolute values of Y values. The drawing function was doing this,
-    but not FindDataLimits, resulting in incorrect limits if any Y<0.
-        Part 4: The rewritten DrawArea() also handles a new plot type
-    'stackedarea'.  This is an area plot where the Y values are stacked,
-    similar to 'stackedbars'.
-        Note: As part of the changes, it is now an error to try an area plot
-    with an unequal number of Y points for each X.
-
-2010-03-23
-    * Feature request 2973995 "Add y-Data to Stackedbars":
-      Implemented Y Data Labels for Stacked Bar charts (stackedbars).
-      The labels are enabled with SetYDataLabelPos, same as with bar charts.
-      There are two types of labels: above the stack with the total, and
-      within the bars at each segment. 'plotin' turns on the upper ones, and
-      'plotstack' turns both on.
-
-    * Other changes:
-      + Removed unimplemented second argument to SetYDataLabelPos.
-      + Fixed questionable logic in SetYDataLabelPos when given an argument
-        that belongs with SetYTickLabelPos.
-      + Fix comments at top of plot-type Draw functions.
-
-    * Fix for bug 2974639 "Stacked bars plot breaks with X axis != 0":
-      Stacked bar plots with non-zero X axis position no longer break apart
-      into segments with gaps. The bars are drawn up from the X axis, and
-      any segments or partial segments below the X axis are not drawn.
-
-2010-03-22
-    * Change related to feature request 2947679 - Fix 'dot' point shape:
-      Use imagefilledellipse(), not imagefilledarc(), when drawing the 'dot'
-      point shape. The fix was needed for future support of truecolor images
-      with transparency, but filled dots from imagefilledellipse() look
-      better (rounder) with regular images and opaque colors.
-      Credit to mvaldez for identifying the problem and providing the fix.
-
-2010-03-04
-    * Fix for bug 2963757 "point_counts undefined error in 5.1.0":
-      Fixed CheckPointParams so it sets point_counts even when the point shape
-      and point size arrays are already the same size and do not need padding.
-
-2010-01-26
-    * Fix for bug 2938219 "Bars go in wrong direction":
-      Fixed CalcAxisPositions() to be consistent in positioning the X axis.
-      When all Y values are <0 and the Y=0 line is not part of the plot range,
-      PHPlot will now default the X axis to the top of the plot, not the
-      bottom.  This fixes the problem with bars to negative Y values being
-      drawn downward if Y=0 is visible, but upward if Y=0 is not visible.
-      This also affects thinbarline plots.
-      Credit to lauryn1298 for finding the bug.
-
-2009-12-24 (lbayuk)     ===== Released as 5.1.0 =====
-
-2009-12-18
-    * Change for bug 1795971 "Fix default data colors":
-      The default Data Color and Error Bar Color arrays now have 16
-      different colors, no duplicates, and nothing so light that it
-      is invisible.
-      Using '' or False as the argument to SetDataColors, SetErrorBarColors,
-      and SetDataBorderColors now re-initializes the map to the defaults.
-      This was previously undocumented, and in some cases set the map to
-      something different from the default.
-
-2009-12-15
-    * Cleanup: Remove DrawAxisLegend() - empty function marked TODO,
-      not really clear what it was meant to do.
-
-2009-12-14
-    * Fix for bug 2914403 "Pie + X/Y titles: Undefined property error":
-      In DrawGraph(), don't try to draw X or Y titles for pie charts.
-
-    * Feature request 2899921: "allow different format for data and tick
-      labels"; Bug 2906436: "Fixes for X Tick Labels vs X Data Labels",
-      and partial implementation of changes from user 'adoll' regarding
-      tick vs data labels:
-
-      New public functions:
-      + SetXDataLabelType() : Sets formatting for X Data Labels
-      + SetYDataLabelType() : Sets formatting for Y Data Labels (bar charts)
-      + SetXDataLabelAngle() : Sets text angle for X Data Labels
-      + SetYDataLabelAngle() : Sets text angle for Y Data Label (bar charts)
-      The defaults for these are set up to be fully backward compatible
-      with previous releases of PHPlot (except see the next item).
-
-      Re-used function name SetXDataLabelAngle():
-      + This has been deprecated and undocumented since 2003-12-07, and
-        used to just call SetXLabelAngle(). For new behavior, see above.
-
-      Changes to public functions:
-      + SetXDataLabelPos() and SetXTickLabelPos() no longer cancel each
-        other out (set the other control variable to 'none'). Instead,
-        they are both considered before plot drawing.
-
-      Changes to internal functions:
-      + DrawDataLabel() now uses the font, angle, and color arguments as
-        provided, and does not substitute values if they are empty.
-      + SetLabelType() now takes mode='xd' and 'yd' for X Data and Y Data
-        label formatting; 'x' and 'y' are for tick labels only now.
-      + Functions that work on Data labels now call FormatLabels() with the
-        new mode parameter value 'xd' or 'yd, and use the new
-        data_label_angle variables.
-      + New CheckLabels(), used by DrawGraph to process label parameters.
-      + CalcMargins() - Rewritten to handle changes to Tick and Data labels.
-
-      Changes to internal class variables:
-      + New: x_data_label_angle, y_data_label_angle
-      + Do not initialize x_tick_label_pos or x_data_label_pos, so that
-        CheckLabels() can tell if they were set or not and apply defaults.
-      + Initialize y_data_label_pos to 'none', not 'plotleft'.
-      + Add 2 more indexes to label_format[] array: 'xd' and 'yd'.
-
-    * Cleanup:
-      + Delete unused internal class variable: draw_y_data_label_lines
-      + Delete unused function SetDrawYDataLabelLines()
-
-2009-12-07
-    * Fix bug 1795972 "Fix default point shapes":
-      +  Added 10 new point shapes to the existing 10 shapes.
-      +  Changed the default point shape from all 'diamond' to a
-         selection of up to 10 different shapes.
-      +  Fixed bug in the code that tried to set the point shapes
-         and sizes arrays to be the same size. This was not working,
-         resulting in unexpected point sizes.
-      +  Changed default point size to 6 for all shapes. It was trying
-         to be "5, 5, 3" but due to several bugs this was not working.
-      +  Do not adjust shape sizes to even numbers (was done for only two
-         shapes).  Instead, consistently truncate size/2 when needed.
-      NOTE: These may change the look of 'points' and 'linepoints' plots.
-
-    * Changed startup initialization code:
-      +  SetDefaultStyles() was doing some odd things using a variable
-         called "session_set", with comments referring to non-existent
-         session support code. This has been removed. There should be
-         no visible changes from this. PHPlot does not use PHP sessions.
-
-2009-12-04
-    * Fix for bug 2908256, errors in pie charts with bad data array:
-      (From a Drupal contrib module report by thekevinday.)
-      With pie charts only, a data array with no valid Y values resulted
-      in PHP error messages. All other plot types handle this by producing
-      an image without a graph.
-      Fixed DrawPieChart to behave this way too. If there are no valid Y
-      values, or if the sum of all Y values is 0, do not error out, but
-      don't draw a pie chart either.
-      Also, pie charts now ignore non-numeric Y values, like other plot types.
-
-2009-11-20 (lbayuk)
-    * Fix for bug 2900914 "Problem with display of 0 on Y axis":
-      Changed how X and Y values are stepped by tick intervals, to avoid
-      cumulative round-off error. This fixes the problem when Y crosses 0 with
-      a tick step such as 0.1 resulting in a long label for a very small but
-      non-zero number. Fixed DrawXTicks, DrawYTicks, and CalcMaxTickLabelSize.
-      (Originally reported by cncnet)
-
-2009-11-19 (lbayuk)
-    * Improve support for using callbacks to annotate plots:
-      Added new callback 'draw_all', called after all drawing.
-      Supply plot_area[] as argument to some drawing callbacks.
-      Added new method GetDeviceXY() to translate from world coordinates.
-      Allow NULL or '' for $font in DrawText() internal method, meaning to
-          use the generic font. If callbacks want to use DrawText, this
-          avoids them having to reference the internal fonts[] array.
-
-2009-11-01 (lbayuk)
-    * Address bug report 2886365 "Declare all functions and variables in
-      PHP5 style"
-      PHP5 deprecates the use of 'var' to declare a class member variable.
-      All initialized class member variables are now declared 'public'.
-      (It was tempting to make most or all 'protected' or 'private', but
-      that would likely break too much, including the PHPlot Test Suite.)
-
-      Most class member functions which are meant for internal use only are
-      now declared 'protected', so they cannot be called from scripts
-      (except in child classes). (Note PHP5 does not deprecate the use of
-      just 'function' to mean public, so public functions were not changed.)
-      Internal functions are those documented in the manual under Developer's
-      Guide, Internal Functions. If your code breaks because you are using
-      a method which is now protected, please post the details on the help
-      forum.
-
-      Some member variables which were set in the constructor are now
-      initialized with the class instead. (No impact.)
-
-      Removed commented-out, FIXME-noted code for interim labels.
-
-2009-10-12 (lbayuk)
-    * Bug report 2839547, allow SetImageBorderType('none') to reset the image
-      border type.  Also checked for other cases where there is no reset;
-      found one that exists (Set[XY]LabelType) but needs to be documented.
-
-2009-07-09 (lbayuk)
-    * Added a hook $plot->locale_override which can be set to True to prevent
-      PHPlot from loading locale settings from the environment with
-      setlocale(LC_ALL, ''). This is necessary for testing PHPlot on Windows,
-      where you cannot force a locale with an environment variable. It might
-      also be needed for people who want PHPlot's locale to differ from the
-      web server's locale.
-
-2009-06-12 (lbayuk)     ===== Released as 5.0.7 =====
-
-2009-06-11 (lbayuk)
-    * Change PHPlot license to LGPL, per Afan.
-        phplot.php, phplot_data.php - Change license notice.
-        rgb.inc.php - Change top comments and remove bottom marker.
-        COPYING - new file, text of LGPL.
-        LICENSE.* - removed files - old licenses.
-        Makefile - change list of distributed files.
-
-    * Fix for bug 2803900: SetRGBArray('large') does not work. The include
-      file defined a different array name than the main script expected.
-      (This bug seems to have happened over 8 years ago.) Fixed the array
-      names to match. Also removed the ./ prefix from the included filename
-      so it will be found if on the include path but not in the script
-      directory.  Also added error check if the rgb.inc.php include file
-      is needed and not found.
-
-2009-05-25 (lbayuk)
-    * Added new feature to allow partial margin or plot area specification.
-      You can omit, or specify as NULL, any of the 4 arguments to
-      SetMarginsPixels() or SetPlotAreaPixels(), and this means PHPlot
-      should use the automatically calculated margin on that side.
-      Credit to adoll for this feature.
-
-2009-05-17 (lbayuk)
-    * Fix for bug 2791502 "Error plots treat missing Y values as 0":
-      Plots with data type data-data-error now support missing Y values,
-      instead of treating them as 0. This works with lines, points,
-      and linepoints plot types, and also honors SetDrawBrokenLines.
-
-
-    * Fix for bug 2792860 "Wrong DataLabelLines with missing Y":
-      Do not draw X Data Label Lines at points with missing Y values.
-
-
-    * Fix for bug 2786350 "Missing Y data results in bad auto-range":
-      Rewrote FindDataLimits to ignore missing Y values, rather than
-      treating them as if 0, for calculating range.
-      Bug report and analysis by mrten.
-
-    * Fix for bug 2786354 "Incorrect auto-range for data-data-error":
-      For data-data-error data type, apply the positive and negative error
-      amounts for each Y point to that point only, rather than applying the
-      largest errors to the overall minimum and maximum Y value for the row.
-
-    Note: The two fixes above can change existing plots which rely on
-      automatic Y range calculation. The first fix affects plots with
-      missing Y values and min(Y)>0. The second fix can affect plots using
-      data-data-error data type and different error values for different
-      points. In both cases the new Y range can be smaller than before.
-
-2009-01-20 (lbayuk)     ===== Released as 5.0.6 =====
-
-2009-01-18 (lbayuk)
-    * Fix for bug 1891636 "Misaligned TTF X Labels":
-         PHPlot was using the actual bounding box of each line of text
-      to allocate space and set the text positioning, but was ignoring the
-      fact that the text baseline is not the same as the bottom of the
-      bounding box. This resulted in uneven alignment of the X labels if
-      they had different heights (for example, month names Jul and Aug).
-
-      PHPlot now calculates the size of text for allocation (SizeText) using
-      the descenders on the last line, and calculates the size for drawing
-      (DrawText) only to the baseline. PHPlot also now uses a fixed line
-      spacing for each line of text in a font, rather than the actual text
-      height. This allows separately drawn multi-line labels to align.
-
-    * Changes to line spacing when using multi-line labels:
-         PHPlot was using the class variable line_spacing to mean the
-      number of pixels between lines of multi-line labels. This made the
-      spacing too small for larger fonts, and it was not possible to adjust
-      line spacing for different types of text.
-
-         PHPlot now interprets line_spacing as the number of pixels only
-      for GD text, and as a scale factor for the font's built-in line
-      spacing for TrueType text. In addition, a new optional argument is
-      added to SetFont, SetFontGD, and SetFontTTF to set a line spacing
-      specific to that type of text.
-
-    * Changes had to be made to the legend drawing code to accommodate the
-      changes to font handling.
-
-      Note: The line spacing change results in slightly looser spacing on
-      multi-line TrueType text labels, and slightly taller legends, compared
-      to version 5.0.5.
-
-2008-09-21 (lbayuk)
-    * Interim fix for bug 1932571 "Data-Data Plot fails with same X values".
-      PHPlot will no longer hang when the range of X values is 0 (that is, when
-      x_min == x_max). It will arbitrarily set an X range of 1, so the
-      calculated tick step is not 0. This is a temporary fix. Work on a smarter
-      X and Y range calculation is in progress, which will handle edge cases
-      like this better, but it isn't ready and this bug has been open too long.
-      Credit to andyl for finding the bug.
-
-    * Fix font path: Use DIRECTORY_SEPARATOR constant not '/'.
-
-    Extended the label formatting capabilities, adding 'printf' and 'custom'
-    types, added a prefix and suffix for 'data' type, and allow format controls
-    to be included in SetXLabelType and SetYLabelType.
-
-    External changes:
-    * Added 'printf' label type. The caller specifies the print format as the
-      2nd argument to SetXLabelType or SetYLabelType (default '%e').
-             $plot->SetXLabelType('printf', '%5.2f');
-
-    * Added 'custom' label type. The caller supplies a callback (typically a
-      function name) and optional pass-through argument as the 2nd and 3rd
-      arguments to Set[XY]LabelType.  The function is called as $f($value, $arg)
-      to return the formatted $value.
-             $plot->SetXLabelType('custom', 'myfunction', $arg_value);
-
-    * In addition to Set[XY]TimeFormat, the format string for type 'time' can
-      now be set as the 2nd argument to Set[XY]LabelType.
-             $plot->SetXLabelType('time', '%H:%M');
-
-    * In addition to SetPrecision[XY], the precision for type 'data' can now be
-      set as the 2nd argument to Set[XY]LabelType. A 3rd and 4th argument
-      can supply a prefix and suffix for 'data' formatting. (All optional)
-             $plot->SetXLabelType('data', 2, '$', 'US');
-
-    Internal changes:
-    * Class variables x_precision, y_precision, x_label_type, y_label_type,
-      x_time_format, and y_time_format have been removed.
-
-    * New class array variable label_format[], with elements 'x' and 'y' which
-      are arrays for label formatting. Elements in the sub-arrays are not
-      initialized until needed.
-
-    * New function SetLabelType, which implements Set[XY]LabelType now.
-
-    * FormatLabel() was rewritten to support the new label formatting.
-
-    Compatibility:
-    * Any code that directly references class variables related to label
-      formatting will break, except for data_units_text. Use the documented
-      function methods instead.  Setting data_units_text as a suffix is
-      deprecated but still works.
-
-    * The 'data' type precision for 'Y' is still used for pie chart labels.
-
-2008-07-12 (lbayuk)
-    Multiple comment spelling error fixes. No functional changes.
-
-2008-07-06 (lbayuk)
-    Changes to allow mixing GD fixed-font text and TrueType Font (TTF) text
-    on the same plot.
-    (This change came from work done trying to fix TTF text positioning,
-    where it looks like additional information needs to be stored for TrueType
-    fonts. The old font data structure was awkward to extend, and allowing
-    mixed GD/TTF text was on the to-do list anyway.)
-
-    External changes:
-    * SetFontGD(), SetFontTTF(): New functions to set a font, with type.
-    * SetFont(): Now calls SetFontGD or SetFontTTF depending on $use_ttf.
-    These changes should be fully compatible with existing programs.
-
-    Internal changes:
-    * Updated comments explaining SetUseTTF() now sets the default type
-      (not the only type) of text used.
-    * Put all the font data into a class array. (Replaces $this->generic_font
-      with $this->fonts['generic'], etc.)
-    * ProcessTextGD() and ProcessTextTTF() now take the font array as one
-      argument, rather than separate arguments for font path and size.
-
-2008-01-13 (lbayuk)     ===== Released as 5.0.5 =====
-    * phplot.php: Updated version
-    * README.txt: Updated for new release
-    * NEWS.txt: Add text for new release
-    * Makefile: Remove 'Callbacks' from release target, as this material is
-      now in the reference manual.
-
-2008-01-07 (lbayuk)
-    Copyright updated to 2008 and PHP4 no longer listed as supported.
-
-    Major rewrite of the margin calculation functions to address multiple
-    problems.  Fixes for bugs 1856207 "Margin error with 'xaxis'/'yaxis'
-    position, 1843012 "Make margins, drawing consistent", and 945439
-    "x_tick_label_height not set correctly".
-
-    Note: These changes are inter-dependent and cannot be split up.
-
-    * Defer all calculations to DrawGraph time, to eliminate order dependencies.
-      These functions now just store their arguments in the object, and all
-      calculations happen later:
-    + SetXAxisPosition, SetYAxisPosition
-    + SetMarginsPixels
-    + SetPlotAreaPixels (Stores margins, not area, now.)
-    + SetPlotAreaWorld
-    + SetXTickIncrement, SetYTickIncrement
-
-    * A new callback 'debug_scale' was added to trace the margin and scale
-      calculations.
-
-    * CalcMargins was rewritten. Actual sizes of tick and data labels are now
-      used, rather than guesses like "use size of biggest Y value". A minimum
-      value (3 x safe_margin, or 15 pixels) applies to each margin.
-
-    * FindDataLimits no longer needs to find the longest data label, since
-      CalcMargins now does that more precisely.
-
-    * DrawXTitle and DrawYTitle now use position offsets calculated by
-      CalcMargins. Note: These titles are now offset from the plot area,
-      not the image area. The titles will move if you had set the plot area
-      or margins.
-
-    * DrawYTick, DrawXTick rewritten to use pre-calculated offsets, and common
-      code moved to new CalcTicks().
-
-    * DrawXDataLabel: Use pre-calculated offsets for text.
-
-    * DrawGraph: Rewrote top section (before drawing anything) to do the
-      calculations in the proper order, unconditionally.
-
-    * Class variables removed:
-      x_label_inc, y_label_inc, _x_label_cnt : These were never used.
-      title_height, x_title_height, y_title_width : Now internal to CalcMargins.
-      data_limits_done : No more need to remember if FindDataLimits called.
-
-    * New class variables added:
-      plot_margins_set : Keeps track of user-set plot area or automatic.
-      x_label_top_offset, x_label_bot_offset, x_offset_axis_offset,
-          y_label_left_offset, y_label_right_offset, y_label_axis_offset,
-          x_title_top_offset, x_title_bot_offset,
-          y_title_left_offset, y_title_left_offset : Label offsets
-      
-    * New internal functions:
-      CalcPlotAreaPixels : Deferred calculations taken out of SetPlotAreaPixels
-        and SetMarginsPixels.
-      CalcPlotAreaWorld : Deferred calculations taken out of SetPlotAreaWorld.
-      CalcAxisPositions : Calculate axis positions, moved from CalcTranslation.
-      CalcTicks : Calculate X and Y tick interval. This still uses the
-        same simple method (basically range/10), but now we could drop in a new
-        algorithm much more easily. This is now also used by CalcMargins.
-        Code taken out of DrawXTicks and DrawYTicks.
-      CalcMaxTickLabelSize : So CalcMargins can use the exact tick label sizes.
-      CalcMaxDataLabelSize : So CalcMargins can use the exact data label sizes.
-      DrawXTick : Code split out from DrawXTicks for symmetry with DrawYTick.
-
-
-2007-12-13 (lbayuk)
-    * Changed ProcessTextTTF() so SizeText() will return integers. It rounds
-      the calculated values up, so the bounding box really contains the text.
-      This also prevents unneeded float calculations in derived values.
-
-2007-12-09 (lbayuk)
-    Major rewrite of the text drawing functions to address multiple problems.
-    Note: These changes are inter-dependent and cannot be split up.
-
-    * Fixed bug 1813070 "Bad position for multi-line TrueType text":
-      TTF text is now drawn line-by-line, not as a block, for proper
-      alignment and positioning.
-
-    * Fixed bug 1813071 "Wrong title height for multi-line TTF text":
-      Corrected miscalculation of overall height of multi-line TTF titles.
-      This bug resulted in over-sized margins.
-      The height is now computed line-by-line, including the inter-line spacing.
-
-    * Fixed bug 1813474 "DrawText alignment arguments wrong":
-      Corrected meaning of 'top' vs 'bottom' alignment. PHPlot now follows
-      the usual conventions: 'top' alignment means top of text to reference.
-      DrawText default for vertical alignment is still 'bottom', but the
-      meaning was corrected.  All callers of DrawText were fixed.
-
-    * Fixed bug 1816844 "Fix order dependency for setting titles":
-      Defer processing titles strings until DrawGraph(), so there is no
-      more order dependency (no need to set font before setting title strings).
-
-    * Fixed bug 1819668 "Horiz. align multi-line text: GD vs TTF":
-      The new text routines draw TTF text line-by-line and correctly do
-      right-, center-, and left- alignment of each line within a text block.
-
-    * Fixed bug 1826513 "FIXME in DrawLegend: Max label length":
-      Use actual width of widest legend line to calculate legend box size.
-
-    * Partial fix for bug 945439 "x_tick_label_height not set correctly":
-      In FindDataLimits(), save the longest data label, not just its length,
-      and use the actual rendered size of that string in CalcMargins() for
-      the margin calculations.
-      Also take into account which of the tick or data labels are visible.
-      This is not a complete fix, but is a significant improvement.
-
-    The following changes were made related to the above fixes:
-
-    + Replaced internal function TTFBBoxSize(), which didn't work right, with
-      SizeText(). It returns the orthogonal bounding box of a block of text,
-      and works with both GD and TTF text.
-
-    + DrawText() and SizeText() call a single function ProcessText(), which is
-      the only place GD text and TTF text are distinguished. (So eventually
-      we will be able to mix GD and TTF text on a plot.)
-
-    + New internal functions ProcessTextGD() and ProcessTextTTF() draw (or size)
-      GD and TTF text respectively. These are only called by ProcessText().
-      These are re-implementations which properly position and align text.
-
-    + Removed class variables title_angle, x_title_angle, and y_title_angle. The
-      titles only work at their fixed angles anyway (0, 0, and 90 respectively).
-
-    + Line spacing set with SetLineSpacing() now affects TTF text as well as
-      GD text. Previously, it only affected GD text. The default line spacing
-      happens to be usable for TTF text.
-
-    + Added new callback hook 'debug_textbox' for developing, testing, and
-      documenting. It provides access to the text area bounding box.
-
-    + Removed unneeded class variables x_tick_label_height, y_tick_label_width,
-      x_tot_margin, y_tot_margin.
-
-2007-11-25
-    * Improve error handling:
-      Internal functions PrintError() and DrawError() are now the same. Both
-      will draw the error message into the image and output it, and then
-      trigger a user-level error. If no error handler has been set, it will
-      exit, as before. But now the error message should also get logged, or
-      written to the standard error stream, depending on the SAPI in use.
-      You can now establish an error handler to catch most PHPlot errors and
-      do some cleanup before exit.
-
-      This fix also covers bug #1823774 "Default Font Path and Error Message
-      Output".
-
-      Fixed the return value of most PHPlot functions, to return False on
-      error, else True. Since uncaught errors are fatal anyway, this only
-      affects code with an error handler that returns, which is not
-      recommended and unsupported at this time. These changes are for
-      possible future error handling options.
-
-2007-11-22
-    * Fix bug 1836528 "Insufficient checking of parameter values":
-      Rewrote CheckOption to correctly validate option choices.
-      (It previously accepted substrings and other incorrect values.)
-      PHPlot methods that use CheckOption now must be called with valid option
-      values. Empty strings are also no longer accepted.
-
-2007-11-17 (lbayuk)
-    * Change to callbacks to support extra arguments.
-      The PHPlot class can now pass extra arguments to a callback function.
-      Callback functions now take the following form:
-          my_callback($img, $passthru_arg, ...)
-      Where '...' is zero or more additional arguments supplied by PHPlot to
-      the callback. Each implemented callback reason will define any
-      additional arguments it uses. The existing defined callbacks have not
-      changed and do not currently pass any extra arguments.
-
-2007-11-10 (lbayuk)
-    * Fix bug 1827263 "Spoiled up pie-chart if $val is close to zero":
-      Skip pie slices which would result in an integer angle of zero
-      degrees, because the GD arc filling function will draw a complete
-      circle for that case.
-      Credit to Viacheslav <webdeveloper.ua at gmail.com> for finding this.
-
-    * Removed 8 of the functions (class methods) marked 'deprecated'.  Only
-      deprecated functions which seem to have been for internal use have
-      been removed. Even old scripts shouldn't be using them, and they are
-      becoming a problem to maintain.
-      Removed: SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights()
-      CalcYWidths() DrawLabels() InitImage() DrawDashedLine().
-
-2007-10-20 (lbayuk)     ===== Released as 5.0.4 =====
-    * phplot.php: Updated copyright, version, and authors comments at top.
-    * README.txt: Updated for new release
-    * NEWS.txt: Add text for new release
-
-2007-10-18 (lbayuk)
-    * Add callbacks - experimental feature:
-      New functions SetCallback, GetCallback, RemoveCallback.
-      New internal function DoCallback.
-      Added callback hooks to DrawGraph.
-
-      Re-arranged code in DrawGraph to bring pie chart drawing into the main
-      switch on plot type, rather than a special case in its own block. This
-      makes it easier to follow and easier to add callback hooks.
-
-    * Callbacks: New file, documentation for the new callbacks feature.
-      (This won't be in the manual while it is an experimental feature.)
-
-2007-10-15 (lbayuk)
-    * Fix for bug 1813021: Miss-positioned right-justified vertical GD text.
-      Fixed DrawText() to correctly position 90 degree right-justified text
-      drawn in a fixed GD font. This could be seen with 90 degree Y tick
-      labels. (Found by accident while working on TrueType text problems.)
-      Also some code cleanup in DrawText: use elseif where appropriate.
-
-2007-10-09 (lbayuk)
-    * Code cleanup: Simplify SetIndexColor() and SetIndexDarkColor().
-      There is no need to first try ImageColorExact, then ImageColorResolve
-      if that fails. ImageColorResolve does all that for us.
-
-      Code cleanup: Rewrite SetRGBColor(). It now detects if an unrecognized
-      color name or color value form is used, and draws an error message.
-      Before this it would get a PHP index error and "headers already sent"
-      condition.
-
-    * Code cleanup: Remove duplicated code for loading image files.
-      Added new class-private function GetImage() which loads an image based
-      on the image type, and also returns the image size. This replaces
-      duplicated code in tile_img() and SetInputFile().
-      Also fixed comment at top of SetImageFile which said it was deprecated.
-      It isn't - it is used by the constructor. Moved the function out of the
-      'deprecated' area up to below where it is used.
-
-    * Code cleanup: PHPlot should not define or affect anything outside its
-      own class.
-      - Removed the check for __FUNCTION__ (PHP 4.3 and up). This is obsolete.
-      - Do not set error_reporting to E_ALL. Although it is recommended that
-      scripts do this, it is not the place of loaded classes to do it.
-      - Remove unused global constant TOTY.
-      - Removed constants MAXY and MINY. Global constants like this are bad.
-      These were used as magic index values into data[] to hold min and max Y
-      values for the row. Instead, put them in separate arrays which are
-      named data_miny[] and data_maxy[]. (This seems to be only used by the
-      data line drawing function.)
-
-      Comment cleanup: Remove one commented-out partial function DrawPlotLabel,
-      and fix another commented-out code fragment in DrawYErrorBar. Both of
-      these had unmatched braces in them which caused a balance-braces check
-      to fail.
-
-    * Code cleanup, array padding: Get rid of functions outside the class
-      and remove the interim fix for PHP 5 (which changed the behavior of
-      array_merge).  Rewrote external function array_pad_array() as a new
-      class function pad_array().  It does not need access to the class,
-      but I don't think PHPlot should add to the global namespace more
-      than necessary.  The third argument (array to use for padding) was
-      never used, so it was removed. It always pads the array with itself.
-      It now only works on 'usual integer indexed' arrays (0-based
-      sequential integer index). The was previously required but
-      undocumented for some of the arrays (like line_widths); now it is
-      required for all style arrays and will be documented. Now we can pad
-      the array to the required length, not just N times its previous
-      length, and we don't need array_merge.  Deleted external function
-      array_merge_php4() as it is no longer used.
-
-      Deleted PHP end marker ?>. You don't need this and it can cause
-      problems with extra whitespace in your output.
-
-2007-09-24 (lbayuk)
-    * Code cleanup: Fix ternary operator misuse.  This doesn't change
-      behavior, but it was annoying me so I fixed it.
-      Replaced all cases of code like this: $a = ($a > $b) ? $b : $a
-      With just: if ($a > $b) $a = $b
-
-    * Fix Makefile 'release' target to set owner/group when creating
-      the tar file. This avoids having to run it as root, but it needs
-      GNU tar to work.
-
-2007-09-08 (lbayuk)
-    * Fix for bug 1790441: Removed the PHPlot quasi-destructor function and
-      the register_shutdown_function() call which arranged for it to be used.
-      This was preventing release of memory when a PHPlot object was unset,
-      because the registered shutdown function held a reference to it.
-      So rather than improving memory use, it had the opposite effect.
-        Note: It is no longer necessary or recommended to use reference
-        assignment ($plot =& new PHPlot) for PHPlot object creation.
-      Thanks to annajilly for the thorough analysis, bug report, and fix.
-
-2007-09-05 (lbayuk)
-    * Rewrote FormatLabel() to ignore blank label values. Adapted from a
-      patch and feature request submitted by Gerhard Reithofer (exgerhardr).
-      Blank labels used to produce an error if the LabelType was set to
-      'time', and zero if set to 'data'. Now they are just ignored. This
-      provides a simple way to have labels only at selected intervals when
-      using time or data formats. For example, you can have a date/time
-      label at every 10th data point by setting the labels for the other 9
-      to be empty strings. Also: Removed $which_pos values 'plotx' and
-      'ploty'.  These were unused by PHPlot and this is an internal-only
-      function so there is no compatibility issue. Removed error checking on
-      $which_pos for the same reason; the error message used an undefined
-      variable anyway so it wouldn't have worked.
-
-2007-08-26 (lbayuk)
-    * Allow SetLegendStyle colorbox_align argument to be 'none', to suppress
-      the colorboxes in the legend.
-
-      Fix comment on $legend_text_align: empty means right, not left.
-
-      Rewrote DrawLegend layout code to make it easier to understand. The
-      result should be within 1 or 2 pixels of the previous size and position.
-
-    * Fixes for bug 1779115: SetLegendWorld() fails on undefined vars
-      Store the given coordinates and remember that they need to be converted
-      from world to pixel coordinates, but defer trying to actually convert
-      them until it is time to draw the legend. This way, there are no
-      problems with the scale having to being set up first (which is nearly
-      impossible to do).  Made the following changes:
-
-        Changed legend class variables to be uninitialized, and unset (rather
-        than empty string) means use the defaults. Added a new variable:
-        $legend_xy_world. If it is set, (legend_x_pos, legend_y_pos) need to
-        be converted to pixel coords. If it is unset, they are already pixel
-        coords (or undefined, meaning defaults).
-
-        Changed usage of internal function DrawLegend(): removed all arguments.
-        X and Y were always the class variables anyway, and now it needs to
-        also use the new flag to tell it if X and Y are world or pixel coords.
-        The third argument was unused.
-
-        Removed third, unused, default NULL argument from SetLegendPixels and
-        SetLegendWorld.
-        Changes to DrawLegend to convert x, y coords to pixel coordinates
-        if they came from SetLegendWorld. Also account for new usage of
-        the class variables: Test for unset to mean use default.
-
-2007-08-04 (lbayuk)
-    * New feature: control legend text and color box alignment.
-      Adds a new function SetLegendStyle to adjust the alignment of the
-      text and the color boxes inside the legend.
-      Based on part of bug 1208054, contributed by David Hernández Sanz.
-
-2006-12-02 (lbayuk)
-    * Fixes for bug 1605555: Y Data Labels use wrong font and not formatted.
-      Use y_label_font (not x_label_font) for Y Data Labels.
-      Use the formatted value for the label, not the original text.
-      (This applies to bar charts only, with the new Y data labels.)
-
-    * One fix for bug 1208054: Localization of number format.
-      If number formatting is enabled with 'data' format type, PHPlot previously
-      used dot for decimal point and comma for thousands separator, and there
-      was no way to change it.
-      
-      This fix adds a new function:
-               SetNumberFormat($decimal_point, $thousands_separator)
-      to set the separators.  In addition, if that function is not used,
-      PHPlot will now try to use locale-dependent separators. If locale
-      information is not available, it will fall back to the old defaults
-      of dot and comma.
-
-      Note: This change may have some negative effects. 1) If your locale is
-      "C" or "Posix", you might not get a thousands separator now by default.
-      You should be using a more specific locale. 2) If your PHP script is
-      forcing a specific locale with setlocale(), PHPlot will probably undo
-      that because it uses setlocale(LC_ALL, '') to import locale information
-      from the environment.  We have to do that, or a locale set through
-      the environment is ignored. But it will override a manually set locale.
-
-    * Fix for bug 937944: X/Y Tick Counts
-      PHPlot could draw one too few Y tick marks, and one too many X tick marks.
-
-      Changed the code to stop drawing X (Y) tick marks when the current X (Y)
-      value exceeds the maximum X (Y) value plus a small fudge factor. The fudge
-      factor accounts for cumulative error when repeatedly adding a delta to
-      the X (Y) value.
-
-      Notes: The bug report was writing about Y tick counts only, but X tick
-      counts can also be wrong. The proposed fix in the bug report does not
-      work in all cases.
-
-      This fix changes the appearance of many plots which were missing the
-      top-most Y tick mark. The extra X-tick mark problem is less common.
-
-===== Released as 5.0rc3 =====
-
-2006-11-13 (lbayuk)
-    * Fix for bug 1437912: x-axis label misalignment [bar charts]
-      The calculations were redone from scratch.
-      New control variable 'bar_extra_space', which works in addition to
-      'group_frac_width' to control how much extra space is around the bars.
-      Made bar widths match for 'stackedbars' and 1-bar-per-group 'bars'.
-
-      NOTE: This changes the appearance of charts. bars in 'stackedbars'
-      will now be thinner, and bars in 'bars' graphs will be thicker. I
-      saw no reason for them being different before.
-
-      This fix required fixing the positioning on the new bar data labels,
-      which was off before.  The bar data labels will now be centered.
-      Additional fixes to bar chart data labels:
-         For negative values, the label will center under the bar.
-         Fixed X-adjustment to account for shading.
-         Fixed to not suppress the data label if the value is 0.
-
-
-2006-11-10 (lbayuk)
-    * Fix for bug 1594457: DrawError text wrap and background fix
-      Do error image white background correctly, and word-wrap the text.
-
-    * Fix for bug 1594458: Suppress lines or points in 'linepoints' 
-      Don't draw X data labels twice for 'linepoints'.
-      Allow SetPointShapes value 'none' to suppress points, and allow
-      SetLineStyles value 'none' to suppress lines. This allows a 'linepoints'
-      graph to mix lines only, points only, and both on the same graph.
-
-
-2006-11-09 (lbayuk)
-    * Fixes for bug 1446523:
-      + Wrong variable name in deprecated SetAxisFontSize()
-      + Fails to properly handle error if SetDataValues() was never
-        called, or not called with a data array.
-
-    * Fix for bug 1117122: Pie Chart ignores SetPlotAreaPixels
-      Don't let DrawGraph recalculate the plot area for pie charts if the
-      user already set it with SetPlotAreaPixels.
-
-      NOTE: This fix may slightly change the appearance of some pie charts,
-      whether or not they use SetPlotAreaPixels.
-
-    * Fix for bug 1103992: Wrong max Y calculated for stackedbars
-      Changes FindDataLimits to calculate max Y correctly. It was counting
-      the first Y value in each record twice, which is always wrong but
-      only affected stackedbars because the Y values are summed.
-
-    * Fix for bug 1096199: Wrong error bar colors in DrawDotsError.
-      Rewrites DrawDotsError to make it work like DrawLinesError to
-      correctly increment the record and color indexes.
-      Also fixes uninitialized x_now_pixels.
-
-    * Fix for bug 1096197: No borders on unshaded Draw[Stacked]Bars
-      Unshaded Bars and StackedBars covered the border with the rectangle.
-      The fix is to draw the rectangle, then the border.
-
-      NOTE: This fix changes chart appearance. Bars and Stacked Bars
-      will now get a black border around each bar by default, if you
-      turn off the 3D-shading. If you want borderless, unshaded bars
-      you need to use SetDataBorderColors to set the data border colors
-      to be the same as the data colors.
-
-    * Fix for bug 1333164: Negative data values, if string variables, result
-      in unfilled bars. The problem was a string-to-string compare of a
-      negative number with the empty string x_axis_position. Fixed by
-      initializing x_axis_y_pixels to 0 if SetXAxisPosition was not used.
-
-
-2005-04-17 (afan)
-    * Fix for bug [ 1161072 ] SetInputFile warning, background overwrite
-
-    * Bug 1182672 fixed
-
-2005-04-15 (afan)
-    * fix for bug: [ 1182666 ] Y Auto-scale rounds in wrong direction
-
-    * Fix for bugs 1144644 TrueType font path problems and 1106328 TTF
-      path/filename inconsistency
-
-    * Fix Bug: [ 1117120 ] X Title sizing uses Y Title font height
-
-2005-04-13 (afan)
-    * Error in SetLineStyles() - does not accept an array argument
-
-
-2005-03-29 (afan)
-    * Small typo fixed in SetYDataLabelPos
-
-    * Update SetDataLabelPos: For past compatibility we accept plotleft,
-      ...but pass it to SetTickLabelPos
-
-2005-03-26 (afan)
-    * Change to line 3802: data lables now work with multiple bars with *$idx
-
-2005-03-25 (afan)
-    * Added Function DrawDataLabels to put data labels in world coords,
-      added call from DrawBars and modified SetYDataLabelPos to flag
-      whether or not to call DrawDataLabels.
-
-2005-01-20 (migueldb)
-    * Many bugfixes reported and solved by L. J. Bayuk. Thanks!
-      + fixed bug #1096190
-      + FindDataLimits(): fixed bug #1096192
-      + CalcTranslation(): fixed bug #1101317
-      + DrawImageBorder(): fixed bug 1096200
-      + DrawXDataLabel(): fixed bug 1099879
-      + DrawDots(): fixed bug #1096194
-
-===== Released as 5.0rc2 =====
-
-2004-10-24 (migueldb)
-    * array_merge_php4(): added to cope with the bug introduced by
-        the change in array_merge() from PHP4 to PHP5 (I haven't verified this)
-    * Fixed some divisions by zero, thanks to an old bug report.
-
-2004-09-09 (migueldb)
-    * SetPointSize(): deprecated
-    * SetPointSizes(): added as replacement for SetPointSize().
-      Now able to set point sizes on a per line basis.
-    * SetPointShape(): deprecated.
-    * SetPointShapes(): added as replacement for SetPointShape().
-      Now able to set point shape on a per line basis.
-    * DrawDot(): now needs record number to decide which dot shape and
-      size to draw.
-    * CalcMargins(): dirty fix for x data label placing.
-    * tile_img(): fixed tile placement.
-
-2004-06-14 (migueldb)
-    * SetXTickLabelPos() and others: more on the bug reported by Jo Demol.
-    * Fixed bug reported by Jo Demol.
-
-2004-05-11 (migueldb)
-    * SetBgImage(): added.
-    * SetPlotAreaBgImage(): added.
-    * SetInputFile(): deprecated.
-    * DrawBackground(): now accepts images as backgrounds.
-    * DrawPlotAreaBackground(): now accepts images as backgrounds.
-    * tile_img(): internal method added.
-
-..........
-Editor's Note: For older changes to PHPlot, please see the CVS logs.
diff --git a/gosa-core/include/phplot-5.1.2/HorizontalBars.txt b/gosa-core/include/phplot-5.1.2/HorizontalBars.txt
deleted file mode 100644 (file)
index 9c2fadb..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-phplot/HorizontalBars - Documentation for an experimental new plot type
-Last updated for PHPlot-5.1.2 on 2010-06-26
-The project home page is http://sourceforge.net/projects/phplot/
------------------------------------------------------------------------------
-Overview:
-
-This file documents a new plot type, Horizontal Bars. This was added to
-PHPlot in version 5.1.2 as an experimental feature.
-
-    NOTICE:
-
-    This new plot type is experimental. This means anything about this
-    may change in future releases, in ways that might be incompatible
-    with the current implementation, or the new plot type might even
-    be removed completely. The new plot type is not yet documented in
-    the PHPlot Reference Manual. This text file is the only documentation.
-
-Feedback on this feature is welcome. Please use the "help & discussion"
-forum at http://sourceforge.net/projects/phplot/
-
------------------------------------------------------------------------------
-Usage:
-
-In a horizontal bar chart, the X axis and Y axis are oriented the same as
-in other PHPlot plot types: X axis is horizontal, increasing towards the
-right, and Y axis is vertical, increasing towards the top.
-
-    Y
-    ^
-    |
-    |==============
-    |
-    |=====
-    |
-    |=========
-    |
-    +---------------------> X
-
-To make a horizontal bar chart, use the same plot type as vertical bar
-charts ('bars'), but use the new data type 'text-data-yx'. The new data
-type indicates your data array has a different representation, mapping Y
-values to X values (instead of X values to Y values).
-
-For a normal (vertical) bar chart, the data array has type 'text-data' and
-looks like this:
-  $data = array(  array('Label1', Y11, Y12, ...),
-                  array('Label2', Y21, Y22, ...),
-                  ...);
-Each entry (row) in the data array represents one group of bars. Each group
-has a label and one or more Y values. The X values are implicit: the first
-row has the first X value, the second row has the second X value, etc.
-
-For the new horizontal bar charts, the data array has the new type
-'text-data-yx' and looks like this:
-  $data = array(  array('Label1', X11, X12, ...),
-                  array('Label2', X21, X22, ...),
-                  ...);
-Each entry (row) in the data array represents one group of bars. Each group
-has a label and one or more X values. The Y values are implicit: the first
-row has the first Y value, the second row has the second Y value, etc.
-
-As you can see, a vertical bar chart can be changed to a horizontal bar
-chart simply by changing the data type passed to SetDataType(). The data
-array itself does not change. Other issues with horizontal bar charts are
-discussed below.
-
-This complete script makes a very simple horizontal bar chart:
-    <?php
-    require 'phplot.php';
-    $p = new PHPlot(800, 800);
-    $p->SetDataValues(array(array('A', 10, 25), array('B', 30, 5)));
-    $p->SetDataType('text-data-yx');
-    $p->SetPlotType('bars');
-    $p->DrawGraph();
-
-Note that the bars in a horizontal bar chart are ordered from bottom to top
-(that is, increasing Y values). In the example above, the "A" label bar
-group is drawn below the "B" label bar group. If you need bars ordered from
-top to bottom, you will have to change your data array accordingly.
-
------------------------------------------------------------------------------
-Ticks and Labels:
-
-Since the X axis and Y axis do not change positions for horizontal bar
-charts, the label and tick controls still refer to the X and Y axis.
-However, the independent values are now Y, and the dependent values are
-now X. Also, the label strings in your data array are plotted along the Y
-axis for horizontal bar charts, rather than along the X axis for regular
-bar charts.
-
-To control the data labels positions, use SetYDataLabelPos(). New option
-values have been added to this function, which was previously used only to
-position bar chart value labels with the options 'plotin', 'plotstack', or
-'none'. With horizontal bar charts, SetYDataLabelPos() positions the
-regular data labels that go along the Y axis. The new option values are
-'plotleft', 'plotright', or 'both'.
-  'plotleft' : Draw data labels along the left side of the plot area.
-  'plotright' : Draw data labels along the right side of the plot area.
-  'both' : Draw data labels along both left and right sides.
-  'none' : Do not draw data labels.
-
-For bar charts, it makes no sense to have ticks or tick labels along the
-independent axis. This is the Y axis for horizontal bar charts.  Therefore,
-you should use SetYTickPos('none') to turn off the tick marks on the Y
-axis. You do not normally need to use SetYTickLabelPos('none') to turn off
-the tick labels along the Y axis, since PHPlot will do this automatically
-if your data array has labels.
-
-To control the presentation of the data labels with horizontal bar charts,
-use the correct functions that refer to the Y data labels, not X data
-labels as with vertical bar charts.
-
-   SetYDataLabelAngle() or SetYLabelAngle()
-       Set angle of data label text. Default is 0 degrees.
-
-   SetYDataLabelType() or SetYLabelType()
-       Select the type of formatting for the data labels.
-
-   SetFont(), SetFontGD(), or SetFontTTF()
-       Use the element name 'y_label' for the data labels.
-
-Note that the PHPlot Reference Manual currently says the Y Data Label
-functions are only for bar chart data value labels (see Data Value Labels
-below regarding this term). That information is out of date. These
-functions are now also used for data labels in horizontal bar charts.
-
------------------------------------------------------------------------------
-Grid:
-
-For horizontal bar charts, the X grid lines default on, and the Y grid lines
-default off. (This is the opposite of normal bar charts, where the X grid
-lines default off, and the Y grid lines default on.)
-
------------------------------------------------------------------------------
-Y Axis Position:
-
-PHPlot uses a different default for the X axis and the Y axis positions.
-This affects horizontal bar charts if you have any data values which are
-less than zero.  The X axis is normally positioned at Y=0, and the Y axis
-is normally positioned at the left side of the plot.
-
-If you have both positive and negative values in your data array, both
-vertical and horizontal bar charts will draw the bars away from the zero
-value. For vertical bar charts, the X axis will be drawn at that zero value
-(perhaps in the middle of the plot), with bars going up and down from
-there. But for horizontal bar charts, the Y axis will by default remain at
-the left edge of the plot; the bars will start from the X=0 value
-(somewhere in the middle of the plot area) and go left and right from
-there. In this situation, you might want to use SetYAxisPosition(0) to
-force the Y axis to be at X=0.
-
------------------------------------------------------------------------------
-Scaling:
-
-You can use SetPlotAreaWorld() to explicitly set any or all of the 4 limits
-of the plot area. Any limits you do not provide will be calculated for you.
-The algorithm is due for replacement, but it will now apply the same
-calculations to Y and X values in horizontal bar charts as it currently
-applies to X and Y (respectively) in vertical bar charts. That is, the
-range for the independent variable will be calculated to contain and center
-the bar groups, and the range for the dependent variable will include and
-usually exceed the actual data range.
-
-The example under Usage above will produce an auto-calculated Y range of 4
-to 33, with the X range set to center the two bar groups. If you change
-'text-data-yx' to 'text-data', you will get a vertical bar chart with the
-same automatic range.
-
------------------------------------------------------------------------------
-Data Value Labels:
-
-Data Value Labels are not yet available with horizontal bar charts. These
-are the text labels within the plot that identify the data value just above
-the bars. (See Example 5.19 "Bar Chart with Data Labels" in the manual.)
-
-Note: Data Value Labels are currently referred to in the manual as Y Data
-Labels. If horizontal bars are accepted and documented in the manual, this
-will be changed to call them 'Data Value Labels'. This is necessary to
-avoid confusion with X Data Labels and Y Data Labels.
-
------------------------------------------------------------------------------
-Other Plot Types Not Available:
-
-There is currently no corresponding horizontal analog for plot type
-stackedbars, nor are there any other horizontal plot types at this time.
-Using data type 'text-data-yx' with other plot types will fail.
-(Starting with 5.1.2, PHPlot always checks that the selected data type
-is supported for the selected plot type.)
-
------------------------------------------------------------------------------
-Implementation Notes:
-
-The following is a summary of the changes made to PHPlot to implement
-horizontal bar charts.
-
-1) Do not initialize y_tick_label_pos or y_data_label_pos. The defaults
-have to be dynamically calculated for horizontal bar charts, so tick labels
-can be suppressed. (This was already being done for X labels.) Existing
-internal function CheckLabels() was extended to do this for Y also.
-
-2) Do not initialize the X and Y grid setting variables. The defaults have
-to be dynamically calculated because they differ with swapped data arrays.
-New internal function CalcGridSettings() does this.
-
-3) SetYDataLabelPos() accepts the new arguments plotleft, plotright, and
-both. Old compatibility code that passed these values to SetYTickLabelPos()
-has been removed.
-
-4) SetDataType() accepts a new value: 'text-data-yx'.
-
-5) FindDataLimits() was changed to properly calculate minimum and maximum
-values from text-data-yx data arrays. The arrays data_miny and data_maxy
-were renamed to just data_min and data_max, since they now describe limits
-of either X or Y values, depending on the data type.
-
-6) Changes were made to CalcMargins() to account for the labels in the data
-array being drawn on the Y axis instead of X axis, in the text-data-yx
-case.
-
-7) CalcPlotAreaWorld() is extended to calculate defaulted plot ranges
-correctly for the swapped X/Y case. The algorithm is the same (and due for
-replacement). It applies a fixed range to Y and an extended range to X. It
-is also ready for possible future expansion to include swapped X/Y plots
-with explicit Y values.
-
-8) Changed CalcBarWidths() to use either the plot area width or height,
-depending on the bar directions, when calculating the bar widths.
-
-9) Extended CalcMaxDataLabelSize() to work with both X and Y labels.
-Before, it returned the maximum height of the data labels. Now it can
-instead return the maximum width of the data labels; this is used for
-horizontal bar charts.  It also has to pick the proper font, angle, and
-format code for X or Y.
-
-10) New internal function DrawYDataLabel() to draw data labels for
-horizontal bar charts.
-
-11) New internal function DrawHorizBars() draws the horizontal bar chart.
-
-12) DrawGraph() now decides to draw a bar or horizontal bar chart based on
-the data type (text-data or text-data-yx).
-
------------------------------------------------------------------------------
diff --git a/gosa-core/include/phplot-5.1.2/NEWS.txt b/gosa-core/include/phplot-5.1.2/NEWS.txt
deleted file mode 100644 (file)
index e5fdb24..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
-This is the NEWS file for PHPlot, with release documentation.
-The project web site is http://sourceforge.net/projects/phplot/
-The project home page is http://phplot.sourceforge.net/
-Refer the the ChangeLog file for detailed source changes.
------------------------------------------------------------------------------
-
-2010-06-29 Release 5.1.2
-
-Overview:
-
-This is the current stable release of PHPlot. Truecolor image support is no
-longer considered 'experimental', and is now documented in the reference
-manual. There is a new experimental feature for horizontal bar charts. This
-release also contains a bug fix and new feature.
-
-
-Cautions and Important Notes:
-
-The advisory against using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use
-TrueType fonts (TTF) continues. See the item below for PHPlot-5.1.1. The
-good news is that this has been fixed by the PHP Team and will be in the
-next releases.
-
-Compatibility of data type and plot type are now checked completely.  If
-you used an incorrect data type with certain plot types, your script may no
-longer work until you fix the data type. Specifically, the area, squared,
-and thinbarline plot types failed to check the data type they received, and
-treated anything other than 'data-data' as 'text-data'.  If you have a
-squared plot with data type 'data-data-error', for example (which is not
-supposed to work), it did produce a plot, but will now result in an error.
-
-The addition of horizontal bar charts should not impact any existing plot,
-with one small exception. The function SetYDataLabelPos() used to accept
-some additional, undocumented options (plotleft, plotright, both, yaxis)
-and pass these through to SetYTickLabelPos() "for compatibility". It no
-longer does so, as some of those are now used for horizontal bar chart
-labels. To position Y tick labels, use only SetYTickLabelPos().
-
-
-New features in 5.1.2:
-
-#3002606 "Add to plot and image border options":
-  SetPlotBorderType() now accepts 'right', 'top', and 'bottom', as well
-      as an array of options. So you can now control exactly which of the 4
-      border sides will be drawn.
-  SetImageBorderType() now accepts 'solid' as a choice. This will use the
-      actual color set with SetImageBorderColor(), rather than the darker
-      shade as type 'plain' does (which may have been a bug).
-  SetImageBorderWidth() is a new function that sets the width of the image
-      border. The defaults are the same as the fixed values used before: 1
-      pixel for plain, 2 pixels for raised.  The image border width is now
-      accounted for in margin calculations, if it is greater than 2 (to make
-      sure existing plots will not change).
-
-#2885930 "Horizontal Bars":
-  Horizontal bar charts are implemented, as an experimental feature.
-  'Experimental' means they are not yet documented in the reference manual,
-  and subject to change or removal.
-  Refer to the text file HorizontalBars.txt for details.
-
-#2947679 (follow-up) "Support for alpha blending/Truecolor":
-  Truecolor support is now documented in the Reference Manual. The interim
-  documentation file Truecolor.txt has been removed. Alpha channel
-  specification now works with both constructors and both image types.  This
-  fixes an issue if the base constructor was used with a truecolor background
-  image. (In PHPlot-5.1.1, the result would be a truecolor image, but the
-  alpha channel features were not available.)
-
-
-Bug Fixed in 5.1.2:
-
-#3010116 "Bad rendering of title in multi-plot image when using TTF":
-  Make sure the main title is drawn only once, to avoid bad rendering of
-  TTF titles with multiple plots due to anti-aliasing.
-
------------------------------------------------------------------------------
-
-2010-04-04 Release 5.1.1
-
-Overview:
-
-This is the current stable release of PHPlot. This release adds truecolor
-image support as an experimental feature, fixes a number of bugs and adds
-a few new features.
-
-The PHPlot reference manual has been updated to match this release.  The
-manual is available as a separate download from Sourceforge. The manual is
-also available for on-line viewing from the project home page.
-
-See the ChangeLog file in the release for more about changes and bug fixes.
-
-
-Cautions and Important Notes:
-
-Avoid using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use TrueType fonts
-(TTF). Some new bugs were introduced in those releases that adversely
-affects accurate positioning and rendering of TrueType font text.
-
-
-New features in 5.1.1:
-
-#2947679 "Support for alpha blending/Truecolor":
-  PHPlot can now produce truecolor images, with alpha blending of colors and
-  other effects. This is considered an experimental feature, meaning it is
-  not yet documented in the PHPlot Reference Manual, and subject to change.
-  Refer to the text file Truecolor.txt included in the PHPlot release for
-  information on using truecolor.
-  Two drawing changes were made to improve plot appearance with Truecolor:
-  + Filled dots (in points & linespoints plots) are now drawn better. This
-    also makes them look rounder with regular (non-Truecolor) plots.
-  + Area plots have the areas filled without overlapping each area down to
-    the Y axis. This was needed to fix problems with alpha blending, and
-    should have no effect on non-Truecolor plots.
-
-#2973995 "Add y-Data to Stackedbars":
-  You can now have Y Data Labels with 'stackedbars' plots. These label the Y
-  values (incremental and total) for each bar. Refer to the reference manual
-  page for SetYDataLabelPos().
-
-
-Bug Fixes in 5.1.1:
-
-#2976735 "Improvements and fixes for 'area' plots":
-  Moving X axis works; handle Y<0 better; new 'stackedarea' plot type is a
-  variation on 'area' with the data represented differently.
-
-#2974639 "Stacked bars plot breaks with X axis != 0":
-  Moving X axis works.
-
-#2963757 "point_counts undefined error in 5.1.0":
-  Fixed an error introduced in PHPlot-5.1.0 when point size and shape arrays
-  were set to the same size.
-
-#2938219 "Bars go in wrong direction":
-  For bar charts with all Y<0, bars will still be drawn down even if Y=0 is
-  not in range.
-
------------------------------------------------------------------------------
-
-2009-12-24 Release 5.1.0
-
-Overview:
-
-This is the current stable release of PHPlot. This release fixes a number of
-bugs and adds some new features. Some of the changes in this release can
-alter the appearance of plots, so be sure to review the information in this
-NEWS file and test this release with your application.
-
-The PHPlot reference manual has been updated to match this release.  The
-manual is available as a separate download from Sourceforge. The manual is
-also available for on-line viewing from the project home page.
-
-See the ChangeLog file in the release for more about changes and bug fixes.
-
-
-New features in 5.1.0:
-
-+ A new "contrib" directory has been added for useful add-ons.
-  This currently contains:
-    * prune_labels : Control data label density on X axis.
-    * color_range : Define a gradient map for data colors.
-
-+ Feature Request 2899921 "Allow different format for data and tick labels"
-  Text angle and format can now be controlled separately for data labels.
-
-+ Locale loading override
-  New variable locale_override stops PHPlot from getting locale from system.
-
-+ Translating Coordinates
-  New function GetDeviceXY() to translate world to device coordinates.
-
-+ New drawing callback
-  New callback 'draw_all', called after all drawing is done.
-  The manual now contains an example of using this new callback and
-  the new GetDeviceXY() function to annotate a plot.
-
-
-Bug Fixes in 5.1.0:
-
-#2914403 "Pie + X/Y titles: Undefined property error"
-  X/Y titles are now properly ignored for pie charts.
-
-#2908256 "Error: array_sum() should be an array" (drupal)
-#2916864 "Should at least print legend on pie charts with empty data"
-  Pie charts with invalid data (no Y values > 0) now make an empty plot.
-
-#2906436 "Fixes for X Tick Labels vs X Data Labels"
-  Smarter determination of whether to do Tick labels, Data labels, or both.
-
-#2900914 "Problem with display of 0 on Y axis"
-  Fixed rounding error that could produce something like Y=8.12345E-16.
-
-#2886365 "PHP 5 patch" (Declare all functions and variables in PHP5 style)
-  Most internal PHPlot member functions now have "protected" visibility.
-
-#2839547 "SetImageBorderType('none')
-  You can use SetImageBorderType('none') to turn the image border back off.
-
-#1795972 "Fix default point shapes"
-  We now have 20 (vs 10) point shapes, with 10 (vs 1) used by default.
-
-#1795971 "Fix default data colors"
-  We now have 16 (vs 8) default data colors, no duplicates, all visible.
-
-
-Visible Changes and Possible Incompatibilities:
-
-+ PHP5 visibility changes (Bug #2886365)
-Details: Most internal PHPlot member functions now have visibility
-    'protected', rather than all being public. All member variables are
-    still 'public'.
-
-Reason for the change: Use the recommended PHP5 syntax, better OO style.
-
-Compatibility: If you were calling a PHPlot internal function that got
-    changed to 'protected', this will break. Please report this.
-
-
-+ Fix default point shapes (Bug 1795972)
-Details: We now have 20 (vs 10) point shapes available, and by default we
-    have 10 (vs 1) different shapes in use. The default size is now 6 pixels
-    for all point shapes.
-
-Reason for the changes: Using different shapes helps distinguish the data
-    sets. The existing 10 defined shapes were not enough, since some of them
-    are not centered over the points, too small, or otherwise hard to see.
-    The code to synchronize the point shape and size arrays was broken, and
-    some dubious code to adjust sizes to even numbers needed to be fixed.
-
-Compatibility (1): If you have a points or linepoints plot with more than
-    one dataset, and you did not use SetPointShapes() to configure the
-    shapes, them your plot will change from using a diamond for all data
-    sets to using different shapes for up to 10 data sets.
-
-Compatibility (2): Fixing the point size/point shape array size bug may
-    slightly change the size of some shapes, but it now works the way it
-    was documented and supposed to work.
-
-+ Fix default data colors (Bug 1795971)
-Details: Defined a new set of 16 default data colors. The colors are
-    different and contrast well against the default white background.
-    The first 4 colors were not changed.
-
-Reason for the change: The default 8 data colors included two instances
-    of orange, and one color which was invisible on a white background.
-
-Compatibility: Colors will change on any plot with more than 4 data sets
-    where you did not use SetDataColors() to set your own data colors.
-
-+ Re-used old function SetXDataLabelAngle()
-Details: SetXDataLabelAngle() now does something different.
-
-Reason for the change: This name was needed for a new function, to set the
-    angle for the X Data Labels. The old use of this function was not
-    documented, and marked "deprecated" in the code since around 2003-12-07.
-
-Compatibility: If you are still using SetXDataLabelAngle() to set both Tick
-    and Data label angles, you need to use SetXLabelAngle() instead.
-
-+ Separate controls for tick and data labels (Feature Request 2899921)
-Details: New functions SetXDataLabelAngle(), SetYDataLabelAngle(),
-    SetXDataLabelType(), and SetYDataLabelType() to allow separate control
-    over the angle and format of data labels, versus tick labels.
-
-Reason for the change: Allow Data Labels to use different formatting and
-    angle compared to Tick Labels.
-
-Compatibility: The default behavior has been set up such that there should
-    be no compatibility issues. For example:
-    Old behavior: SetXLabelType() sets the type for both tick and data labels.
-    New behavior: SetXLabelType() sets the type for tick labels and the
-        default type for data labels.  SetXDataLabelType() sets the type for
-        data labels (overrides SetXLabelType).
-
-+ X Tick Labels vs X Data Labels (Bug 2906436)
-Details: Regarding SetXTickLabelPos() and SetXDataLabelPos(): If only one
-    of them is called, the behavior is unchanged (only that label type will
-    be displayed). If both are called: Do exactly what was requested. If
-    neither was called: display only data labels if any data labels are
-    non-empty, else display only tick labels.
-
-Reason for the change: 1) Fix the long-standing problem behavior that by
-    default PHPlot overlays tick and data labels below the X axis. 2) Fix
-    order dependency between setting the position of tick and data labels.
-    3) Prepare for future extension of data labels, and allow both tick
-    and data labels to be on if the programmer enables both.
-
-Compatibility: There are some cases where your plot will change.
-    (a) Calls neither SetXDataLabelPos() nor SetXTickLabelPos():
-      Old behavior: Both tick and data labels displayed, possibly overlaid.
-      New behavior: If there are any non-blank data labels, then show only
-          the data labels, not the tick labels. Otherwise, show tick labels.
-
-   (b) Calls both SetXDataLabelPos() and SetXTickLabelPos(), with other than
-       'none' for each position:
-     Old behavior: The latter call was effective; earlier one ignored.
-     New behavior: Independent of order, both calls are effective.
-
------------------------------------------------------------------------------
-
-2009-06-14 Release 5.0.7
-
-Overview:
-
-This is the current stable release of PHPlot. The release adds one new
-feature, fixes a few bugs, and changes the license under which PHPlot
-is released.
-
-The PHPlot reference manual has been updated to match this release.  The
-manual is available as a separate download from Sourceforge. The manual is
-also now available for on-line viewing at http://phplot.sourceforge.net
-
-See the ChangeLog file for more about changes and bug fixes.
-
-
-Licensing:
-
-PHPlot is now released on the terms of the GNU Lesser General Public
-License, version 2.1. (Previous versions of PHPlot were released under
-a dual "PHP/GPL" license.) The licensing change was authorized by the
-original author and copyright holder of PHPlot.
-
-
-New feature in 5.0.7:
-
-+ Plot area margins can now be partially specified, using either
-  SetMarginsPixels or SetPlotAreaPixels. In previous releases of
-  PHPlot you had to either specify all 4 margins or none.
-  Credit to adoll for this feature.
-
-
-Visible Changes and Possible Incompatibilities:
-
-+ Y data range can change:
-  As a result of the bug fixes in this release, automatically-calculated
-  Y data ranges can change. If you have missing Y values in your data,
-  and you let PHPlot calculate the Y data range (that is, you do not
-  call SetPlotAreaWorld with a Ymin value), then the lower limit for Y
-  can change. If you have a plot with data-data-error data type, different
-  error values for different points, and let PHPlot calculate the Y data
-  range, then either Y limit can change.
-
-
-Bug Fixes in 5.0.7:
-
-
-+ Fix for bug 2803900: SetRGBArray('large') does not work:
-  Corrected an array name usage problem. You can now select the large
-  color map. Also PHPlot no longer overrides use of the PHP include
-  path when loading the large color map, and now reports an error if the
-  file is needed and not found.
-
-+ Fix for bug 2791502 "Error plots treat missing Y values as 0":
-  Missing Y values now with with data-data-error plots.
-
-+ Fix for bug 2792860 "Wrong DataLabelLines with missing Y":
-  Data label lines are now suppressed at missing Y values.
-
-+ Fix for bug 2786350 "Missing Y data results in bad auto-range":
-  Missing Y values are now ignored when calculating the Y data range.
-  Bug report and analysis by mrten.
-
-+ Fix for bug 2786354 "Incorrect auto-range for data-data-error":
-  The Y data range is now correctly calculated for data-data-error plots
-  when the error values differ from point to point.
-
-
------------------------------------------------------------------------------
-
-2009-01-20 Release 5.0.6
-
-Overview:
-
-This is the current stable release of PHPlot. The purpose of this release
-is to fix additional problems with text spacing and positioning, and
-introduce some minor new features.
-
-The PHPlot reference manual has been updated to match this release.  The
-manual is available as a separate download from Sourceforge. The manual is
-also now available for on-line viewing at http://phplot.sourceforge.net
-
-
-New features in 5.0.6:
-
-+ Allow mixing GD and TrueType font text on the same plot
-  You can use the new method functions SetFontGD() and SetFontTTF() to
-  select a font and font type for text element (labels, titles, etc.) For
-  example, you can have TrueType plot titles, and GD-fixed font labels.
-  SetUseTTF() now sets the default text type, TTF or GD. This is fully
-  backward compatible.
-
-+ Extended label formatting
-  See the reference manual for more information on these.
-
-  New label formatting types are added: 'printf' (using a user-defined
-  format), and 'custom' (using a callback function).
-
-  For 'data' type formatting, a prefix and suffix can be added. (PHPlot
-  previously had an undocumented suffix for 'data' type, which still
-  works.)
-
-  For 'time' formatting, the format can now be specified in the same function
-  call rather than using SetXTimeFormat and SetYTimeFormat.
-
-  For 'data' formatting, the precision can now be specified in the same
-  function call, rather than using SetPrecisionX and SetPrecisionY.
-
-+ Better control over line spacing in multi-line labels
-
-  Line spacing can now be set separately for each text element using an
-  additional argument to SetFont, SetFontGD, and SetFontTTF.  The overall
-  SetLineSpacing() value is the default for each text element that does not
-  have a specific line spacing set.
-
-  PHPlot now interprets the value set for line spacing as the number of
-  pixels only for GD text. For TrueType text, it is a scale factor for the
-  font's built-in line spacing for TrueType text. The equation used is:
-      interline_spacing = line_spacing * font_natural_spacing / 6
-  where line_spacing is either the global value set with SetLineSpacing
-  or a more specific value set with SetFont(), and font_natural_spacing
-  is the amount of space between lines built-in to the TrueType font. The
-  factor 6 should really be 4 (since PHPlot always used 4 as the default
-  line_spacing, this would give the natural font spacing by default). But
-  the text is too widely spaced with this value, and 6 was chosen to be
-  more compatible for typical font sizes.
-
-Visible Changes and Possible Incompatibilities:
-
-+ Line spacing
-  Multi-line TrueType titles and labels will have different inter-line
-  spacing. Since the text size affects the margin and plot area sizes,
-  this results in slightly different sized features on any plot with
-  multi-line TrueType text.
-  Previous versions of PHPlot used a default 4 pixels for inter-line
-  spacing of multi-line TrueType text, regardless of the font size.
-  PHPlot now uses the 'natural' font inter-line spacing, adjusted by a line
-  spacing parameter (per text type, with a global default).
-
-  The same change can also increase the size of the legend box slightly.
-
-+ Internal changes were made to the way font information is stored. Anything
-  that directly references PHPlot internals regarding fonts will break. Usage
-  also changed for the internal functions to size and draw text (ProcessText*,
-  SizeText*) due to font data storage changes.
-
-+ Changes were made to internal class variables used to store label
-  formatting information. Anything relying on these internals may break.
-
-
-Bug Fixes in 5.0.6:
-
-#1932571: Data-Data Plot fails with same X values
-  PHPlot will no longer hang if all X values are the same. But this is
-  interim fix to force the X range to 1 to prevent the hang. Eventually,
-  smarter automatic range code will handle this better.
-  Credit to andyl for finding this.
-
-#1891636: Misaligned TTF X Labels
-  PHPlot will now correctly line-up TrueType labels along the X axis. There
-  were small but very noticeable errors before, when the text had descenders
-  or lines with all short letters.
-
-
------------------------------------------------------------------------------
-
-2008-01-13 Released 5.0.5
-
-Overview:
-
-This is the current stable release of PHPlot. The emphasis of this release
-is to improve text positioning, margin calculation, and error handling.
-
-Although this is considered a stable release, it has a large amount
-of changed code compared to the previous release 5.0.4. Two of the more
-complex components of PHPlot - text and margin calculations - were mostly
-re-written in this release. You are advised to carefully test your own
-applications with PHPlot-5.0.5 to see how your plots look. Refer to the
-README.txt file included in the release for information on reporting problems.
-
-Starting with this release, PHPlot no longer supports PHP4, since the PHP
-group officially declared end-of-life for PHP4 as of 31 December 2007.
-PHPlot-5.0.5 was tested only with PHP-5.2.5 and we are unlikely to address
-any issues using PHPlot with older versions of PHP.
-
-The PHPlot reference manual has been updated to match this release.  The
-manual is available as a separate download from Sourceforge. The manual is
-now also now available for on-line viewing at http://phplot.sourceforge.net
-
-The callback feature added in 5.0.4 is now documented in the reference
-manual. It is still considered experimental and subject to change, however.
-
-
-
-Visible Changes and Possible Incompatibilities:
-
-+ Dropped support for PHP4.
-
-+ Eliminated remaining order-dependent behavior related to margins and
-text. PHPlot should now do nothing at all, except record parameters, until
-you draw the graph with DrawGraph. I believe this was always the intended
-behavior of PHPlot, but over time perhaps various pre-calculations and
-dependencies crept in. Fixing this simplifies processing and should lead to
-more consistent behavior.
-
-+ The rewritten margin calculation code now uses actual sizes of all tick
-and data labels and tick marks, rather than guesses. Margins collapse to
-remove unused elements, but a minimum margin (currently fixed at 15 pixels)
-is applied so the plot edges don't get to close to the image edges. The
-result is that most graphs with auto-calculated margins will change in
-appearance. It most cases, the margins get slightly smaller. In other
-cases, earlier releases mis-calculated the margins, so this release will
-produce much neater margins.
-
-+ The X and Y titles are now offset out from the plot area, not in from the
-image area.  For auto-calculated margins this should not make any
-difference, but if you use SetMarginsPixels or SetPlotAreaPixels to set
-larger margins, the axis titles will move in closer to the plot with this
-release.
-
-+ Changes were made to PHPlot internals, including removal of some class
-variables and functions, and addition of new variables and functions.
-These are documented in the ChangeLog. Relying on any internal variables
-or functions in an application using PHPlot is unwise. The following
-internal functions were removed:
-     SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights()
-     CalcYWidths() DrawLabels() InitImage() DrawDashedLine()
-         These were marked 'deprecated', were undocumented and unmaintained.
-     TTFBBoxSize()
-         This was replaced with SizeText().
-
-+ Line spacing set with SetLineSpacing() now affects TTF text as well as
-GD text. Previously, it only affected GD text. The default line spacing
-happens to be usable for TTF text.
-
-+ Changes were made to error handling. PHPlot will now trigger a user-level
-error after producing an error image, instead of exiting.  If no error
-handler has been set, it will exit, as before. But now the error message
-should also get logged, or written to the standard error stream, depending
-on the SAPI in use.  You can now establish an error handler to catch most
-PHPlot errors and do some cleanup before exit.
-
-+ PHPlot no longer accepts some invalid option values (such as a substring
-of a valid value, or empty strings) passed to functions. If your
-application aborts in CheckOption with PHPlot-5.0.5 but 'worked' with
-previous releases, them you were probably using an invalid option value.
-
-
-
-Bug Fixes in 5.0.5:
-
-#945439: x_tick_label_height not set correctly
-  Exact sizes of labels are now used to calculate margins.
-
-#1813070: Bad position for multi-line TrueType text
-  Fixed as part of text functions rewrite. Use correct basepoint
-  (lower left of each line) when positioning text lines.
-
-#1813071: Wrong title height for multi-line TTF text
-  Fixed as part of text functions rewrite: calculate height of
-  multi-line text correctly. Also now uses the line-spacing setting.
-
-#1813474: DrawText alignment arguments wrong
-  Fixed so 'top' and 'bottom' now have the usual meaning: top means
-  align top of text with reference, bottom means align bottom of text.
-  This was switched before. Changed every internal caller to compensate.
-
-#1816844: Fix order dependency for setting titles
-  Defer processing of title strings until DrawGraph(),
-  so it doesn't matter if fonts, etc. are set before or after.
-
-#1819668: Horiz. align multi-line text: GD vs TTF
-  The text functions were rewritten to draw TTF text line-by-line,
-  like GD text, and correctly align each line.
-
-#1823774: Default Font Path and Error Message
-  Error handling has been improved to make sure a message is logged, in
-  addition to the error image, and use error_trigger rather than exit.
-
-#1826513: FIXME in DrawLegend: Max label length
-  The actual size needed for legend text is now used.
-
-#1827263: Spoiled up pie-chart if $val is close to zero
-  Fixed by skipping over any segment that rounds to 0 degrees of
-  arc. (The GD function uses integer angles only, and 0 degrees
-  means draw a complete circle.)
-
-#1836528: Insufficient checking of parameter values
-  Rewrote validator function to reject improper parameter values.
-
-#1843012: Make margins, drawing consistent
-  Margin code logic was rewritten and checked for consistency.
-
-#1856207: Margin error with 'xaxis'/'yaxis' position
-  Margin space is now allocated for ticks and labels if their position
-  is 'xaxis' or 'yaxis' and the axis is at the plot edge. This is not
-  a perfect fix (the axis could be close but not at the edge).
-
-
------------------------------------------------------------------------------
-
-2007-10-20 Released 5.0.4
-
-Overview:
-
-This is the latest stable release of PHPlot. We are abandoning the 'rc'
-version naming style, because we don't consider these last releases
-'release candidate' versions. As we continue to make changes to PHPlot,
-we are not converging toward a final "5.0" release, however we do consider
-these releases stable and complete enough for production use.
-
-This release fixes a number of problems and introduces a few new features.
-
-The PHPlot reference manual has also been updated to match this release.
-New material has been added documenting some of the PHPlot internals.
-The manual is available as a separate download from Sourceforge.
-
-
-Code Cleanup:
-
-Some code cleanup is going in to this release. It is hoped that these
-changes will not impact any existing scripts using PHPlot, but will make
-the PHPlot code itself easier to understand and maintain.
-
-PHPlot now avoids making changes outside its own class definition. There
-are no longer any functions defined outside the class, nor any constants.
-Three constants (MINY MAXY TOTY) were removed, and 2 functions were removed
-(see Visible Changes below).  Also PHPlot no longer sets the PHP error
-reporting level to E_ALL. Although we highly recommend setting error
-reporting to E_ALL in your php.ini file or scripts, it is not right for
-PHPlot to assume that you want it.
-
-
-Visible Changes and Possible Incompatibilities:
-
-Arrays containing color and style information are used with several PHPlot
-functions to control the plot style array. These functions are:
-    SetPointShapes, SetPointSizes, SetLineWidths, SetLineStyles,
-    SetDataColors, SetDataBorderColors, and SetErrorBarColors.
-The arrays passed to these functions MUST used sequential integer 0-based
-indexes. This is what the PHP manual calls "Usual integer indices (starting
-from zero, increasing by one)". This is the type of array you get in PHP by
-default if you use array() without specifying key values, or use the
-empty-bracket assignment operator to add values onto an array.  In previous
-versions of PHPlot, some of these functions would also work with
-string-indexed or non-sequentially-indexed arrays, but this was not clearly
-defined. Starting with PHPlot-5.0.4, only arrays with "usual integer
-indices" work, and other array indexes will cause errors.
-
-Some internal-use-only functions have had their usage changed or been removed.
-If you are using functions that are not documented in the PHPlot Function
-Reference in the manual, your code may have to be changed.
-
-As part of the code cleanup, two functions which were defined outside the
-PHPlot class were removed: array_pad_array(), and array_merge_php4().
-If your code used these, you need to fix your code.
-
-The routines which accept a color name, value, or array now check for a valid
-color name. If you specify a color name which is not in your current color
-table, PHPlot will draw an error and exit. Previously, PHP would report an
-index error, continue, and get a 'headers already sent' message.
-
-
-Bug Fixes in 5.0.4:
-
-#1813021: Miss-positioned right-justified vertical GD text.
-  Fixed DrawText() to correctly position 90 degree right-justified text
-  drawn in a fixed GD font. This could be seen with 90 degree Y tick labels.
-
-#1790441 Removed destructor/shutdown function, and no longer recommend
-  using reference assignment when creating a PHPlot object. This was
-  interfering with memory usage.
-  Credit to annajilly for analysis.
-
-#1779115 SetLegendWorld() failed because of undefined variables. The
-  required order dependency was too hard to meet. This is now fixed.
-  You can now use SetLegendWorld anywhere before DrawGraph.
-
-#1726810 (feature request, but actually a bug fix) Ignore empty strings
-  as data labels when doing time or data label formatting. These would
-  previously produce errors or bad formatting. Now you can omit labels
-  as needed even with time and data formatting.
-  Credit to exgerhardr for finding this.
-
-#1605555 Y data labels used wrong font and not formatted (bar charts only).
-
-#1208054 Localization of number formatting in 'data' format type. PHPlot
-  will attempt to format the numbers in a way appropriate to your locale.
-  You can also force the formatting with the new function SetNumberFormat.
-  Credit to David Hernández Sanz.
-
-#937944 X/Y Tick counts: PHPlot could draw one two few Y tick counts, and
-  one too many X tick counts. This is not a perfect fix, and more work is
-  needed here, but this fixes an error case in both X and Y values.
-
-
-New Features in 5.0.4:
-
-New function SetLegendStyle allows control of the alignment of text and
-  color boxes within the legend.  Also allows removing the color boxes.
-  Based on bug #1208054.
-  Credit to David Hernández Sanz.
-
-New function SetNumberFormat. See bug report #1208054 above.
-
-Callbacks are added. PHPlot can call back your functions while generating the
-  plot. This is experimental, and documented only in the file "Callbacks".
-  Credit to annajilly for the idea and design.
-
------------------------------------------------------------------------------
-
-2006-11-13 Released 5.0rc3
-
-Overview:
-
-This is an interim release. It has been a long time since the previous
-release 5.0rc2, and there have been a lot of changes. There are still more
-changes likely to go in before we have "5.0", but there are enough for now.
-
-The PHPlot Reference Manual has also been released, and is available as a
-separate download from Sourceforge. PHPlot users and developers are
-strongly encouraged to read the manual.
-
-This release does not include the "doc/" and "examples/" directories of
-previous releases. The Reference Manual contains more complete and
-up-to-date information and examples, and I am unable to maintain the doc/
-and examples/ files while also maintaining the Reference Manual. If you
-need those files, they can be accessed with the Sourceforge web CVS
-browser.
-
-
-New Features:
-
-The emphasis for this release is bug fixing, so there are few new features.
-
-+ You can now suppress lines or points on individual plots in a linepoints
-  graph. This feature was added because I needed a graph with several
-  linepoints lines, but also with a solid line showing an "80% goal".
-  Use SetPointShapes with the value 'none' in the array to suppress the
-    point markers for that plot (and only draw the line).
-  Use SetLineStyles with the value 'none' in the array to suppress the
-    line for that plot (and only draw the point markers).
-  [Bug # 1594458]
-
-+ Bar charts can have data labels above the bar with the value. Turn
-  these on with SetYDataLabelPos('plotin'). This is somewhat experimental,
-  since there isn't a lot of room for labels on top of the bars and you
-  may find the results are not useful.
-
-
-Visible Changes:
-
-Here are the more significant changes in this release. These are changes
-which may affect existing scripts and output from PHPlot.  See the
-ChangeLog file for information about all changes and bug fixes.
-
-+ A bug fix on bar chart bar borders results in black borders around the
-  bars if shading is turned off. The border was previously covered up,
-  but was supposed to be there. If you need borderless, unshaded bars,
-  you need to use SetDataBorderColors to make the borders the same colors
-  as the bars. [Bug # 1096197]
-
-+ TrueType font pathname handling was fixed. You no longer need to use
-  SetUseTTF(True). You can either use full paths to the font files with
-  SetDefaultTTFont() and SetFont(), or you can call SetTTFPath() to point
-  to a directory of font files, and then use simple font filenames without
-  paths in SetDefaultTTFont() and SetFont().
-  [Bug # 1144644 plus several others]
-
-+ There have been several fixes regarding automatically calculated ranges
-  and scales. The result is that you may see less extra space and fewer
-  tick marks in some cases.
-
-+ A fix was made to bar and stackedbar graph bar widths in order to get
-  the X axis labels to properly center. As part of the fix, the bar widths
-  now match between the two graph types. (Before this fix, the bars were
-  narrower in bar graphs compared to the same data plotted as a stacked
-  bar.) As a result, bar graph bars will now be drawn with wider bars, and
-  stackedbar graph bars will be narrower. You can adjust this with the new
-  class variable bar_extra_space.     [Bug # 1437912]
-
-+ Dot shapes and sizes were off by 1 or 2 slots in the array of shapes or
-  sizes. After the fix, you may get different dot shapes or sizes per
-  plot line. [Bug # 1096194]
-
-
-Testing:
-Since its output is visual (graphics), and it has so many interconnected
-modes and options, PHPlot is difficult to test. But at least we are now
-trying. I have a collection of PHPlot scripts (currently about 60) and a
-script to run through them. The script automatically checks that:
-    1) Nothing was written to the standard error stream;
-    2) An image file of size greater than 0 was written;
-    3) Neither the test script nor PHPlot did exit(). This catches cases
-       where PHPlot aborts with DrawError().
-
-The automated test is an easy way to check for serious regression, but you
-really need to inspect the output files to validate PHPlot. This takes a
-little time, and it is easy to overlook problems.
-
-The real issue is test coverage. Just as we can be sure that future
-PHPlot releases will pass the test collection, we can also be sure that
-future bug reports will be written against untested cases.
-
---------------------
-
-2006-11-08 PHPlot on Sourceforge has a new maintainer: lbayuk
-
---------------------
-
-2004-10-24 Released 5.0rc2
-
---------------------
-
diff --git a/gosa-core/include/phplot-5.1.2/README.txt b/gosa-core/include/phplot-5.1.2/README.txt
deleted file mode 100644 (file)
index 03471bf..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-This is the README file for PHPlot
-Last updated for PHPlot-5.1.2 on 2010-06-29
-The project web site is http://sourceforge.net/projects/phplot/
-The project home page is http://phplot.sourceforge.net/
------------------------------------------------------------------------------
-
-OVERVIEW:
-
-PHPlot is a PHP class for creating scientific and business charts.
-
-The release documentation contains only summary information. For more
-complete information, download the PHPlot Reference Manual from the
-Sourceforge project web site. You can also view the manual online at
-http://phplot.sourceforge.net
-
-For important changes in this release, see the NEWS.txt file.
-
-
-CONTENTS:
-
-   COPYING  . . . . . . . . . . . . LGPL 2.1 License file
-   ChangeLog  . . . . . . . . . . . Lists changes to the sources
-   HorizontalBars.txt . . . . . . . Experimental feature documentation
-   NEWS.txt . . . . . . . . . . . . Highlights changes in releases
-   README.txt   . . . . . . . . . . This file
-   contrib  . . . . . . . . . . . . "Contributed" directory, add-ons
-   phplot.php   . . . . . . . . . . The main PHPlot source file
-   phplot_data.php  . . . . . . . . Auxiliary and extended functions
-   rgb.inc.php  . . . . . . . . . . Optional extended color table
-
-REQUIREMENTS:
-
-You need a recent version of PHP5. Usually, we recommend you use the latest
-stable release, however due to problems with PHP-5.3.2 and PHP-5.2.13 you
-are advised to use the previous releases if possible. The problems are
-specific to TrueType font (TTF) text. If you are not using TTF text, you
-may use PHP-5.3.2 or 5.2.13.  (The PHP team already has a fix for this TTF
-problem in PHP-5.3.3 development snapshots, so the fix should be in the
-next releases PHP-5.3.3 and PHP-5.2.14.)
-
-This version of PHPlot has been tested with PHP-5.3.1 and PHP-5.2.12 on
-Linux, and with PHP-5.3.1 on Windows/XP. The PHPlot Test Suite currently
-contains 432 test cases.
-
-You need the GD extension to PHP either built in to PHP or loaded as a
-module. Refer to the PHP documentation for more information - see the
-Image Functions chapter in the PHP Manual. We test PHPlot only with the
-PHP-supported, bundled GD library.
-
-If you want to display PHPlot charts on a web site, you need a PHP-enabled
-web server. You can also use the PHP CLI interface without a web server.
-
-PHPlot supports TrueType fonts, but does not include any TrueType font
-files.  If you want to use TrueType fonts on your charts, you need to have
-TrueType support in GD, and some TrueType font files.  By default, PHPlot
-uses a simple font which is built in to the GD library.
-
-
-INSTALLATION:
-
-Unpack the distribution. (If you are reading this file, you have probably
-already done that.)
-
-Installation of PHPlot simply involves copying three script files somewhere
-your PHP application scripts will be able to find them. The scripts are:
-     phplot.php
-     phplot_data.php
-     rgb.inc.php
-(Only phplot.php is necessary for most graphs.)
-Make sure the permissions on these files allow the web server to read them.
-
-The ideal place is a directory outside your web server document area,
-and on your PHP include path. You can add to the include path in the PHP
-configuration file; consult the PHP manual for details.
-
-
-KNOWN ISSUES:
-
-Here are some of the problems we know about in PHPlot. See the bug tracker
-on the PHPlot project web site for more information.
-
-#1795969 The automatic range calculation for Y values needs to be rewritten.  
-  This is especially a problem with small offset ranges (e.g. Y=[999:1001]).
-  You can use SetPlotAreaWorld to set a specific range instead.
-
-#1605558 Wide/Custom dashed lines don't work well
-  This is partially a GD issue, partially PHPlot's fault.
-
-#2919086 Improve tick interval calculations
-  Tick interval calculations should try for intervals of 1, 2, or 5 times
-  a power of 10.
-
-PHP Bugs #51207, #51094, and others: These are PHP bugs, not PHPlot,
-on rendering of TrueType font (TTF) text in PHP-5.3.2 and 5.2.13.
-
-
-If you think you found a problem with PHPlot, or want to ask questions or
-provide feedback, please use the Help and Discussion forum at
-     http://sourceforge.net/projects/phplot/
-If you are sure you have found a bug, you can report it on the Bug tracker
-at the same web site. There is also a Features Request tracker.
-
-
-TESTING:
-
-You can test your installation by creating the following two files somewhere
-in your web document area. First, the HTML file:
-
------------- simpleplot.html ----------------------------
-<html>
-<head>
-<title>Hello, PHPlot!</title>
-</head>
-<body>
-<h1>PHPlot Test</h1>
-<img src="simpleplot.php">
-</body>
-</html>
----------------------------------------------------------
-
-Second, in the same directory, the image file producing PHP script file.
-Depending on where you installed phplot.php, you may need to specify a path
-in the 'require' line below.
-
------------- simpleplot.php -----------------------------
-<?php
-require 'phplot.php';
-$plot = new PHPlot();
-$data = array(array('', 0, 0), array('', 1, 9));
-$plot->SetDataValues($data);
-$plot->SetDataType('data-data');
-$plot->DrawGraph();
----------------------------------------------------------
-
-Access the URL to 'simpleplot.html' in your web browser. If you see a
-simple graph, you have successfully installed PHPlot. If you see no
-graph, check your web server error log for more information.
-
-
-COPYRIGHT and LICENSE:
-
-PHPlot is Copyright (C) 1998-2010 Afan Ottenheimer
-
-This 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;
-version 2.1 of the License.
-
-This software 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 software; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/gosa-core/include/phplot-5.1.2/contrib/README.txt b/gosa-core/include/phplot-5.1.2/contrib/README.txt
deleted file mode 100644 (file)
index 3c63225..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-This is the README for PHPlot Contributed Code
-The project web site is http://sourceforge.net/projects/phplot/
-Last updated on 2009-12-08
------------------------------------------------------------------------------
-
-The PHPlot Contributed Code directory contains code you might find useful
-with PHPlot, but that doesn't quite belong as part of PHPlot itself.
-
-You will have to read the comments in the code files, and see the example
-files, to determine what these do and if they are useful to you. None of
-these functions is documented in the PHPlot Reference Manual.
-
-You may include or paste these functions into your own scripts. Check the
-files for details, but some of these are considered "public domain" with no
-usage or license restrictions.
-
------------------------------------------------------------------------------
-Contents:
-
-prune_labels: Reduce the number of labels along the X axis
-    prune_labels.php . . . . . . . . . . . . Code
-    prune_labels.example.php . . . . . . . . Example
-    prune_labels.test.php  . . . . . . . . . Test
-
-color_range: Create a gradient color map for data colors
-    color_range.php  . . . . . . . . . . . . Code
-    color_range.example.php  . . . . . . . . Example
-    color_range.test1.php  . . . . . . . . . Image creation test
-    color_range.test2.php  . . . . . . . . . Unit test
-
------------------------------------------------------------------------------
diff --git a/gosa-core/include/phplot-5.1.2/contrib/color_range.example.php b/gosa-core/include/phplot-5.1.2/contrib/color_range.example.php
deleted file mode 100644 (file)
index d29978b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-# PHPlot / contrib / color_range : Example
-# $Id: color_range.example.php,v 1.1 2009/12/09 03:45:45 lbayuk Exp $
-# This is a bar chart with a color gradient for the bars in each group.
-
-require_once 'phplot.php';
-require_once 'color_range.php';
-
-$bars_per_group = 10;
-$x_values = 4;
-
-mt_srand(1);
-$data = array();
-for ($i = 0; $i < $x_values; $i++) {
-    $row = array($i);
-    for ($j = 0; $j < $bars_per_group; $j++) $row[] = mt_rand(0, 100);
-    $data[] = $row;
-}
-
-$p = new PHPlot(800, 600);
-$p->SetTitle('Example - Bar Chart with gradient colors');
-$p->SetDataType('text-data');
-$p->SetDataValues($data);
-$p->SetPlotAreaWorld(0, 0, $x_values, 100);
-
-# This isn't necessary, as we do know how many data sets (bars_per_group):
-$n_data = count_data_sets($data, 'text-data');
-# Make a gradient color map:
-$colors = color_range($p->SetRGBColor('SkyBlue'),
-                      $p->SetRGBColor('DarkGreen'), $n_data);
-$p->SetDataColors($colors);
-$p->SetXTickLabelPos('none');
-$p->SetXTickPos('none');
-$p->SetPlotType('bars');
-$p->DrawGraph();
diff --git a/gosa-core/include/phplot-5.1.2/contrib/color_range.php b/gosa-core/include/phplot-5.1.2/contrib/color_range.php
deleted file mode 100755 (executable)
index 65437ed..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-/*
-   PHPlot / contrib / color_range
-   $Id: color_range.php,v 1.1 2009/12/09 03:45:48 lbayuk Exp $
-   PHPlot contrib code - public domain - no copyright - use as you wish
-
-   Original contribution from: Josep Sanz <josep dot sans at w3 dot es>
-      "I wrote this code to calculate the range of colors between 2 colors
-      to plot using the range from color_a to color_b..."
-
-   I have changed the code and repackaged it, but the idea is the same.
-   Given 2 colors and number of data sets, computes an array of colors
-   that make up a gradient between the two provided colors, for use
-   with SetDataColors().
-
-   Provides the following functions:
-       $colors = color_range($color_a, $color_b, $n_intervals)
-              Returns a color array for SetDataColors.
-
-       $n = count_data_sets($data, $data_type)
-              Counts the number of data sets in a data array.
-              This can be used to provide $n_intervals in color_range().
-*/
-
-
-
-/*
-   Fill a color map with a gradient step between two colors.
-  Arguments:
-    $color_a : Starting color for the gradient. Array of (r, g, b)
-    $color_b : Ending color for the gradient. Array of (r, g, b)
-    $n_steps : Total number of color steps, including color_a and color_b.
-
-  Returns: A color map array with n_steps colors in the form
-           $colors[i][3], suitable for SetDataColors().
-
-  Notes:
-    You may use the PHPlot internal function $plot->SetRGBColor($color)
-    to convert a color name or #rrggbb notation into the required array
-    of 3 values (r, g, b) for color_a and color_b.
-
-*/
-function color_range($color_a, $color_b, $n_steps)
-{
-    if ($n_steps < 2) $n_steps = 2;
-    $nc = $n_steps - 1;
-    # Note: $delta[] and $current[] are kept as floats. $colors is integers.
-    for ($i = 0; $i < 3; $i++)
-        $delta[$i] = ($color_b[$i] - $color_a[$i]) / $nc;
-    $current = $color_a;
-    for ($col = 0; $col < $nc; $col++) {
-        for ($i = 0; $i < 3; $i++) {
-            $colors[$col][$i] = (int)$current[$i];
-            $current[$i] += $delta[$i];
-        }
-    }
-    $colors[$nc] = $color_b;  # Make sure the last color is exact.
-    return $colors;
-}
-
-
-/*
-    Determine the number of data sets (plot lines, bars per group, pie
-    segments, etc.) contained in a data array.
-    This can be used to determine n_steps for $color_range.
-
-  Arguments:
-    $data : PHPlot data array
-    $data_type : PHPlot data type, describing $data. (e.g. 'data-data')
-  Returns: The number of data sets in the data array.
-  Notes:
-    This has to scan the entire data array. Don't use this unless you
-    really don't have a better way to determine the number of data sets.
-
-    This does NOT require that the data array be integer indexed.
-
-*/
-function count_data_sets($data, $data_type)
-{
-
-    if ($data_type == 'text-data-single')
-        return count($data); # Pie chart, 1 segment per record
-
-    # Get the longest data record:
-    $max_row = 0;
-    foreach ($data as $row)
-        if (($n = count($row)) > $max_row) $max_row = $n;
-
-   if ($data_type == 'text-data')
-      return ($max_row - 1);  # Each record is (label Y1 Y2...)
-
-   if ($data_type == 'data-data')
-      return ($max_row - 2); # Each record is (label X Y1 Y2...)
-
-   if ($data_type == 'data-data-error')
-      return (($max_row - 2) / 3); # Each record is (label X Y1 Y1+ Y1-...)
-
-   # Not a recognized data type... Just return something sane.
-   return $max_row;
-}
diff --git a/gosa-core/include/phplot-5.1.2/contrib/color_range.test1.php b/gosa-core/include/phplot-5.1.2/contrib/color_range.test1.php
deleted file mode 100644 (file)
index 661f591..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-# PHPlot / contrib / color_range : Test 1, make a picture
-# $Id: color_range.test1.php,v 1.1 2009/12/09 03:45:49 lbayuk Exp $
-# This creates a PNG file on output with a color gradient.
-
-require_once 'color_range.php';
-
-function usage()
-{
-   fwrite(STDERR, "Usage: color_range.test1.php color1 color2 number_of_colors
-Each color is of the form rrggbb with 2 digit hex color components.
-");
-   exit(1);
-}
-
-# Split color "rrggbb" into separate components. Code is from PHPlot.
-function rgb($color)
-{
-  return array(hexdec(substr($color, 1, 2)),
-               hexdec(substr($color, 3, 2)),
-               hexdec(substr($color, 5, 2)));
-}
-
-if ($_SERVER['argc'] != 4) usage();
-
-$color1 = rgb($_SERVER['argv'][1]);
-$color2 = rgb($_SERVER['argv'][2]);
-$n_col = (int)$_SERVER['argv'][3];
-if ($n_col < 2) usage();
-
-# Build a color map from colors[0]=color1 to colors[$n_col-1]=color2.
-$colors = color_range($color1, $color2, $n_col);
-
-# Make a picture:
-$w = 800;
-$h = 800;
-$im = imagecreate($w, $h);
-$background = imagecolorresolve($im, 0, 0, 0);
-for ($col = 0; $col < $n_col; $col++) {
-    list($r, $g, $b) = $colors[$col];
-    $colmap[$col] = imagecolorresolve($im, $r, $g, $b);
-}
-
-$margin = 20;
-$bar_width = (int)(($w - 2 * $margin) / $n_col);
-$x1 = $margin;
-$x2 = $x1 + $bar_width;
-$y1 = $margin;
-$y2 = $h - $margin;
-for ($col = 0; $col < $n_col; $col++) {
-    imagefilledrectangle($im, $x1, $y1, $x2, $y2, $colmap[$col]);
-    $x1 = $x2;
-    $x2 += $bar_width;
-}
-imagepng($im);
diff --git a/gosa-core/include/phplot-5.1.2/contrib/color_range.test2.php b/gosa-core/include/phplot-5.1.2/contrib/color_range.test2.php
deleted file mode 100644 (file)
index bf6ff6c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-/*
-  PHPlot / contrib / color_range : Unit tests
-  $Id: color_range.test2.php,v 1.1 2009/12/09 03:45:51 lbayuk Exp $
-
-  Tests color.range.php functions:
-      color_range($color_a, $color_b, $n_steps)
-      count_data_sets($data, $data_type)
-
-*/
-require_once 'color_range.php';
-
-
-# Testing count_data_sets()
-function test_count_data_sets($data, $data_type, $expected)
-{
-  $n = count_data_sets($data, $data_type);
-  if ($n == $expected) $result = "Pass";
-  else $result = "FAIL: Expected $expected but got";
-  echo "$result: $n data sets, $data_type with " . count($data) . " records.\n";
-}
-
-function test_driver_count_data_sets()
-{
-    echo "\nTesting count_data_sets():\n";
-    $data1 = array(array('a', 1, 2, 3), array('b', 2, 2, 3));
-    $data2 = array(array('a', 1, 2, 3, 4, 5, 6, 7), array('b', 2, 4, 5, 6));
-    $data3 = array(array('', 1), array('', 2), array('', 3), array('', 4));
-    $data4 = array(array('', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
-                   array('', 1, 2, 3, 4, 5, 6, 7),
-                   array('', 1, 2, 3, 4));
-
-    test_count_data_sets($data1, 'text-data', 3);
-    test_count_data_sets($data1, 'data-data', 2);
-    test_count_data_sets($data2, 'data-data-error', 2);
-    test_count_data_sets($data3, 'text-data-single', 4);
-
-    test_count_data_sets($data4, 'text-data', 13);
-    test_count_data_sets($data4, 'data-data', 12);
-    test_count_data_sets($data4, 'data-data-error', 4);
-    test_count_data_sets($data4, 'text-data-single', 3);
-}
-
-# Testing color_range()
-function test_color_range($color1, $color2, $nsteps, $expected)
-{
-    $info = 'From (' . implode(', ', $color1)
-       . ') To (' . implode(', ', $color2) . ") with $nsteps steps";
-
-    $colors = color_range($color1, $color2, $nsteps);
-    if ($colors == $expected) echo "Pass: $info\n";
-    else echo "FAIL: $info\n" . print_r($colors, True) . "\n";
-    if (($n = count($colors)) != $nsteps)
-        echo "FAIL: Bad count $n expecting $nsteps\n";
-}
-
-function test_driver_color_range()
-{
-    echo "\nTesting color_range():\n";
-    test_color_range(array(0,0,0), array(255,255,255), 3,
-        array(array(0,0,0), array(127,127,127), array(255,255,255)));
-
-    test_color_range(array(255,0,0), array(0,255,0), 2,
-        array(array(255,0,0), array(0,255,0)));
-
-    test_color_range(array(100,0,100), array(0,100,0), 6,
-        array(array(100,0,100), array(80,20,80), array(60,40,60),
-              array(40,60,40), array(20,80,20), array(0,100,0)));
-}
-
-
-test_driver_count_data_sets();
-test_driver_color_range();
diff --git a/gosa-core/include/phplot-5.1.2/contrib/prune_labels.example.php b/gosa-core/include/phplot-5.1.2/contrib/prune_labels.example.php
deleted file mode 100644 (file)
index ae05bbf..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-# PHPlot / contrib / prune_labels : Example
-# $Id: prune_labels.example.php,v 1.1 2009/12/09 03:45:53 lbayuk Exp $
-# This produces 250 data points with date-formatted labels, and sets
-# a max of 20 labels to display.
-
-require_once 'phplot.php';
-require_once 'prune_labels.php';
-
-$base = mktime(12, 0, 0, 1, 1, 2000);
-$data = array();
-for ($i = 0; $i < 250; $i++) {
-    $data[] = array(86400 * $i + $base, $i, $i * 0.20);
-}
-
-# Show no more than 20 labels:
-prune_labels($data, 20);
-
-$p = new PHPlot(800, 600);
-$p->SetTitle('Example - pruned data labels');
-$p->SetDataType('data-data');
-$p->SetDataValues($data);
-$p->SetXLabelType('time', '%Y-%m-%d');
-$p->SetXLabelAngle(90);
-$p->SetXDataLabelPos('plotdown');
-$p->SetXTickLabelPos('none');
-$p->SetXTickPos('none');
-$p->SetDrawXGrid(False);
-$p->SetDrawYGrid(False);
-$p->SetPlotType('lines');
-$p->DrawGraph();
diff --git a/gosa-core/include/phplot-5.1.2/contrib/prune_labels.php b/gosa-core/include/phplot-5.1.2/contrib/prune_labels.php
deleted file mode 100644 (file)
index 5f272e5..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-/*
-   PHPlot / contrib / prune_labels
-   $Id: prune_labels.php,v 1.1 2009/12/09 03:45:55 lbayuk Exp $
-   PHPlot contrib code - public domain - no copyright - use as you wish
-
-Reduce the number of data labels along the X axis,  when the density is too
-high.  This simply blanks out M-1 of every M labels in the data array.
-There are other ways to do this, but we need to keep the labels uniformly
-spaced.  You select the target maximum label count (maxlabels), and you will
-get no more than maxlabels data labels.
-
-  Arguments:
-     $data  - The PHPlot data array (reference variable)
-     $maxlabels - The maximum number of data labels you are willing to have,
-  Returns: Nothing
-     Modifies the $data array in place to remove some of the labels.
-
-   Notes:
-     The data array and its rows must be 0-based integer indexed arrays.
-*/
-function prune_labels(&$data, $maxlabels)
-{
-    # Do nothing if there are not already too many labels:
-    if (($n = count($data)) <= $maxlabels) return;
-
-    # Compute how many labels to erase. Keep 1 of every $m labels.
-    $m = (int)ceil($n / $maxlabels);
-
-    # Process the data array, zapping M-1 of every M labels:
-    $k = 0;
-    for ($i = 0; $i < $n; $i++) {
-       if ($k > 0) $data[$i][0] = '';
-       if (++$k >= $m) $k = 0;
-    }
-}
diff --git a/gosa-core/include/phplot-5.1.2/contrib/prune_labels.test.php b/gosa-core/include/phplot-5.1.2/contrib/prune_labels.test.php
deleted file mode 100644 (file)
index 6d3bbb2..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-# PHPlot / contrib / prune_labels : Test
-# $Id: prune_labels.test.php,v 1.1 2009/12/09 03:45:57 lbayuk Exp $
-# Test driver for contrib / prune_labels
-
-require_once 'prune_labels.php';
-
-/* Testing the prune_labels function: */
-function test($count, $maxlabels)
-{
-    # Make an array of count records, like PHPlot uses, with labels:
-    $data = array();
-    for ($i = 0; $i < $count; $i++) {
-        $data[] = array("Row $i", $i, 100, 200, 300);
-    }
-
-    prune_labels($data, $maxlabels);
-
-    # See how many labels are non-blank now:
-    $line = '';
-    $non_blank = 0;
-    for ($i = 0; $i < $count; $i++) {
-        if (!empty($data[$i][0])) {
-            $non_blank++;
-            $line .= '*';
-        } else {
-            $line .= '_';
-        }
-    }
-    $status = ($non_blank <= $maxlabels) ? 'PASS' : 'FAIL';
-    echo "$status: $count rows, maxlabels=$maxlabels => $non_blank labels\n";
-    echo substr($line, 0, 80) . "\n";  # Only show first 80 chars.
-}
-
-/* Test cases for prune_labels */
-for ($n = 7; $n <= 1000; $n *= 2) test($n, 10);
-for ($g = 5; $g <= 40; $g++) test(72, $g);
-# Edge cases
-test(80, 41);
-test(80, 40);
-test(80, 39);
diff --git a/gosa-core/include/phplot-5.1.2/phplot.php b/gosa-core/include/phplot-5.1.2/phplot.php
deleted file mode 100644 (file)
index e914570..0000000
+++ /dev/null
@@ -1,5873 +0,0 @@
-<?php
-/* $Id: phplot.php,v 1.182 2010/06/30 00:39:08 lbayuk Exp $ */
-/*
- * PHPLOT Version 5.1.2
- *
- * A PHP class for creating scientific and business charts
- * Visit http://sourceforge.net/projects/phplot/
- * for PHPlot documentation, downloads, and discussions.
- * ---------------------------------------------------------------------
- * Copyright (C) 1998-2010 Afan Ottenheimer
- *
- * This 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;
- * version 2.1 of the License.
- *
- * This software 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 software; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * ---------------------------------------------------------------------
- *
- * Co-author and maintainer (2003-2005)
- * Miguel de Benito Delgado <nonick AT vodafone DOT es>
- *
- * Maintainer (2006-present)
- * <lbayuk AT users DOT sourceforge DOT net>
- *
- * Requires PHP 5.2.x or later. (PHP 4 is unsupported as of Jan 2008)
- */
-
-class PHPlot {
-
-    /* Declare class variables which are initialized to static values. Many more class variables
-     * are used, defined as needed, but are unset by default.
-     * All these are declared as public. While it is tempting to make them private or protected, this
-     * is avoided for two reasons. First, it will break existing code, since all member variables
-     * were public in PHP4 and who knows what internal variables people used. Second, it makes
-     * testing harder and less effective. Nevertheless, your code should not modify these.
-     */
-
-    public $is_inline = FALSE;             // FALSE = Sends headers, TRUE = sends just raw image data
-    public $browser_cache = FALSE;         // FALSE = Sends headers for browser to not cache the image,
-                                           // (only if is_inline = FALSE also)
-    public $print_image = TRUE;            // DrawGraph calls PrintImage. See SetPrintImage
-    public $background_done = FALSE;       // TRUE after background image is drawn once
-
-    public $safe_margin = 5;               // Extra margin used in several places, in pixels
-
-    public $x_axis_position = '';          // Where to draw both axis (world coordinates),
-    public $y_axis_position = '';          // leave blank for X axis at 0 and Y axis at left of plot.
-
-    public $xscale_type = 'linear';        // linear, log
-    public $yscale_type = 'linear';
-
-//Fonts
-    public $use_ttf  = FALSE;              // Use True Type Fonts by default?
-    public $ttf_path = '.';                // Default path to look in for TT Fonts.
-    public $default_ttfont = 'benjamingothic.ttf';
-    public $line_spacing = 4;              // Controls line spacing of multi-line labels
-
-    // Label angles: 0 or 90 degrees for fixed fonts, any for TTF
-    public $x_label_angle = 0;             // For X tick labels
-    // public $x_data_label_angle;         // For X data labels; defaults to x_label_angle - see CheckLabels()
-    public $y_label_angle = 0;             // For Y tick labels
-    public $y_data_label_angle = 0;        // For Y data labels
-
-//Formats
-    public $file_format = 'png';
-    public $output_file = '';              // For output to a file instead of stdout
-
-//Data
-    public $data_type = 'text-data';       // Structure of the data array 
-    public $plot_type= 'linepoints';       // bars, lines, linepoints, area, points, pie, thinbarline, squared
-
-    public $label_scale_position = 0.5;    // Shifts data labels in pie charts. 1 = top, 0 = bottom
-    public $group_frac_width = 0.7;        // Bars use this fraction (0 to 1) of a group's space
-    public $bar_extra_space = 0.5;         // Number of extra bar's worth of space in a group
-    public $bar_width_adjust = 1;          // 1 = bars of normal width, must be > 0
-
-// Titles
-    public $title_txt = '';
-
-    public $x_title_txt = '';
-    public $x_title_pos = 'none';          // plotdown, plotup, both, none
-
-    public $y_title_txt = '';
-    public $y_title_pos = 'none';          // plotleft, plotright, both, none
-
-
-//Labels
-    // There are two types of labels in PHPlot:
-    //    Tick labels: they follow the grid, next to ticks in axis.
-    //                 they are drawn at grid drawing time, by DrawXTicks() and DrawYTicks()
-    //    Data labels: they follow the data points, and can be placed on the axis or the plot (x/y)
-    //                 they are drawn at graph plotting time, by Draw*DataLabel(), called by DrawLines(), etc.
-    //                 Draw*DataLabel() also draws H/V lines to datapoints depending on draw_*_data_label_lines
-    // Tick Labels
-    // Tick and Data label positions are not initialized, because PHPlot needs to tell if they
-    // defaulted or are set by the user. See CheckLabels() for details. The variables and
-    // effective defaults are shown here in comments (but CheckLabels adjusts the defaults).
-    // public $x_tick_label_pos = 'plotdown';     // X tick label position 
-    // public $y_tick_label_pos = 'plotleft';     // Y tick label position
-    // public $x_data_label_pos = 'plotdown';     // X data label position
-    // public $y_data_label_pos = 'none';         // Y data label position
-
-    public $draw_x_data_label_lines = FALSE;   // Draw a line from the data point to the axis?
-
-    // Label format controls: (for tick, data and plot labels)
-    // Unset by default, these array members are used as needed for 'x' (x tick labels), 'xd' (x data
-    // labels), 'y' (y tick labels), and 'yd' (y data labels).
-    //    type, precision, prefix, suffix, time_format, printf_format, custom_callback, custom_arg.
-    // These replace the former: x_label_type, x_time_format, x_precision (similar for y), data_units_text.
-    public $label_format = array('x' => array(), 'xd' => array(), 'y' => array(), 'yd' => array());
-    // data_units_text is retained for backward compatibility, because there was never a function
-    // to set it. Use the 'suffix' argument to Set[XY]LabelType instead.
-    public $data_units_text = '';              // Units text for 'data' labels (i.e: '¤', '$', etc.)
-
-// Legend
-    public $legend = '';                       // An array with legend titles
-    // These variables are unset to take default values:
-    // public $legend_x_pos;                   // User-specified upper left coordinates of legend box
-    // public $legend_y_pos;
-    // public $legend_xy_world;                // If set, legend_x/y_pos are world coords, else pixel coords
-    // public $legend_text_align;              // left or right, Unset means right
-    // public $legend_colorbox_align;          // left, right, or none; Unset means same as text_align
-
-//Ticks
-    public $x_tick_length = 5;                 // tick length in pixels for upper/lower axis
-    public $y_tick_length = 5;                 // tick length in pixels for left/right axis
-
-    public $x_tick_cross = 3;                  // ticks cross x axis this many pixels
-    public $y_tick_cross = 3;                  // ticks cross y axis this many pixels
-
-    public $x_tick_pos = 'plotdown';           // plotdown, plotup, both, xaxis, none
-    public $y_tick_pos = 'plotleft';           // plotright, plotleft, both, yaxis, none
-
-    public $num_x_ticks = '';
-    public $num_y_ticks = '';
-
-    public $x_tick_inc = '';                   // Set num_x_ticks or x_tick_inc, not both.
-    public $y_tick_inc = '';                   // Set num_y_ticks or y_tick_inc, not both.
-
-    public $skip_top_tick = FALSE;
-    public $skip_bottom_tick = FALSE;
-    public $skip_left_tick = FALSE;
-    public $skip_right_tick = FALSE;
-
-//Grid Formatting
-    // public $draw_x_grid = FALSE;            // Default is False except for swapped data type
-    // public $draw_y_grid = TRUE;             // Default is True except for swapped data type
-
-    public $dashed_grid = TRUE;
-    public $grid_at_foreground = FALSE;        // Chooses whether to draw the grid below or above the graph
-
-//Colors and styles       (all colors can be array (R,G,B) or named color)
-    public $color_array = 'small';             // 'small', 'large' or array (define your own colors)
-                                            // See rgb.inc.php and SetRGBArray()
-    public $i_border = array(194, 194, 194);
-    public $plot_bg_color = 'white';
-    public $bg_color = 'white';
-    public $label_color = 'black';
-    public $text_color = 'black';
-    public $grid_color = 'black';
-    public $light_grid_color = 'gray';
-    public $tick_color = 'black';
-    public $title_color = 'black';
-    public $default_colors = array(       // The default colors for data and error bars
-        'SkyBlue', 'green', 'orange', 'blue', 'red', 'DarkGreen', 'purple', 'peru',
-        'cyan', 'salmon', 'SlateBlue', 'YellowGreen', 'magenta', 'aquamarine1', 'gold', 'violet');
-
-    // data_colors and error_bar_colors are initialized to default_colors by SetDefaultStyles.
-    // public $data_colors;                    // Data colors
-    // public $error_bar_colors;               // Error bar colors
-    // data_border_colors is initialized to black by SetDefaultStyles.
-    // public $data_border_colors;             // Data border colors
-
-    public $line_widths = 1;                  // single value or array
-    public $line_styles = array('solid', 'solid', 'dashed');   // single value or array
-    public $dashed_style = '2-4';              // colored dots-transparent dots
-
-    public $point_sizes = array(6);            // Array of sizes for points. See CheckPointParams()
-    public $point_shapes = array(              // Array of point shapes. See SetPointShapes() and DrawDot()
-          'diamond', 'dot', 'delta', 'home', 'yield', 'box', 'circle', 'up', 'down', 'cross'
-       );
-
-    public $error_bar_size = 5;                // right and left size of tee
-    public $error_bar_shape = 'tee';           // 'tee' or 'line'
-    public $error_bar_line_width = 1;          // single value (or array TODO)
-
-    public $plot_border_type = 'sides';        // left, right, top, bottom, sides, none, full; or array
-    public $image_border_type = 'none';        // 'raised', 'plain', 'none'
-    // public $image_border_width;             // NULL, 0, or unset for default. Default depends on type.
-
-    public $shading = 5;                       // 0 for no shading, > 0 is size of shadows in pixels
-
-    public $draw_plot_area_background = FALSE;
-    public $draw_broken_lines = FALSE;          // Tells not to draw lines for missing Y data.
-
-    public $data_colors_alpha = 0;              // Default alpha for data colors. See SetDataColors()
-
-
-//Miscellaneous
-    public $callbacks = array(                  // Valid callback reasons (see SetCallBack)
-        'draw_setup' => NULL,
-        'draw_image_background' => NULL,
-        'draw_plotarea_background' => NULL,
-        'draw_titles' => NULL,
-        'draw_axes' => NULL,
-        'draw_graph' => NULL,
-        'draw_border' => NULL,
-        'draw_legend' => NULL,
-        'draw_all' => NULL,
-        'debug_textbox' => NULL,  // For testing/debugging text box alignment
-        'debug_scale' => NULL,    // For testing/debugging scale setup
-    );
-
-
-//////////////////////////////////////////////////////
-//BEGIN CODE
-//////////////////////////////////////////////////////
-
-    /*!
-     * Constructor: Setup img resource, colors and size of the image, and font sizes.
-     *
-     * \param which_width       int    Image width in pixels.
-     * \param which_height      int    Image height in pixels.
-     * \param which_output_file string Filename for output.
-     * \param which_input_file  string Path to a file to be used as background.
-     */
-    function PHPlot($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
-    {
-        $this->SetRGBArray($this->color_array);
-
-        if ($which_output_file)
-            $this->SetOutputFile($which_output_file);
-
-        if ($which_input_file)
-            $this->SetInputFile($which_input_file);
-        else {
-            $this->image_width = $which_width;
-            $this->image_height = $which_height;
-
-            $this->img = ImageCreate($this->image_width, $this->image_height);
-            if (! $this->img)
-                return $this->PrintError('PHPlot(): Could not create image resource.');
-        }
-
-        $this->SetDefaultStyles();
-        $this->SetDefaultFonts();
-    }
-
-    /*!
-     * Reads an image file. Stores width and height, and returns the image
-     * resource. On error, calls PrintError and returns False.
-     * This is used by the constructor via SetInputFile, and by tile_img().
-     */
-    protected function GetImage($image_filename, &$width, &$height)
-    {
-        $error = '';
-        $size = getimagesize($image_filename);
-        if (!$size) {
-            $error = "Unable to query image file $image_filename";
-        } else {
-            $image_type = $size[2];
-            switch($image_type) {
-            case IMAGETYPE_GIF:
-                $img = @ ImageCreateFromGIF ($image_filename);
-                break;
-            case IMAGETYPE_PNG:
-                $img = @ ImageCreateFromPNG ($image_filename);
-                break;
-            case IMAGETYPE_JPEG:
-                $img = @ ImageCreateFromJPEG ($image_filename);
-                break;
-            default:
-                $error = "Unknown image type ($image_type) for image file $image_filename";
-                break;
-            }
-        }
-        if (empty($error) && !$img) {
-            # getimagesize is OK, but GD won't read it. Maybe unsupported format.
-            $error = "Failed to read image file $image_filename";
-        }
-        if (!empty($error)) {
-            return $this->PrintError("GetImage(): $error");
-        }
-        $width = $size[0];
-        $height = $size[1];
-        return $img;
-    }
-
-    /*!
-     * Selects an input file to be used as background for the whole graph.
-     * This resets the graph size to the image's size.
-     * Note: This is used by the constructor. It is deprecated for direct use.
-     */
-    function SetInputFile($which_input_file)
-    {
-        $im = $this->GetImage($which_input_file, $this->image_width, $this->image_height);
-        if (!$im)
-            return FALSE;  // GetImage already produced an error message.
-
-        // Deallocate any resources previously allocated
-        if (isset($this->img))
-            imagedestroy($this->img);
-
-        $this->img = $im;
-
-        // Do not overwrite the input file with the background color.
-        $this->background_done = TRUE;
-
-        return TRUE;
-    }
-
-/////////////////////////////////////////////
-//////////////                         COLORS
-/////////////////////////////////////////////
-
-    /* 
-     * Returns a GD color index value to a color specified as for SetRGBColor().
-     * This works with both palette and truecolor images.
-     *    $which_color : The color specification. See SetRGBColor for formats.
-     *    $alpha : Optional default Alpha value, if $which_color does not include alpha.
-     * Returns a GD color index, or NULL on error.
-     * Note: For palette images, this is an index into the color map.
-     * For truecolor images, this is a 32 bit value 0xAARRGGBB. But this difference
-     * is internal to GD.
-     */
-    function SetIndexColor($which_color, $alpha = 0)
-    {
-        list ($r, $g, $b, $a) = $this->SetRGBColor($which_color, $alpha);  //Translate to RGBA
-        if (!isset($r)) return NULL;
-        return ImageColorResolveAlpha($this->img, $r, $g, $b, $a);
-    }
-
-    /*
-     * Returns an index to a slightly darker color than the one requested.
-     * This works with both palette and truecolor images.
-     *    $which_color : The color specification. See SetRGBColor for formats.
-     *    $alpha : Optional default Alpha value, if $which_color does not include alpha.
-     * Returns a GD color index, or NULL on error.
-     */
-    protected function SetIndexDarkColor($which_color, $alpha = 0)
-    {
-        list ($r, $g, $b, $a) = $this->SetRGBColor($which_color, $alpha);
-        if (!isset($r)) return NULL;
-        $r = max(0, $r - 0x30);
-        $g = max(0, $g - 0x30);
-        $b = max(0, $b - 0x30);
-        return ImageColorResolveAlpha($this->img, $r, $g, $b, $a);
-    }
-
-    /*!
-     * Sets/reverts all colors and styles to their defaults.
-     */
-    protected function SetDefaultStyles()
-    {
-        /* Some of the Set*() functions use default values when they get no parameters. */
-        $this->SetDefaultDashedStyle($this->dashed_style);
-        $this->SetImageBorderColor($this->i_border);
-        $this->SetPlotBgColor($this->plot_bg_color);
-        $this->SetBackgroundColor($this->bg_color);
-        $this->SetLabelColor($this->label_color);
-        $this->SetTextColor($this->text_color);
-        $this->SetGridColor($this->grid_color);
-        $this->SetLightGridColor($this->light_grid_color);
-        $this->SetTickColor($this->tick_color);
-        $this->SetTitleColor($this->title_color);
-        $this->SetDataColors();
-        $this->SetErrorBarColors();
-        $this->SetDataBorderColors();
-        return TRUE;
-    }
-
-
-    /*
-     *
-     */
-    function SetBackgroundColor($which_color)
-    {
-        $this->bg_color= $which_color;
-        $this->ndx_bg_color= $this->SetIndexColor($this->bg_color);
-        return isset($this->ndx_bg_color);
-    }
-
-    /*
-     *
-     */
-    function SetPlotBgColor($which_color)
-    {
-        $this->plot_bg_color= $which_color;
-        $this->ndx_plot_bg_color= $this->SetIndexColor($this->plot_bg_color);
-        return isset($this->ndx_plot_bg_color);
-    }
-
-   /*
-    *
-    */
-    function SetTitleColor($which_color)
-    {
-        $this->title_color= $which_color;
-        $this->ndx_title_color= $this->SetIndexColor($this->title_color);
-        return isset($this->ndx_title_color);
-    }
-
-    /*
-     *
-     */
-    function SetTickColor ($which_color)
-    {
-        $this->tick_color= $which_color;
-        $this->ndx_tick_color= $this->SetIndexColor($this->tick_color);
-        return isset($this->ndx_tick_color);
-    }
-
-
-    /*
-     * Do not use. Use SetTitleColor instead.
-     */
-    function SetLabelColor ($which_color)
-    {
-        $this->label_color = $which_color;
-        $this->ndx_title_color= $this->SetIndexColor($this->label_color);
-        return isset($this->ndx_title_color);
-    }
-
-
-    /*
-     *
-     */
-    function SetTextColor ($which_color)
-    {
-        $this->text_color= $which_color;
-        $this->ndx_text_color= $this->SetIndexColor($this->text_color);
-        return isset($this->ndx_text_color);
-    }
-
-
-    /*
-     *
-     */
-    function SetLightGridColor ($which_color)
-    {
-        $this->light_grid_color= $which_color;
-        $this->ndx_light_grid_color= $this->SetIndexColor($this->light_grid_color);
-        return isset($this->ndx_light_grid_color);
-    }
-
-
-    /*
-     *
-     */
-    function SetGridColor ($which_color)
-    {
-        $this->grid_color = $which_color;
-        $this->ndx_grid_color= $this->SetIndexColor($this->grid_color);
-        return isset($this->ndx_grid_color);
-    }
-
-
-    /*
-     *
-     */
-    function SetImageBorderColor($which_color)
-    {
-        $this->i_border = $which_color;
-        $this->ndx_i_border = $this->SetIndexColor($this->i_border);
-        $this->ndx_i_border_dark = $this->SetIndexDarkColor($this->i_border);
-        return isset($this->ndx_i_border);
-    }
-
-
-    /*
-     *
-     */
-    function SetTransparentColor($which_color)
-    {
-        $ndx = $this->SetIndexColor($which_color);
-        if (!isset($ndx))
-            return FALSE;
-        ImageColorTransparent($this->img, $ndx);
-        return TRUE;
-    }
-
-
-    /*!
-     * Sets the array of colors to be used. It can be user defined, a small predefined one
-     * or a large one included from 'rgb.inc.php'.
-     *
-     * \param which_color_array If an array, the used as color array. If a string can
-     *        be one of 'small' or 'large'.
-     */
-    function SetRGBArray ($which_color_array)
-    {
-        if ( is_array($which_color_array) ) {           // User defined array
-            $this->rgb_array = $which_color_array;
-            return TRUE;
-        } elseif ($which_color_array == 'small') {      // Small predefined color array
-            $this->rgb_array = array(
-                'white'          => array(255, 255, 255),
-                'snow'           => array(255, 250, 250),
-                'PeachPuff'      => array(255, 218, 185),
-                'ivory'          => array(255, 255, 240),
-                'lavender'       => array(230, 230, 250),
-                'black'          => array(  0,   0,   0),
-                'DimGrey'        => array(105, 105, 105),
-                'gray'           => array(190, 190, 190),
-                'grey'           => array(190, 190, 190),
-                'navy'           => array(  0,   0, 128),
-                'SlateBlue'      => array(106,  90, 205),
-                'blue'           => array(  0,   0, 255),
-                'SkyBlue'        => array(135, 206, 235),
-                'cyan'           => array(  0, 255, 255),
-                'DarkGreen'      => array(  0, 100,   0),
-                'green'          => array(  0, 255,   0),
-                'YellowGreen'    => array(154, 205,  50),
-                'yellow'         => array(255, 255,   0),
-                'orange'         => array(255, 165,   0),
-                'gold'           => array(255, 215,   0),
-                'peru'           => array(205, 133,  63),
-                'beige'          => array(245, 245, 220),
-                'wheat'          => array(245, 222, 179),
-                'tan'            => array(210, 180, 140),
-                'brown'          => array(165,  42,  42),
-                'salmon'         => array(250, 128, 114),
-                'red'            => array(255,   0,   0),
-                'pink'           => array(255, 192, 203),
-                'maroon'         => array(176,  48,  96),
-                'magenta'        => array(255,   0, 255),
-                'violet'         => array(238, 130, 238),
-                'plum'           => array(221, 160, 221),
-                'orchid'         => array(218, 112, 214),
-                'purple'         => array(160,  32, 240),
-                'azure1'         => array(240, 255, 255),
-                'aquamarine1'    => array(127, 255, 212)
-                );
-            return TRUE;
-        } elseif ($which_color_array === 'large')  {    // Large color array
-            if (!@include('rgb.inc.php')) {
-                return $this->PrintError("SetRGBArray(): Large color map could not be loaded\n"
-                                       . "from 'rgb.inc.php'.");
-            }
-            $this->rgb_array = $ColorArray;
-        } else {                                        // Default to black and white only.
-            $this->rgb_array = array('white' => array(255, 255, 255), 'black' => array(0, 0, 0));
-        }
-
-        return TRUE;
-    }
-
-    /*
-     * Parse a color description and return the color component values.
-     * Arguments:
-     *   $color_asked : The desired color description, in one of these forms:
-     *       Component notation: array(R, G, B) or array(R, G, B, A) with each
-     *          in the range described below for the return value.
-     *          Examples: (255,255,0)  (204,0,0,30)
-     *       Hex notation: "#RRGGBB" or "#RRGGBBAA" where each pair is a 2 digit hex number.
-     *          Examples: #FF00FF (magenta)   #0000FF40 (Blue with alpha=64/127)
-     *       Named color in the current colormap, with optional suffix ":alpha" for alpha value.
-     *          Examples:  blue   red:60  yellow:20
-     *   $alpha : optional default alpha value. This is applied to the color if it doesn't
-     *       already have an alpha value. If not supplied, colors are opaque (alpha=0) by default.
-     *
-     * Returns an array describing a color as (R, G, B, Alpha).
-     * R, G, and B are integers 0-255, and Alpha is 0 (opaque) to 127 (transparent).
-     */
-    function SetRGBColor($color_asked, $alpha = 0)
-    {
-        if (empty($color_asked)) {
-            $ret_val = array(0, 0, 0);
-
-        } elseif (is_array($color_asked) && (($n = count($color_asked)) == 3 || $n == 4) ) {
-            // Already an array of 3 or 4 elements:
-            $ret_val = $color_asked;
-
-        } elseif (preg_match('/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i',
-                             $color_asked, $ss)) {
-            // #RRGGBB or #RRGGBBAA notation:
-            $ret_val = array(hexdec($ss[1]), hexdec($ss[2]), hexdec($ss[3]));
-            if (isset($ss[4])) $ret_val[] = hexdec($ss[4]);
-
-        } elseif (isset($this->rgb_array[$color_asked])) {
-            // Color by name:
-            $ret_val = $this->rgb_array[$color_asked];
-
-        } elseif (preg_match('/(.+):([\d]+)$/', $color_asked, $ss)
-                  && isset($this->rgb_array[$ss[1]])) {
-            // Color by name with ":alpha" suffix, alpha is a decimal number:
-            $ret_val = $this->rgb_array[$ss[1]];
-            $ret_val[3] = (int)$ss[2];
-
-        } else {
-            return $this->PrintError("SetRGBColor(): Color '$color_asked' is not valid.");
-        }
-
-        // Append alpha if not already provided for:
-        if (count($ret_val) == 3)
-            $ret_val[] = $alpha;
-        return $ret_val;
-    }
-
-    /*!
-     * Sets the colors for the data, with optional default alpha value (for PHPlot_truecolor only)
-     * Cases are:
-     *    SetDataColors(array(...))  : Use the supplied array as the color map.
-     *    SetDataColors(colorname)   : Use an array of just colorname as the color map.
-     *    SetDataColors() or SetDataColors(NULL) : Load default color map if no color map is already set.
-     *    SetDataColors('') or SetDataColors(False) : Load default color map (even if one is already set).
-     */
-    function SetDataColors($which_data = NULL, $which_border = NULL, $alpha = NULL)
-    {
-        if (is_array($which_data)) {
-            $this->data_colors = $which_data;  // Use supplied array
-        } elseif (!empty($which_data)) {
-            $this->data_colors = array($which_data);  // Use supplied single color
-        } elseif (empty($this->data_colors) || !is_null($which_data)) {
-            $this->data_colors = $this->default_colors;  // Use default color array
-        } // Else do nothing: which_data is NULL or missing and a color array is already set.
-
-        // If an alpha value is supplied, use it as the new default. Need to save and restore
-        // this because the color indexes will be regenerated when the arrays are padded.
-        if (!empty($alpha))
-            $this->data_colors_alpha = $alpha;
-
-        $i = 0;
-        foreach ($this->data_colors as $col) {
-            $ndx = $this->SetIndexColor($col, $this->data_colors_alpha);
-            if (!isset($ndx))
-                return FALSE;
-            $this->ndx_data_colors[$i] = $ndx;
-            $this->ndx_data_dark_colors[$i] = $this->SetIndexDarkColor($col, $this->data_colors_alpha);
-            $i++;
-        }
-
-        // For past compatibility:
-        return $this->SetDataBorderColors($which_border);
-    } // function SetDataColors()
-
-
-    /*!
-     * Set the colors for the bars and stacked bars outlines.
-     * Argument usage is similar to SetDataColors(), except the default is just black.
-     */
-    function SetDataBorderColors($which_br = NULL)
-    {
-        if (is_array($which_br)) {
-            $this->data_border_colors = $which_br; // Use supplied array
-        } elseif (!empty($which_br)) {
-            $this->data_border_colors = array($which_br);  // Use supplied single color
-        } elseif (empty($this->data_border_colors) || !is_null($which_br)) {
-            $this->data_border_colors = array('black'); // Use default
-        } // Else do nothing: which_br is NULL or missing and a color array is already set.
-
-        $i = 0;
-        foreach($this->data_border_colors as $col) {
-            $ndx = $this->SetIndexColor($col);
-            if (!isset($ndx))
-                return FALSE;
-            $this->ndx_data_border_colors[$i] = $ndx;
-            $i++;
-        }
-        return TRUE;
-    } // function SetDataBorderColors()
-
-
-    /*!
-     * Sets the colors for the data error bars.
-     * Argument usage is the same as SetDataColors().
-     */
-    function SetErrorBarColors($which_err = NULL)
-    {
-        if (is_array($which_err)) {
-            $this->error_bar_colors = $which_err;  // Use supplied array
-        } elseif (!empty($which_err)) {
-            $this->error_bar_colors = array($which_err);  // Use supplied single color
-        } elseif (empty($this->error_bar_colors) || !is_null($which_err)) {
-            $this->error_bar_colors = $this->default_colors;  // Use default color array
-        } // Else do nothing: which_err is NULL or missing and a color array is already set.
-
-        $i = 0;
-        foreach($this->error_bar_colors as $col) {
-            $ndx = $this->SetIndexColor($col);
-            if (!isset($ndx))
-                return FALSE;
-            $this->ndx_error_bar_colors[$i] = $ndx;
-            $i++;
-        }
-        return TRUE;
-    } // function SetErrorBarColors()
-
-
-    /*!
-     * Sets the default dashed style.
-     *  \param which_style A string specifying order of colored and transparent dots,
-     *         i.e: '4-3' means 4 colored, 3 transparent;
-     *              '2-3-1-2' means 2 colored, 3 transparent, 1 colored, 2 transparent.
-     */
-    function SetDefaultDashedStyle($which_style)
-    {
-        // String: "numcol-numtrans-numcol-numtrans..."
-        $asked = explode('-', $which_style);
-
-        if (count($asked) < 2) {
-            return $this->PrintError("SetDefaultDashedStyle(): Wrong parameter '$which_style'.");
-        }
-
-        // Build the string to be eval()uated later by SetDashedStyle()
-        $this->default_dashed_style = 'array( ';
-
-        $t = 0;
-        foreach($asked as $s) {
-            if ($t % 2 == 0) {
-                $this->default_dashed_style .= str_repeat('$which_ndxcol,', $s);
-            } else {
-                $this->default_dashed_style .= str_repeat('IMG_COLOR_TRANSPARENT,', $s);
-            }
-            $t++;
-        }
-        // Remove trailing comma and add closing parenthesis
-        $this->default_dashed_style = substr($this->default_dashed_style, 0, -1);
-        $this->default_dashed_style .= ')';
-
-        return TRUE;
-    }
-
-
-    /*!
-     * Sets the style before drawing a dashed line. Defaults to $this->default_dashed_style
-     *   \param which_ndxcol Color index to be used.
-     */
-    protected function SetDashedStyle($which_ndxcol)
-    {
-        // See SetDefaultDashedStyle() to understand this.
-        eval ("\$style = $this->default_dashed_style;");
-        return imagesetstyle($this->img, $style);
-    }
-
-
-    /*!
-     * Sets line widths on a per-line basis.
-     */
-    function SetLineWidths($which_lw=NULL)
-    {
-        if (is_null($which_lw)) {
-            // Do nothing, use default value.
-        } else if (is_array($which_lw)) {
-            // Did we get an array with line widths?
-            $this->line_widths = $which_lw;
-        } else {
-            $this->line_widths = array($which_lw);
-        }
-        return TRUE;
-    }
-
-    /*!
-     *
-     */
-    function SetLineStyles($which_ls=NULL)
-    {
-        if (is_null($which_ls)) {
-            // Do nothing, use default value.
-        } else if ( is_array($which_ls)) {
-            // Did we get an array with line styles?
-            $this->line_styles = $which_ls;
-        } else {
-            $this->line_styles = ($which_ls) ? array($which_ls) : array('solid');
-        }
-        return TRUE;
-    }
-
-
-/////////////////////////////////////////////
-//////////////                 TEXT and FONTS
-/////////////////////////////////////////////
-
-
-    /*!
-     * Controls the line spacing of multi-line labels.
-     * For GD text, this is the number of pixels between lines.
-     * For TTF text, it controls line spacing in proportion to the normal
-     * spacing defined by the font.
-     */
-    function SetLineSpacing($which_spc)
-    {
-        $this->line_spacing = $which_spc;
-        return TRUE;
-    }
-
-
-    /*!
-     * Select the default font type to use.
-     *   $which_ttf : True to default to TrueType, False to default to GD (fixed) fonts.
-     * This also resets all font settings to the defaults.
-     */
-    function SetUseTTF($which_ttf)
-    {
-        $this->use_ttf = $which_ttf;
-        return $this->SetDefaultFonts();
-    }
-
-    /*!
-     * Sets the directory name to look into for TrueType fonts.
-     */
-    function SetTTFPath($which_path)
-    {
-        // Maybe someone needs really dynamic config. He'll need this:
-        // clearstatcache();
-
-        if (is_dir($which_path) && is_readable($which_path)) {
-            $this->ttf_path = $which_path;
-            return TRUE;
-        }
-        return $this->PrintError("SetTTFPath(): $which_path is not a valid path.");
-    }
-
-    /*!
-     * Sets the default TrueType font and updates all fonts to that.
-     * The default font might be a full path, or relative to the TTFPath,
-     * so let SetFont check that it exists.
-     * Side effects: Enables use of TrueType fonts as the default font type,
-     * and resets all font settings.
-     */
-    function SetDefaultTTFont($which_font)
-    {
-        $this->default_ttfont = $which_font;
-        return $this->SetUseTTF(TRUE);
-    }
-
-    /*!
-     * Sets fonts to their defaults
-     */
-    protected function SetDefaultFonts()
-    {
-        // TTF:
-        if ($this->use_ttf) {
-            return $this->SetFont('generic', '', 8)
-                && $this->SetFont('title', '', 14)
-                && $this->SetFont('legend', '', 8)
-                && $this->SetFont('x_label', '', 6)
-                && $this->SetFont('y_label', '', 6)
-                && $this->SetFont('x_title', '', 10)
-                && $this->SetFont('y_title', '', 10);
-        }
-        // Fixed GD Fonts:
-        return $this->SetFont('generic', 2)
-            && $this->SetFont('title', 5)
-            && $this->SetFont('legend', 2)
-            && $this->SetFont('x_label', 1)
-            && $this->SetFont('y_label', 1)
-            && $this->SetFont('x_title', 3)
-            && $this->SetFont('y_title', 3);
-    }
-
-    /*
-     * Select a fixed (GD) font for an element.
-     * This allows using a fixed font, even with SetUseTTF(True).
-     *    $which_elem : The element whose font is to be changed.
-     *       One of: title legend generic x_label y_label x_title y_title
-     *    $which_font : A GD font number 1-5
-     *    $which_spacing (optional) : Line spacing factor
-     */
-    function SetFontGD($which_elem, $which_font, $which_spacing = NULL)
-    {
-        if ($which_font < 1 || 5 < $which_font) {
-            return $this->PrintError(__FUNCTION__ . ': Font size must be 1, 2, 3, 4 or 5');
-        }
-        if (!$this->CheckOption($which_elem,
-                                'generic, title, legend, x_label, y_label, x_title, y_title',
-                                __FUNCTION__)) {
-            return FALSE;
-        }
-
-        # Store the font parameters: name/size, char cell height and width.
-        $this->fonts[$which_elem] = array('ttf' => FALSE,
-                                          'font' => $which_font,
-                                          'height' => ImageFontHeight($which_font),
-                                          'width' => ImageFontWidth($which_font),
-                                          'line_spacing' => $which_spacing);
-        return TRUE;
-    }
-
-    /*
-     * Select a TrueType font for an element.
-     * This allows using a TrueType font, even with SetUseTTF(False).
-     *    $which_elem : The element whose font is to be changed.
-     *       One of: title legend generic x_label y_label x_title y_title
-     *    $which_font : A TrueType font filename or pathname.
-     *    $which_size : Font point size.
-     *    $which_spacing (optional) : Line spacing factor
-     */
-    function SetFontTTF($which_elem, $which_font, $which_size = 12, $which_spacing = NULL)
-    {
-        if (!$this->CheckOption($which_elem,
-                                'generic, title, legend, x_label, y_label, x_title, y_title',
-                                __FUNCTION__)) {
-            return FALSE;
-        }
-
-        # Empty font name means use the default font.
-        if (empty($which_font))
-            $which_font = $this->default_ttfont;
-        $path = $which_font;
-
-        # First try the font name directly, if not then try with path.
-        if (!is_file($path) || !is_readable($path)) {
-            $path = $this->ttf_path . DIRECTORY_SEPARATOR . $which_font;
-            if (!is_file($path) || !is_readable($path)) {
-                return $this->PrintError(__FUNCTION__ . ": Can't find TrueType font $which_font");
-            }
-        }
-
-        # Calculate the font height and inherent line spacing. TrueType fonts have this information
-        # internally, but PHP/GD has no way to directly access it. So get the bounding box size of
-        # an upper-case character without descenders, and the baseline-to-baseline height.
-        # Note: In practice, $which_size = $height, maybe +/-1 . But which_size is in points,
-        # and height is in pixels, and someday GD may be able to tell the difference.
-        # The character width is saved too, but not used by the normal text drawing routines - it
-        # isn't necessarily a fixed-space font. It is used in DrawLegend.
-        $bbox = ImageTTFBBox($which_size, 0, $path, "E");
-        $height = $bbox[1] - $bbox[5];
-        $width = $bbox[2] - $bbox[0];
-        $bbox = ImageTTFBBox($which_size, 0, $path, "E\nE");
-        $spacing = $bbox[1] - $bbox[5] - 2 * $height;
-
-        # Store the font parameters:
-        $this->fonts[$which_elem] = array('ttf' => TRUE,
-                                          'font' => $path,
-                                          'size' => $which_size,
-                                          'height' => $height,
-                                          'width' => $width,
-                                          'spacing' => $spacing,
-                                          'line_spacing' => $which_spacing);
-        return TRUE;
-    }
-
-
-    /*
-     * Select Fixed/TrueType font for an element. Which type of font is
-     * selected depends on the $use_ttf class variable (see SetUseTTF()).
-     * Before PHPlot supported mixing font types, only this function and
-     * SetUseTTF were available to select an overall font type, but now
-     * SetFontGD() and SetFontTTF() can be used for mixing font types.
-     *    $which_elem : The element whose font is to be changed.
-     *       One of: title legend generic x_label y_label x_title y_title
-     *    $which_font : A number 1-5 for fixed fonts, or a TrueType font.
-     *    $which_size : Ignored for Fixed fonts, point size for TrueType.
-     *    $which_spacing (optional) : Line spacing factor
-     */
-    function SetFont($which_elem, $which_font, $which_size = 12, $line_spacing = NULL)
-    {
-        if ($this->use_ttf)
-            return $this->SetFontTTF($which_elem, $which_font, $which_size, $line_spacing);
-        return $this->SetFontGD($which_elem, $which_font, $line_spacing);
-    }
-
-    /*
-     * Return the inter-line spacing for a font.
-     * This is an internal function, used by ProcessText* and DrawLegend.
-     *   $font : A font array variable.
-     * Returns: Spacing, in pixels, between text lines.
-     */
-    protected function GetLineSpacing($font)
-    {
-        # Use the per-font line spacing preference, if set, else the global value:
-        if (isset($font['line_spacing']))
-            $line_spacing = $font['line_spacing'];
-        else
-            $line_spacing = $this->line_spacing;
-
-        # For GD fonts, that is the spacing in pixels.
-        # For TTF, adjust based on the 'natural' font spacing (see SetFontTTF):
-        if ($font['ttf']) {
-            $line_spacing = (int)($line_spacing * $font['spacing'] / 6.0);
-        }
-        return $line_spacing;
-    }
-
-    /*!
-     * Text drawing and sizing functions:
-     * ProcessText is meant for use only by DrawText and SizeText.
-     *    ProcessText(True, ...)  - Draw a block of text
-     *    ProcessText(False, ...) - Just return ($width, $height) of
-     *       the orthogonal bounding box containing the text.
-     * ProcessText is further split into separate functions for GD and TTF
-     * text, due to the size of the code.
-     *
-     * Horizontal and vertical alignment are relative to the drawing. That is:
-     * vertical text (90 deg) gets centered along Y position with
-     * v_align = 'center', and adjusted to the right of X position with
-     * h_align = 'right'.  Another way to look at this is to say
-     * that text rotation happens first, then alignment.
-     *
-     * Original multiple lines code submitted by Remi Ricard.
-     * Original vertical code submitted by Marlin Viss.
-     *
-     * Text routines rewritten by ljb to fix alignment and position problems.
-     * Here is my explanation and notes. More information and pictures will be
-     * placed in the PHPlot Reference Manual.
-     *
-     *    + Process TTF text one line at a time, not as a block. (See below)
-     *    + Flipped top vs bottom vertical alignment. The usual interpretation
-     *  is: bottom align means bottom of the text is at the specified Y
-     *  coordinate. For some reason, PHPlot did left/right the correct way,
-     *  but had top/bottom reversed. I fixed it, and left the default valign
-     *  argument as bottom, but the meaning of the default value changed.
-     *
-     *    For GD font text, only single-line text is handled by GD, and the
-     *  basepoint is the upper left corner of each text line.
-     *    For TTF text, multi-line text could be handled by GD, with the text
-     *  basepoint at the lower left corner of the first line of text.
-     *  (Behavior of TTF drawing routines on multi-line text is not documented.)
-     *  But you cannot do left/center/right alignment on each line that way,
-     *  or proper line spacing.
-     *    Therefore, for either text type, we have to break up the text into
-     *  lines and position each line independently.
-     *
-     *    There are 9 alignment modes: Horizontal = left, center, or right, and
-     *  Vertical = top, center, or bottom. Alignment is interpreted relative to
-     *  the image, not as the text is read. This makes sense when you consider
-     *  for example X axis labels. They need to be centered below the marks
-     *  (center, top alignment) regardless of the text angle.
-     *  'Bottom' alignment really means baseline alignment.
-     *
-     *    GD font text is supported (by libgd) at 0 degrees and 90 degrees only.
-     *  Multi-line or single line text works with any of the 9 alignment modes.
-     *
-     *    TTF text can be at any angle. The 9 alignment modes work for all angles,
-     *  but the results might not be what you expect for multi-line text. See
-     *  the PHPlot Reference Manual for pictures and details. In short, alignment
-     *  applies to the orthogonal (aligned with X and Y axes) bounding box that
-     *  contains the text, and to each line in the multi-line text box. Since
-     *  alignment is relative to the image, 45 degree multi-line text aligns
-     *  differently from 46 degree text.
-     *
-     *    Note that PHPlot allows multi-line text for the 3 titles, and they
-     *  are only drawn at 0 degrees (main and X titles) or 90 degrees (Y title).
-     *  Data labels can also be multi-line, and they can be drawn at any angle.
-     *  -ljb 2007-11-03
-     *
-     */
-
-    /*
-     * ProcessTextGD() - Draw or size GD fixed-font text.
-     * This is intended for use only by ProcessText().
-     *    $draw_it : True to draw the text, False to just return the orthogonal width and height.
-     *    $font : PHPlot font array (with 'ttf' = False) - see SetFontGD()
-     *    $angle : Text angle in degrees. GD only supports 0 and 90. We treat >= 45 as 90, else 0.
-     *    $x, $y : Reference point for the text (ignored if !$draw_it)
-     *    $color : GD color index to use for drawing the text (ignored if !$draw_it)
-     *    $text : The text to draw or size. Put a newline between lines.
-     *    $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it)
-     *    $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it)
-     * Returns: True, if drawing text, or an array of ($width, $height) if not.
-     */
-    protected function ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor)
-    {
-        # Extract font parameters:
-        $font_number = $font['font'];
-        $font_width = $font['width'];
-        $font_height = $font['height'];
-        $line_spacing = $this->GetLineSpacing($font);
-
-        # Break up the text into lines, trim whitespace, find longest line.
-        # Save the lines and length for drawing below.
-        $longest = 0;
-        foreach (explode("\n", $text) as $each_line) {
-            $lines[] = $line = trim($each_line);
-            $line_lens[] = $line_len = strlen($line);
-            if ($line_len > $longest) $longest = $line_len;
-        }
-        $n_lines = count($lines);
-
-        # Width, height are based on font size and longest line, line count respectively.
-        # These are relative to the text angle.
-        $total_width = $longest * $font_width;
-        $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing;
-
-        if (!$draw_it) {
-            if ($angle < 45) return array($total_width, $total_height);
-            return array($total_height, $total_width);
-        }
-
-        $interline_step = $font_height + $line_spacing; // Line-to-line step
-
-        if ($angle >= 45) {
-            // Vertical text (90 degrees):
-            // (Remember the alignment convention with vertical text)
-            // For 90 degree text, alignment factors change like this:
-            $temp = $v_factor;
-            $v_factor = $h_factor;
-            $h_factor = 1 - $temp;
-
-            $draw_func = 'ImageStringUp';
-
-            // Rotation matrix "R" for 90 degrees (with Y pointing down):
-            $r00 = 0;  $r01 = 1;
-            $r10 = -1; $r11 = 0;
-
-        } else {
-            // Horizontal text (0 degrees):
-            $draw_func = 'ImageString';
-
-            // Rotation matrix "R" for 0 degrees:
-            $r00 = 1; $r01 = 0;
-            $r10 = 0; $r11 = 1;
-        }
-
-        // Adjust for vertical alignment (horizontal text) or horizontal alignment (vertical text):
-        $factor = (int)($total_height * $v_factor);
-        $xpos = $x - $r01 * $factor;
-        $ypos = $y - $r11 * $factor;
-
-        # Debug callback provides the bounding box:
-        if ($this->GetCallback('debug_textbox')) {
-            if ($angle >= 45) {
-                $bbox_width  = $total_height;
-                $bbox_height = $total_width;
-                $px = $xpos;
-                $py = $ypos - (1 - $h_factor) * $total_width;
-            } else {
-                $bbox_width  = $total_width;
-                $bbox_height = $total_height;
-                $px = $xpos - $h_factor * $total_width;
-                $py = $ypos;
-            }
-            $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height);
-        }
-
-        for ($i = 0; $i < $n_lines; $i++) {
-
-            // Adjust for alignment of this line within the text block:
-            $factor = (int)($line_lens[$i] * $font_width * $h_factor);
-            $x = $xpos - $r00 * $factor;
-            $y = $ypos - $r10 * $factor;
-
-            // Call ImageString or ImageStringUp:
-            $draw_func($this->img, $font_number, $x, $y, $lines[$i], $color);
-
-            // Step to the next line of text. This is a rotation of (x=0, y=interline_spacing)
-            $xpos += $r01 * $interline_step;
-            $ypos += $r11 * $interline_step;
-        }
-        return TRUE;
-    }
-
-
-    /*
-     * ProcessTextTTF() - Draw or size TTF text.
-     * This is intended for use only by ProcessText().
-     *    $draw_it : True to draw the text, False to just return the orthogonal width and height.
-     *    $font : PHPlot font array (with 'ttf' = True) - see SetFontTTF()
-     *    $angle : Text angle in degrees.
-     *    $x, $y : Reference point for the text (ignored if !$draw_it)
-     *    $color : GD color index to use for drawing the text (ignored if !$draw_it)
-     *    $text : The text to draw or size. Put a newline between lines.
-     *    $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it)
-     *    $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it)
-     * Returns: True, if drawing text, or an array of ($width, $height) if not.
-     */
-    protected function ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor)
-    {
-        # Extract font parameters (see SetFontTTF):
-        $font_file = $font['font'];
-        $font_size = $font['size'];
-        $font_height = $font['height'];
-        $line_spacing = $this->GetLineSpacing($font);
-
-        # Break up the text into lines, trim whitespace.
-        # Calculate the total width and height of the text box at 0 degrees.
-        # Save the trimmed lines and their widths for later when drawing.
-        # To get uniform spacing, don't use the actual line heights.
-        # Total height = Font-specific line heights plus inter-line spacing.
-        # Total width = width of widest line.
-        # Last Line Descent is the offset from the bottom to the text baseline.
-        # Note: For some reason, ImageTTFBBox uses (-1,-1) as the reference point.
-        #   So 1+bbox[1] is the baseline to bottom distance.
-        $total_width = 0;
-        $lastline_descent = 0;
-        foreach (explode("\n", $text) as $each_line) {
-            $lines[] = $line = trim($each_line);
-            $bbox = ImageTTFBBox($font_size, 0, $font_file, $line);
-            $line_widths[] = $width = $bbox[2] - $bbox[0];
-            if ($width > $total_width) $total_width = $width;
-            $lastline_descent = 1 + $bbox[1];
-        }
-        $n_lines = count($lines);
-        $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing;
-
-        # Calculate the rotation matrix for the text's angle. Remember that GD points Y down,
-        # so the sin() terms change sign.
-        $theta = deg2rad($angle);
-        $cos_t = cos($theta);
-        $sin_t = sin($theta);
-        $r00 = $cos_t;    $r01 = $sin_t;
-        $r10 = -$sin_t;   $r11 = $cos_t;
-
-        # Make a bounding box of the right size, with upper left corner at (0,0).
-        # By convention, the point order is: LL, LR, UR, UL.
-        # Note this is still working with the text at 0 degrees.
-        # When sizing text (SizeText), use the overall size with descenders.
-        #   This tells the caller how much room to leave for the text.
-        # When drawing text (DrawText), use the size without descenders - that
-        #   is, down to the baseline. This is for accurate positioning.
-        $b[0] = 0;
-        if ($draw_it) {
-            $b[1] = $total_height;
-        } else {
-            $b[1] = $total_height + $lastline_descent;
-        }
-        $b[2] = $total_width;  $b[3] = $b[1];
-        $b[4] = $total_width;  $b[5] = 0;
-        $b[6] = 0;             $b[7] = 0;
-
-        # Rotate the bounding box, then offset to the reference point:
-        for ($i = 0; $i < 8; $i += 2) {
-            $x_b = $b[$i];
-            $y_b = $b[$i+1];
-            $c[$i]   = $x + $r00 * $x_b + $r01 * $y_b;
-            $c[$i+1] = $y + $r10 * $x_b + $r11 * $y_b;
-        }
-
-        # Get an orthogonal (aligned with X and Y axes) bounding box around it, by
-        # finding the min and max X and Y:
-        $bbox_ref_x = $bbox_max_x = $c[0];
-        $bbox_ref_y = $bbox_max_y = $c[1];
-        for ($i = 2; $i < 8; $i += 2) {
-            $x_b = $c[$i];
-            if ($x_b < $bbox_ref_x) $bbox_ref_x = $x_b;
-            elseif ($bbox_max_x < $x_b) $bbox_max_x = $x_b;
-            $y_b = $c[$i+1];
-            if ($y_b < $bbox_ref_y) $bbox_ref_y = $y_b;
-            elseif ($bbox_max_y < $y_b) $bbox_max_y = $y_b;
-        }
-        $bbox_width = $bbox_max_x - $bbox_ref_x;
-        $bbox_height = $bbox_max_y - $bbox_ref_y;
-
-        if (!$draw_it) {
-            # Return the bounding box, rounded up (so it always contains the text):
-            return array((int)ceil($bbox_width), (int)ceil($bbox_height));
-        }
-
-        $interline_step = $font_height + $line_spacing; // Line-to-line step
-
-        # Calculate the offsets from the supplied reference point to the
-        # upper-left corner of the text.
-        # Start at the reference point at the upper left corner of the bounding
-        # box (bbox_ref_x, bbox_ref_y) then adjust it for the 9 point alignment.
-        # h,v_factor are 0,0 for top,left, .5,.5 for center,center, 1,1 for bottom,right.
-        #    $off_x = $bbox_ref_x + $bbox_width * $h_factor - $x;
-        #    $off_y = $bbox_ref_y + $bbox_height * $v_factor - $y;
-        # Then use that offset to calculate back to the supplied reference point x, y
-        # to get the text base point.
-        #    $qx = $x - $off_x;
-        #    $qy = $y - $off_y;
-        # Reduces to:
-        $qx = 2 * $x - $bbox_ref_x - $bbox_width * $h_factor;
-        $qy = 2 * $y - $bbox_ref_y - $bbox_height * $v_factor;
-
-        # Check for debug callback. Don't calculate bounding box unless it is wanted.
-        if ($this->GetCallback('debug_textbox')) {
-            # Calculate the orthogonal bounding box coordinates for debug testing.
-
-            # qx, qy is upper left corner relative to the text.
-            # Calculate px,py: upper left corner (absolute) of the bounding box.
-            # There are 4 equation sets for this, depending on the quadrant:
-            if ($sin_t > 0) {
-                if ($cos_t > 0) {
-                    # Quadrant: 0d - 90d:
-                    $px = $qx; $py = $qy - $total_width * $sin_t;
-                } else {
-                    # Quadrant: 90d - 180d:
-                   $px = $qx + $total_width * $cos_t; $py = $qy - $bbox_height;
-                }
-            } else {
-                if ($cos_t < 0) {
-                    # Quadrant: 180d - 270d:
-                    $px = $qx - $bbox_width; $py = $qy + $total_height * $cos_t;
-                } else {
-                    # Quadrant: 270d - 360d:
-                    $px = $qx + $total_height * $sin_t; $py = $qy;
-                }
-            }
-            $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height);
-        }
-
-        # Since alignment is applied after rotation, which parameter is used
-        # to control alignment of each line within the text box varies with
-        # the angle.
-        #   Angle (degrees):       Line alignment controlled by:
-        #  -45 < angle <= 45          h_align
-        #   45 < angle <= 135         reversed v_align
-        #  135 < angle <= 225         reversed h_align
-        #  225 < angle <= 315         v_align
-        if ($cos_t >= $sin_t) {
-            if ($cos_t >= -$sin_t) $line_align_factor = $h_factor;
-            else $line_align_factor = $v_factor;
-        } else {
-            if ($cos_t >= -$sin_t) $line_align_factor = 1-$v_factor;
-            else $line_align_factor = 1-$h_factor;
-        }
-
-        # Now we have the start point, spacing and in-line alignment factor.
-        # We are finally ready to start drawing the text, line by line.
-        for ($i = 0; $i < $n_lines; $i++) {
-
-            # For drawing TTF text, the reference point is the left edge of the
-            # text baseline (not the lower left corner of the bounding box).
-            # The following also adjusts for horizontal (relative to
-            # the text) alignment of the current line within the box.
-            # What is happening is rotation of this vector by the text angle:
-            #    (x = (total_width - line_width) * factor, y = font_height)
-
-            $width_factor = ($total_width - $line_widths[$i]) * $line_align_factor;
-            $rx = $qx + $r00 * $width_factor + $r01 * $font_height;
-            $ry = $qy + $r10 * $width_factor + $r11 * $font_height;
-
-            # Finally, draw the text:
-            ImageTTFText($this->img, $font_size, $angle, $rx, $ry, $color, $font_file, $lines[$i]);
-
-            # Step to position of next line.
-            # This is a rotation of (x=0,y=height+line_spacing) by $angle:
-            $qx += $r01 * $interline_step;
-            $qy += $r11 * $interline_step;
-        }
-        return True;
-    }
-
-    /*
-     * ProcessText() - Wrapper for ProcessTextTTF() and ProcessTextGD(). See notes above.
-     * This is intended for use from within PHPlot only, and only by DrawText() and SizeText().
-     *    $draw_it : True to draw the text, False to just return the orthogonal width and height.
-     *    $font : PHPlot font array, or NULL or empty string to use 'generic'
-     *    $angle : Text angle in degrees
-     *    $x, $y : Reference point for the text (ignored if !$draw_it)
-     *    $color : GD color index to use for drawing the text (ignored if !$draw_it)
-     *    $text : The text to draw or size. Put a newline between lines.
-     *    $halign : Horizontal alignment: left, center, or right (ignored if !$draw_it)
-     *    $valign : Vertical alignment: top, center, or bottom (ignored if !$draw_it)
-     *      Note: Alignment is relative to the image, not the text.
-     * Returns: True, if drawing text, or an array of ($width, $height) if not.
-     */
-    protected function ProcessText($draw_it, $font, $angle, $x, $y, $color, $text, $halign, $valign)
-    {
-        # Empty text case:
-        if ($text === '') {
-            if ($draw_it) return TRUE;
-            return array(0, 0);
-        }
-
-        # Calculate width and height offset factors using the alignment args:
-        if ($valign == 'top') $v_factor = 0;
-        elseif ($valign == 'center') $v_factor = 0.5;
-        else $v_factor = 1.0; # 'bottom'
-        if ($halign == 'left') $h_factor = 0;
-        elseif ($halign == 'center') $h_factor = 0.5;
-        else $h_factor = 1.0; # 'right'
-
-        # Apply a default font. This is mostly for external (callback) users.
-        if (empty($font)) $font = $this->fonts['generic'];
-
-        if ($font['ttf']) {
-            return $this->ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor);
-        }
-        return $this->ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor);
-    }
-
-
-    /*
-     * Draws a block of text. See comments above before ProcessText().
-     *    $which_font : PHPlot font array, or NULL or empty string to use 'generic'
-     *    $which_angle : Text angle in degrees
-     *    $which_xpos, $which_ypos: Reference point for the text
-     *    $which_color : GD color index to use for drawing the text
-     *    $which_text :  The text to draw, with newlines (\n) between lines.
-     *    $which_halign : Horizontal (relative to the image) alignment: left, center, or right.
-     *    $which_valign : Vertical (relative to the image) alignment: top, center, or bottom.
-     */
-    function DrawText($which_font, $which_angle, $which_xpos, $which_ypos, $which_color, $which_text,
-                      $which_halign = 'left', $which_valign = 'bottom')
-    {
-        return $this->ProcessText(True,
-                           $which_font, $which_angle, $which_xpos, $which_ypos,
-                           $which_color, $which_text, $which_halign, $which_valign);
-    }
-
-    /*
-     * Returns the size of block of text. This is the orthogonal width and height of a bounding
-     * box aligned with the X and Y axes of the text. Only for angle=0 is this the actual
-     * width and height of the text block, but for any angle it is the amount of space needed
-     * to contain the text.
-     *    $which_font : PHPlot font array, or NULL or empty string to use 'generic'
-     *    $which_angle : Text angle in degrees
-     *    $which_text :  The text to draw, with newlines (\n) between lines.
-     * Returns a two element array with: $width, $height.
-     * This is just a wrapper for ProcessText() - see above.
-     */
-    function SizeText($which_font, $which_angle, $which_text)
-    {
-        // Color, position, and alignment are not used when calculating the size.
-        return $this->ProcessText(False,
-                           $which_font, $which_angle, 0, 0, 1, $which_text, '', '');
-    }
-
-
-/////////////////////////////////////////////
-///////////            INPUT / OUTPUT CONTROL
-/////////////////////////////////////////////
-
-    /*!
-     * Sets output file format.
-     */
-    function SetFileFormat($format)
-    {
-        $asked = $this->CheckOption($format, 'jpg, png, gif, wbmp', __FUNCTION__);
-        if (!$asked) return False;
-        switch ($asked) {
-        case 'jpg':
-            $format_test = IMG_JPG;
-            break;
-        case 'png':
-            $format_test = IMG_PNG;
-            break;
-        case 'gif':
-            $format_test = IMG_GIF;
-            break;
-        case 'wbmp':
-            $format_test = IMG_WBMP;
-            break;
-        }
-        if (!(imagetypes() & $format_test)) {
-            return $this->PrintError("SetFileFormat(): File format '$format' not supported");
-        }
-        $this->file_format = $asked;
-        return TRUE;
-    }
-
-
-    /*!
-     * Selects an input file to be used as graph background and scales or tiles this image
-     * to fit the sizes.
-     *  \param input_file string Path to the file to be used (jpeg, png and gif accepted)
-     *  \param mode       string 'centeredtile', 'tile', 'scale' (the image to the graph's size)
-     */
-    function SetBgImage($input_file, $mode='centeredtile')
-    {
-        $this->bgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
-        $this->bgimg  = $input_file;
-        return (boolean)$this->bgmode;
-    }
-
-    /*!
-     * Selects an input file to be used as plot area background and scales or tiles this image
-     * to fit the sizes.
-     *  \param input_file string Path to the file to be used (jpeg, png and gif accepted)
-     *  \param mode       string 'centeredtile', 'tile', 'scale' (the image to the graph's size)
-     */
-    function SetPlotAreaBgImage($input_file, $mode='tile')
-    {
-        $this->plotbgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
-        $this->plotbgimg  = $input_file;
-        return (boolean)$this->plotbgmode;
-    }
-
-
-    /*!
-     * Sets the name of the file to be used as output file.
-     */
-    function SetOutputFile($which_output_file)
-    {
-        $this->output_file = $which_output_file;
-        return TRUE;
-    }
-
-    /*!
-     * Sets the output image as 'inline', that is: no Content-Type headers are sent
-     * to the browser. Needed if you want to embed the images.
-     */
-    function SetIsInline($which_ii)
-    {
-        $this->is_inline = (bool)$which_ii;
-        return TRUE;
-    }
-
-
-    /*!
-     * Performs the actual outputting of the generated graph.
-     */
-    function PrintImage()
-    {
-        // Browser cache stuff submitted by Thiemo Nagel
-        if ( (! $this->browser_cache) && (! $this->is_inline)) {
-            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
-            header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT');
-            header('Cache-Control: no-cache, must-revalidate');
-            header('Pragma: no-cache');
-        }
-
-        switch($this->file_format) {
-        case 'png':
-            if (! $this->is_inline) {
-                Header('Content-type: image/png');
-            }
-            if ($this->is_inline && $this->output_file != '') {
-                ImagePng($this->img, $this->output_file);
-            } else {
-                ImagePng($this->img);
-            }
-            break;
-        case 'jpg':
-            if (! $this->is_inline) {
-                Header('Content-type: image/jpeg');
-            }
-            if ($this->is_inline && $this->output_file != '') {
-                ImageJPEG($this->img, $this->output_file);
-            } else {
-                ImageJPEG($this->img);
-            }
-            break;
-        case 'gif':
-            if (! $this->is_inline) {
-                Header('Content-type: image/gif');
-            }
-            if ($this->is_inline && $this->output_file != '') {
-                ImageGIF($this->img, $this->output_file);
-            } else {
-                ImageGIF($this->img);
-            }
-
-            break;
-        case 'wbmp':        // wireless bitmap, 2 bit.
-            if (! $this->is_inline) {
-                Header('Content-type: image/wbmp');
-            }
-            if ($this->is_inline && $this->output_file != '') {
-                ImageWBMP($this->img, $this->output_file);
-            } else {
-                ImageWBMP($this->img);
-            }
-
-            break;
-        default:
-            return $this->PrintError('PrintImage(): Please select an image type!');
-        }
-        return TRUE;
-    }
-
-    /*!
-     *  Error handling for 'fatal' errors:
-     *   $error_message       Text of the error message
-     *  Standard output from PHPlot is expected to be an image file, such as
-     *  when handling an <img> tag browser request. So it is not permitted to
-     *  output text to standard output. (You should have display_errors=off)
-     *  Here is how PHPlot handles fatal errors:
-     *    + Write the error message into an image, and output the image.
-     *    + If no image can be output, write nothing and produce an HTTP
-     *      error header.
-     *    + Trigger a user-level error containing the error message.
-     *      If no error handler was set up, the script will log the
-     *      error and exit with non-zero status.
-     *
-     *  PrintError() and DrawError() are now equivalent. Both are provided for
-     *  compatibility. (In earlier releases, PrintError sent the message to
-     *  stdout only, and DrawError sent it in an image only.)
-     *
-     *  This function does not return, unless the calling script has set up
-     *  an error handler which does not exit. In that case, PrintError will
-     *  return False. But not all of PHPlot will handle this correctly, so
-     *  it is probably a bad idea for an error handler to return.
-     */
-    protected function PrintError($error_message)
-    {
-        // Be sure not to loop recursively, e.g. PrintError - PrintImage - PrintError.
-        if (isset($this->in_error)) return FALSE;
-        $this->in_error = TRUE;
-
-        // Output an image containing the error message:
-        if (!empty($this->img)) {
-            $ypos = $this->image_height/2;
-            $xpos = $this->image_width/2;
-            $bgcolor = ImageColorResolve($this->img, 255, 255, 255);
-            $fgcolor = ImageColorResolve($this->img, 0, 0, 0);
-            ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height, $bgcolor);
-
-            // Switch to built-in fonts, in case of error with TrueType fonts:
-            $this->SetUseTTF(FALSE);
-
-            $this->DrawText($this->fonts['generic'], 0, $xpos, $ypos, $fgcolor,
-                            wordwrap($error_message), 'center', 'center');
-
-            $this->PrintImage();
-        } elseif (! $this->is_inline) {
-            Header('HTTP/1.0 500 Internal Server Error');
-        }
-        trigger_error($error_message, E_USER_ERROR);
-        unset($this->in_error);
-        return FALSE;  # In case error handler returns, rather than doing exit().
-    }
-
-    /*!
-     * Display an error message and exit.
-     * This is provided for backward compatibility only. Use PrintError() instead.
-     *   $error_message       Text of the error message
-     *   $where_x, $where_y   Ignored, provided for compatibility.
-     */
-    protected function DrawError($error_message, $where_x = NULL, $where_y = NULL)
-    {
-        return $this->PrintError($error_message);
-    }
-
-/////////////////////////////////////////////
-///////////                            LABELS
-/////////////////////////////////////////////
-
-
-    /*!
-     * Sets position for X labels following data points.
-     */
-    function SetXDataLabelPos($which_xdlp)
-    {
-        $which_xdlp = $this->CheckOption($which_xdlp, 'plotdown, plotup, both, xaxis, all, none',
-                                         __FUNCTION__);
-        if (!$which_xdlp) return FALSE;
-        $this->x_data_label_pos = $which_xdlp;
-
-        return TRUE;
-    }
-
-    /*
-     * Sets position for Y data labels.
-     * For bars and stackedbars, these are labels above the bars with the Y values.
-     *    Accepted positions are: plotin, plotstack, none.
-     * For horizontal bars, these are the labels along the Y axis or sides. 
-     *    Accepted positions are: plotleft, plotright, both, none.
-     */
-    function SetYDataLabelPos($which_ydlp)
-    {
-        $which_ydlp = $this->CheckOption($which_ydlp, 'plotin, plotstack, none, plotleft, plotright, both',
-                                          __FUNCTION__);
-        if (!$which_ydlp) return FALSE;
-        $this->y_data_label_pos = $which_ydlp;
-
-        return TRUE;
-    }
-
-    /*!
-     * Sets position for X labels following ticks (hence grid lines)
-     */
-    function SetXTickLabelPos($which_xtlp)
-    {
-        $which_xtlp = $this->CheckOption($which_xtlp, 'plotdown, plotup, both, xaxis, all, none',
-                                         __FUNCTION__);
-        if (!$which_xtlp) return FALSE;
-        $this->x_tick_label_pos = $which_xtlp;
-
-        return TRUE;
-    }
-
-    /*!
-     * Sets position for Y labels following ticks (hence grid lines)
-     */
-    function SetYTickLabelPos($which_ytlp)
-    {
-        $this->y_tick_label_pos = $this->CheckOption($which_ytlp, 'plotleft, plotright, both, yaxis, all, none',
-                                                      __FUNCTION__);
-        return (boolean)$this->y_tick_label_pos;
-    }
-
-    /*!
-     * Sets type for tick and data labels on X or Y axis. This is meant for use by
-     * SetXLabelType and SetYLabelType, but can also be called directly.
-     *    $mode  : 'x', 'y', 'xd', or 'yd' - which type of label to configure.
-     *        'x' and 'y' set the type for tick labels, and the default type for data labels
-     *        if they are not separately configured. 'xd' and 'yd' set the type for data labels.
-     *    $args  : Variable arguments, passed as an array.
-     *       [0] = $type (required) : Label type. 'data', 'time', 'printf', or 'custom'.
-     *     For type 'data':
-     *       [1] = $precision (optional). Numeric precision. Can also be set by SetPrecision[XY]().
-     *       [2] = $prefix (optional) - prefix string for labels.
-     *       [3] = $suffix (optional) - suffix string for labels. This replaces data_units_text.
-     *     For type 'time':
-     *       [1] = $format for strftime (optional). Can also be set by Set[XY]TimeFormat().
-     *     For type 'printf':
-     *       [1] = $format (optional) for sprintf.
-     *     For type 'custom':
-     *       [1] = $callback (required) - Custom function or array of (instance,method) to call.
-     *       [2] = $argument (optional) - Pass-through argument for the formatting function.
-     */
-    protected function SetLabelType($mode, $args)
-    {
-        if (!$this->CheckOption($mode, 'x, y, xd, yd', __FUNCTION__))
-            return FALSE;
-
-        $type = isset($args[0]) ? $args[0] : '';
-        $format =& $this->label_format[$mode];  // Shorthand reference to format storage variables
-        switch ($type) {
-        case 'data':
-            if (isset($args[1]))
-                $format['precision'] = $args[1];
-            elseif (!isset($format['precision']))
-                $format['precision'] = 1;
-            $format['prefix'] = isset($args[2]) ? $args[2] : '';
-            $format['suffix'] = isset($args[3]) ? $args[3] : '';
-            break;
-
-        case 'time':
-            if (isset($args[1]))
-                $format['time_format'] = $args[1];
-            elseif (!isset($format['time_format']))
-                $format['time_format'] = '%H:%M:%S';
-            break;
-
-        case 'printf':
-            if (isset($args[1]))
-                $format['printf_format'] = $args[1];
-            elseif (!isset($format['printf_format']))
-                $format['printf_format'] = '%e';
-            break;
-
-        case 'custom':
-            if (isset($args[1])) {
-                $format['custom_callback'] = $args[1];
-                $format['custom_arg'] = isset($args[2]) ? $args[2] : NULL;
-            } else {
-                $type = ''; // Error, 'custom' without a function, set to no-format mode.
-            }
-            break;
-
-        case '':
-        case 'title':   // Retained for backwards compatibility?
-            break;
-
-        default:
-            $this->CheckOption($type, 'data, time, printf, custom', __FUNCTION__);
-            $type = '';
-        }
-        $format['type'] = $type;
-        return (boolean)$type;
-    }
-
-
-    /*
-     * Select label formating for X tick labels, and for X data labels
-     * (unless SetXDataLabelType was called).
-     * See SetLabelType() for details.
-     */
-    function SetXLabelType()  // Variable arguments: $type, ...
-    {
-        $args = func_get_args();
-        return $this->SetLabelType('x', $args);
-    }
-
-    /*
-     * Select label formatting for X data labels, overriding SetXLabelType.
-     */
-    function SetXDataLabelType()  // Variable arguments: $type, ...
-    {
-        $args = func_get_args();
-        return $this->SetLabelType('xd', $args);
-    }
-
-    /*
-     * Select label formating for Y tick labels, and for Y data labels
-     * (unless SetYDataLabelType was called).
-     * See SetLabelType() for details.
-     */
-    function SetYLabelType()  // Variable arguments: $type, ...
-    {
-        $args = func_get_args();
-        return $this->SetLabelType('y', $args);
-    }
-
-    /*
-     * Select label formatting for Y data labels, overriding SetYLabelType.
-     */
-    function SetYDataLabelType()  // Variable arguments: $type, ...
-    {
-        $args = func_get_args();
-        return $this->SetLabelType('yd', $args);
-    }
-
-    function SetXTimeFormat($which_xtf)
-    {
-        $this->label_format['x']['time_format'] = $which_xtf;
-        return TRUE;
-    }
-
-    function SetYTimeFormat($which_ytf)
-    {
-        $this->label_format['y']['time_format'] = $which_ytf;
-        return TRUE;
-    }
-
-    function SetNumberFormat($decimal_point, $thousands_sep)
-    {
-        $this->decimal_point = $decimal_point;
-        $this->thousands_sep = $thousands_sep;
-        return TRUE;
-    }
-
-
-    function SetXLabelAngle($which_xla)
-    {
-        $this->x_label_angle = $which_xla;
-        return TRUE;
-    }
-
-    function SetYLabelAngle($which_yla)
-    {
-        $this->y_label_angle = $which_yla;
-        return TRUE;
-    }
-
-    // If used, this sets the angle for X Data Labels only, separately from tick labels.
-    function SetXDataLabelAngle($which_xdla)
-    {
-        $this->x_data_label_angle = $which_xdla;
-        return TRUE;
-    }
-
-    // Sets the angle for Y Data Labels. Unlike X Data Labels, these default to zero.
-    function SetYDataLabelAngle($which_ydla)
-    {
-        $this->y_data_label_angle = $which_ydla;
-        return TRUE;
-    }
-
-
-/////////////////////////////////////////////
-///////////                              MISC
-/////////////////////////////////////////////
-
-    /*!
-     * Checks the validity of an option.
-     *   $which_opt  String to check, such as the provided value of a function argument.
-     *   $which_acc  String of accepted choices. Must be lower-case, and separated
-     *               by exactly ', ' (comma, space).
-     *   $which_func Name of the calling function, for error messages.
-     * Returns the supplied option value, downcased and trimmed, if it is valid.
-     * Reports an error if the supplied option is not valid.
-     */
-    protected function CheckOption($which_opt, $which_acc, $which_func)
-    {
-        $asked = strtolower(trim($which_opt));
-
-        # Look for the supplied value in a comma/space separated list.
-        if (strpos(", $which_acc,", ", $asked,") !== False)
-            return $asked;
-
-        $this->PrintError("$which_func(): '$which_opt' not in available choices: '$which_acc'.");
-        return NULL;
-    }
-
-    /*
-     * Checks the validity of an array of options.
-     *   $opt  Array or string to check.
-     *   $acc  String of accepted choices. Must be lower-case, and separated
-     *               by exactly ', ' (comma, space).
-     *   $func Name of the calling function, for error messages.
-     * Returns a array option value(s), downcased and trimmed, if all entries in $opt are valid.
-     * Reports an error if any supplied option is not valid. Returns NULL if the error handler returns.
-     */
-    protected function CheckOptionArray($opt, $acc, $func)
-    {
-        $opt_array = (array)$opt;
-        $result = array();
-        foreach ($opt_array as $option) {
-            $choice = $this->CheckOption($option, $acc, $func);
-            if (is_null($choice)) return NULL; // In case CheckOption error handler returns
-            $result[] = $choice;
-        }
-        return $result;
-    }
-
-    /*
-     * Check compatibility of a plot type and data type.
-     * This is called by the plot-type-specific drawing functions.
-     *   $valid_types  String of supported data types. Multiple values must be
-     *      separated by exactly ', ' (comma, space).
-     * Returns True if the type is valid for this plot.
-     * Reports an error if the data type is not value. If the error is handled and
-     *   the handler returns, this returns False.
-     */
-    protected function CheckDataType($valid_types)
-    {
-        if (strpos(", $valid_types,", ", $this->data_type,") !== False)
-            return TRUE;
-
-        $this->PrintError("Data type '$this->data_type' is not valid for '$this->plot_type' plots."
-               . " Supported data type(s): '$valid_types'");
-        return FALSE;
-    }
-
-    /*
-     * Decode the data type into variables used to determine how to process a data array.
-     * Returns a numeric-indexed array with these elements in order:
-     *    swapped_xy  (boolean) True if Y is the independent variable, X dependent (e.g. horizontal bars).
-     *    implied_x   (boolean) True if data array has an implied X value for each set of Y.
-     *    implied_y   (boolean) True if data array has an implied Y value for each set of X.
-     *    err_bars    (boolean) True if data array contains error bars values for each point.
-     * Note these are not independent. implied_y means swapped_xy, and implied_x means !swapped_xy.
-     * Also some possibilities are reserved for future use: swapped_xy && !implied_y would be a
-     * future swapped X/Y equivalent to data-data or data-data-error.
-     */
-    protected function DecodeDataType()
-    {
-        $swapped_xy = ($this->data_type == 'text-data-yx'); // Only swapped type available now
-        $implied_x = ($this->data_type == 'text-data');
-        $implied_y = ($this->data_type == 'text-data-yx');
-        $err_bars = ($this->data_type == 'data-data-error');
-
-        return array($swapped_xy, $implied_x, $implied_y, $err_bars);
-    }
-
-    /*!
-     *  \note Submitted by Thiemo Nagel
-     */
-    function SetBrowserCache($which_browser_cache)
-    {
-        $this->browser_cache = $which_browser_cache;
-        return TRUE;
-    }
-
-    /*!
-     * Whether to show the final image or not
-     */
-    function SetPrintImage($which_pi)
-    {
-        $this->print_image = $which_pi;
-        return TRUE;
-    }
-
-    /*!
-     * Sets the graph's legend. If argument is not an array, appends it to the legend.
-     */
-    function SetLegend($which_leg)
-    {
-        if (is_array($which_leg)) {             // use array
-            $this->legend = $which_leg;
-        } elseif (! is_null($which_leg)) {     // append string
-            $this->legend[] = $which_leg;
-        } else {
-            return $this->PrintError("SetLegend(): argument must not be null.");
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Specifies the position of the legend's upper/leftmost corner,
-     * in pixel (device) coordinates.
-     */
-    function SetLegendPixels($which_x, $which_y)
-    {
-        $this->legend_x_pos = $which_x;
-        $this->legend_y_pos = $which_y;
-        // Make sure this is unset, meaning we have pixel coords:
-        unset($this->legend_xy_world);
-
-        return TRUE;
-    }
-
-    /*!
-     * Specifies the position of the legend's upper/leftmost corner,
-     * in world (data space) coordinates.
-     * Since the scale factor to convert world to pixel coordinates
-     * is probably not available, set a flag and defer conversion
-     * to later.
-     */
-    function SetLegendWorld($which_x, $which_y)
-    {
-        $this->legend_x_pos = $which_x;
-        $this->legend_y_pos = $which_y;
-        $this->legend_xy_world = True;
-
-        return TRUE;
-    }
-
-    /*
-     * Set legend text alignment, color box alignment, and style options
-     *     $text_align accepts 'left' or 'right'.
-     *     $colorbox_align accepts 'left', 'right', 'none', or missing/empty. If missing or empty,
-     *        the same alignment as $text_align is used. Color box is positioned first.
-     *     $style is reserved for future use.
-     */
-    function SetLegendStyle($text_align, $colorbox_align = '', $style = '')
-    {
-        $this->legend_text_align = $this->CheckOption($text_align, 'left, right', __FUNCTION__);
-        if (empty($colorbox_align))
-            $this->legend_colorbox_align = $this->legend_text_align;
-        else
-            $this->legend_colorbox_align = $this->CheckOption($colorbox_align, 'left, right, none', __FUNCTION__);
-        return ((boolean)$this->legend_text_align && (boolean)$this->legend_colorbox_align);
-    }
-
-    /*
-     * Set border for the plot area.
-     * Accepted values are: left, right, top, bottom, sides, none, full or an array of those.
-     */
-    function SetPlotBorderType($pbt)
-    {
-        $this->plot_border_type = $this->CheckOptionArray($pbt, 'left, right, top, bottom, sides, none, full',
-                                                          __FUNCTION__);
-        return !empty($this->plot_border_type);
-    }
-
-    /*
-     * Set border style for the image.
-     * Accepted values are: raised, plain, solid, none
-     *  'solid' is the same as 'plain' except it fixes the color (see DrawImageBorder)
-     */
-    function SetImageBorderType($sibt)
-    {
-        $this->image_border_type = $this->CheckOption($sibt, 'raised, plain, solid, none', __FUNCTION__);
-        return (boolean)$this->image_border_type;
-    }
-
-    /*
-     * Set border width for the image.
-     */
-    function SetImageBorderWidth($width)
-    {
-        $this->image_border_width = $width;
-        return TRUE;
-    }
-
-    /*!
-     * \param dpab bool
-     */
-    function SetDrawPlotAreaBackground($dpab)
-    {
-        $this->draw_plot_area_background = (bool)$dpab;
-        return TRUE;
-    }
-
-
-    /*!
-     * \param dyg bool
-     */
-    function SetDrawYGrid($dyg)
-    {
-        $this->draw_y_grid = (bool)$dyg;
-        return TRUE;
-    }
-
-
-    /*!
-     * \param dxg bool
-     */
-    function SetDrawXGrid($dxg)
-    {
-        $this->draw_x_grid = (bool)$dxg;
-        return TRUE;
-    }
-
-
-    /*!
-     * \param ddg bool
-     */
-    function SetDrawDashedGrid($ddg)
-    {
-        $this->dashed_grid = (bool)$ddg;
-        return TRUE;
-    }
-
-
-    /*!
-     * \param dxdl bool
-     */
-    function SetDrawXDataLabelLines($dxdl)
-    {
-        $this->draw_x_data_label_lines = (bool)$dxdl;
-        return TRUE;
-    }
-
-    /*!
-     * Sets the graph's title.
-     * TODO: add parameter to choose title placement: left, right, centered=
-     */
-    function SetTitle($which_title)
-    {
-        $this->title_txt = $which_title;
-        return TRUE;
-    }
-
-    /*!
-     * Sets the X axis title and position.
-     */
-    function SetXTitle($which_xtitle, $which_xpos = 'plotdown')
-    {
-        if ($which_xtitle == '')
-            $which_xpos = 'none';
-
-        $this->x_title_pos = $this->CheckOption($which_xpos, 'plotdown, plotup, both, none', __FUNCTION__);
-        if (!$this->x_title_pos) return FALSE;
-        $this->x_title_txt = $which_xtitle;
-        return TRUE;
-    }
-
-
-    /*!
-     * Sets the Y axis title and position.
-     */
-    function SetYTitle($which_ytitle, $which_ypos = 'plotleft')
-    {
-        if ($which_ytitle == '')
-            $which_ypos = 'none';
-
-        $this->y_title_pos = $this->CheckOption($which_ypos, 'plotleft, plotright, both, none', __FUNCTION__);
-        if (!$this->y_title_pos) return FALSE;
-        $this->y_title_txt = $which_ytitle;
-        return TRUE;
-    }
-
-    /*!
-     * Sets the size of the drop shadow for bar and pie charts.
-     * \param which_s int Size in pixels.
-     */
-    function SetShading($which_s)
-    {
-        $this->shading = (int)$which_s;
-        return TRUE;
-    }
-
-    function SetPlotType($which_pt)
-    {
-        $this->plot_type = $this->CheckOption($which_pt, 'bars, stackedbars, lines, linepoints,'
-                            . ' area, points, pie, thinbarline, squared, stackedarea',
-                            __FUNCTION__);
-        return (boolean)$this->plot_type;
-    }
-
-    /*!
-     * Sets the position of Y axis.
-     * \param pos int Position in world coordinates.
-     */
-    function SetYAxisPosition($pos)
-    {
-        $this->y_axis_position = (int)$pos;
-        return TRUE;
-    }
-
-    /*!
-     * Sets the position of X axis.
-     * \param pos int Position in world coordinates.
-     */
-    function SetXAxisPosition($pos)
-    {
-        $this->x_axis_position = (int)$pos;
-        return TRUE;
-    }
-
-
-    function SetXScaleType($which_xst)
-    {
-        $this->xscale_type = $this->CheckOption($which_xst, 'linear, log', __FUNCTION__);
-        return (boolean)$this->xscale_type;
-    }
-
-    function SetYScaleType($which_yst)
-    {
-        $this->yscale_type = $this->CheckOption($which_yst, 'linear, log',  __FUNCTION__);
-        return (boolean)$this->yscale_type;
-    }
-
-    function SetPrecisionX($which_prec)
-    {
-        return $this->SetXLabelType('data', $which_prec);
-    }
-
-    function SetPrecisionY($which_prec)
-    {
-        return $this->SetYLabelType('data', $which_prec);
-    }
-
-    function SetErrorBarLineWidth($which_seblw)
-    {
-        $this->error_bar_line_width = $which_seblw;
-        return TRUE;
-    }
-
-    function SetLabelScalePosition($which_blp)
-    {
-        //0 to 1
-        $this->label_scale_position = $which_blp;
-        return TRUE;
-    }
-
-    function SetErrorBarSize($which_ebs)
-    {
-        //in pixels
-        $this->error_bar_size = $which_ebs;
-        return TRUE;
-    }
-
-    /*!
-     * Can be one of: 'tee', 'line'
-     */
-    function SetErrorBarShape($which_ebs)
-    {
-        $this->error_bar_shape = $this->CheckOption($which_ebs, 'tee, line', __FUNCTION__);
-        return (boolean)$this->error_bar_shape;
-    }
-
-    /*
-     * Synchronize the point shape and point size arrays.
-     * This is called just before drawing any plot that needs 'points'.
-     */
-    protected function CheckPointParams()
-    {
-        // Make both point_shapes and point_sizes the same size, by padding the smaller.
-        $ps = count($this->point_sizes);
-        $pt = count($this->point_shapes);
-
-        if ($ps < $pt) {
-            $this->pad_array($this->point_sizes, $pt);
-            $this->point_counts = $pt;
-        } else if ($ps > $pt) {
-            $this->pad_array($this->point_shapes, $ps);
-            $this->point_counts = $ps;
-        } else {
-            $this->point_counts = $ps;
-        }
-
-        // Note: PHPlot used to check and adjust point_sizes to be an even number here,
-        // for all 'diamond' and 'triangle' shapes. The reason for this having been
-        // lost, and the current maintainer seeing no sense it doing this for only
-        // some shapes, the code has been removed. But see what DrawDot() does.
-    }
-
-    /*!
-     * Sets point shape for each data set via an array.
-     * For a list of valid shapes, see the CheckOption call below.
-     * The point shape and point sizes arrays are synchronized before drawing a graph
-     * that uses points. See CheckPointParams()
-     */
-    function SetPointShapes($which_pt)
-    {
-        if (is_array($which_pt)) {
-            // Use provided array:
-            $this->point_shapes = $which_pt;
-        } elseif (!is_null($which_pt)) {
-            // Make the single value into an array:
-            $this->point_shapes = array($which_pt);
-        }
-
-        // Validate all the shapes. This list must agree with DrawDot().
-        foreach ($this->point_shapes as $shape)
-        {
-            if (!$this->CheckOption($shape, 'halfline, line, plus, cross, rect, circle, dot,'
-                       . ' diamond, triangle, trianglemid, delta, yield, star, hourglass,'
-                       . ' bowtie, target, box, home, up, down, none', __FUNCTION__))
-                return FALSE;
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Sets the point size for point plots.
-     * The point shape and point sizes arrays are synchronized before drawing a graph
-     * that uses points. See CheckPointParams()
-     */
-    function SetPointSizes($which_ps)
-    {
-        if (is_array($which_ps)) {
-            // Use provided array:
-            $this->point_sizes = $which_ps;
-        } elseif (!is_null($which_ps)) {
-            // Make the single value into an array:
-            $this->point_sizes = array($which_ps);
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Tells not to draw lines for missing Y data. Only works with 'lines' and 'squared' plots.
-     * \param bl bool
-     */
-    function SetDrawBrokenLines($bl)
-    {
-        $this->draw_broken_lines = (bool)$bl;
-        return TRUE;
-    }
-
-
-    /*
-     * Set the data type, which defines the structure of the data array
-     *  text-data: ('label', y1, y2, y3, ...)
-     *  text-data-single: ('label', data), for some pie charts.
-     *  data-data: ('label', x, y1, y2, y3, ...)
-     *  data-data-error: ('label', x1, y1, e1+, e2-, y2, e2+, e2-, y3, e3+, e3-, ...)
-     *  text-data-yx: ('label', x1, x2, x3, ...)
-     */
-    function SetDataType($which_dt)
-    {
-        //The next four lines are for past compatibility.
-        if ($which_dt == 'text-linear') { $which_dt = 'text-data'; }
-        elseif ($which_dt == 'linear-linear') { $which_dt = 'data-data'; }
-        elseif ($which_dt == 'linear-linear-error') { $which_dt = 'data-data-error'; }
-        elseif ($which_dt == 'text-data-pie') { $which_dt = 'text-data-single'; }
-
-        $this->data_type = $this->CheckOption($which_dt, 'text-data, text-data-single, '.
-                                                         'data-data, data-data-error, text-data-yx',
-                                                         __FUNCTION__);
-        return (boolean)$this->data_type;
-    }
-
-    /*!
-     * Copy the array passed as data values. We convert to numerical indexes, for its
-     * use for (or while) loops, which sometimes are faster. Performance improvements
-     * vary from 28% in DrawLines() to 49% in DrawArea() for plot drawing functions.
-     */
-    function SetDataValues($which_dv)
-    {
-        $this->num_data_rows = count($which_dv);
-        $this->total_records = 0;               // Perform some useful calculations.
-        $this->records_per_group = 1;
-        for ($i = 0, $recs = 0; $i < $this->num_data_rows; $i++) {
-            // Copy
-            $this->data[$i] = array_values($which_dv[$i]);   // convert to numerical indices.
-
-            // Compute some values
-            $recs = count($this->data[$i]);
-            $this->total_records += $recs;
-
-            if ($recs > $this->records_per_group)
-                $this->records_per_group = $recs;
-
-            $this->num_recs[$i] = $recs;
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Pad styles arrays for later use by plot drawing functions:
-     * This removes the need for $max_data_colors, etc. and $color_index = $color_index % $max_data_colors
-     * in DrawBars(), DrawLines(), etc.
-     */
-    protected function PadArrays()
-    {
-        $this->pad_array($this->line_widths, $this->records_per_group);
-        $this->pad_array($this->line_styles, $this->records_per_group);
-
-        $this->pad_array($this->data_colors, $this->records_per_group);
-        $this->pad_array($this->data_border_colors, $this->records_per_group);
-        $this->pad_array($this->error_bar_colors, $this->records_per_group);
-
-        $this->SetDataColors();
-        $this->SetDataBorderColors();
-        $this->SetErrorBarColors();
-
-        return TRUE;
-    }
-
-    /*!
-     * Pads an array with itself. This only works on 0-based sequential integer indexed arrays.
-     *  \param arr array  Original array (reference), or scalar.
-     *  \param size int   Minimum size of the resulting array.
-     * If $arr is a scalar, it will be converted first to a single element array.
-     * If $arr has at least $size elements, it is unchanged.
-     * Otherwise, append elements of $arr to itself until it reaches $size elements.
-     */
-    protected function pad_array(&$arr, $size)
-    {
-        if (! is_array($arr)) {
-            $arr = array($arr);
-        }
-        $n = count($arr);
-        $base = 0;
-        while ($n < $size) $arr[$n++] = $arr[$base++];
-    }
-
-    /*
-     * Format a floating-point number.
-     * This is like PHP's number_format, but uses class variables for separators.
-     * The separators will default to locale-specific values, if available.
-     * Note: This method should be 'protected', but is called from test script(s).
-     */
-    function number_format($number, $decimals=0)
-    {
-        if (!isset($this->decimal_point) || !isset($this->thousands_sep)) {
-            // Load locale-specific values from environment, unless disabled:
-            if (empty($this->locale_override))
-                @setlocale(LC_ALL, '');
-            // Fetch locale settings:
-            $locale = @localeconv();
-            if (!empty($locale) && isset($locale['decimal_point']) &&
-                    isset($locale['thousands_sep'])) {
-              $this->decimal_point = $locale['decimal_point'];
-              $this->thousands_sep = $locale['thousands_sep'];
-            } else {
-              // Locale information not available.
-              $this->decimal_point = '.';
-              $this->thousands_sep = ',';
-            }
-        }
-        return number_format($number, $decimals, $this->decimal_point, $this->thousands_sep);
-    }
-
-    /*
-     * Register a callback (hook) function
-     *   reason - A pre-defined name where a callback can be defined.
-     *   function - The name of a function to register for callback, or an instance/method
-     *      pair in an array (see 'callbacks' in the PHP reference manual).
-     *   arg - Optional argument to supply to the callback function when it is triggered.
-     *      (Often called "clientData")
-     * Returns: True if the callback reason is valid, else False.
-     */
-    function SetCallback($reason, $function, $arg = NULL)
-    {
-        // Use array_key_exists because valid reason keys have NULL as value.
-        if (!array_key_exists($reason, $this->callbacks))
-            return False;
-        $this->callbacks[$reason] = array($function, $arg);
-        return True;
-    }
-
-    /*
-     * Return the name of a function registered for callback. See SetCallBack.
-     *   reason - A pre-defined name where a callback can be defined.
-     * Returns the current callback function (name or array) for the given reason,
-     * or False if there was no active callback or the reason is not valid.
-     * Note you can safely test the return value with a simple 'if', as
-     * no valid function name evaluates to false.
-     */
-    function GetCallback($reason)
-    {
-        if (isset($this->callbacks[$reason]))
-            return $this->callbacks[$reason][0];
-        return False;
-    }
-
-    /*
-     * Un-register (remove) a function registered for callback.
-     *   reason - A pre-defined name where a callback can be defined.
-     * Returns: True if it was a valid callback reason, else False.
-     * Note: Returns True whether or not there was a callback registered.
-     */
-    function RemoveCallback($reason)
-    {
-        if (!array_key_exists($reason, $this->callbacks))
-            return False;
-        $this->callbacks[$reason] = NULL;
-        return True;
-    }
-
-    /*
-     * Invoke a callback, if one is registered.
-     * Accepts a variable number of arguments >= 1:
-     *    reason : A string naming the callback.
-     *    ... : Zero or more additional arguments to be passed to the
-     *      callback function, after the passthru argument:
-     *           callback_function($image, $passthru, ...)
-     * Returns: nothing.
-     */
-    protected function DoCallback()  # Note: Variable arguments
-    {
-        $args = func_get_args();
-        $reason = $args[0];
-        if (!isset($this->callbacks[$reason]))
-            return;
-        list($function, $args[0]) = $this->callbacks[$reason];
-        array_unshift($args, $this->img);
-        # Now args[] looks like: img, passthru, extra args...
-        call_user_func_array($function, $args);
-    }
-
-
-//////////////////////////////////////////////////////////
-///////////         DATA ANALYSIS, SCALING AND TRANSLATION
-//////////////////////////////////////////////////////////
-
-    /*
-     * Analyzes the data array and calculates the minimum and maximum values.
-     * In this function, IV refers to the independent variable, and DV the dependent variable.
-     * For most plots, IV is X and DV is Y. For swapped X/Y plots, IV is Y and DV is X.
-     * At the end of the function, IV and DV ranges get assigned into X or Y.
-     *
-     * Plot types 'stackedbars' and 'stackedarea' are special cases, because the bars or area always
-     *    start at 0 (although they may be clipped below the X axis, if the axis is moved up),
-     *    absolute values are used, and the Y values in each row accumulate.
-     *
-     * This calculates min_x, max_x, min_y, and max_y. It also calculates two arrays
-     * data_min[] and data_max[] with per-row min and max values. These are used for
-     * data label lines. For normal (unswapped) data, these are the Y range for each X.
-     * For swapped X/Y data, they are the X range for each Y.
-     *
-     * Note: This method should be 'protected', but is called from test script(s).
-     */
-    function FindDataLimits()
-    {
-        # Determine how to process the data array:
-        list($swapped_xy, $implied_x, $implied_y, $err_bars) = $this->DecodeDataType();
-        // process_iv is true if the data array contains independent variable values:
-        $process_iv = !($implied_x || $implied_y);
-
-        # Special case processing for certain plot types:
-        $process_stacked = ($this->plot_type == 'stackedbars' || $this->plot_type == 'stackedarea');
-        $abs_val = ($this->plot_type == 'area' || $this->plot_type == 'pie');
-
-        # These need to be initialized in case there are multiple plots and
-        # missing data points.
-        $this->data_min = array();
-        $this->data_max = array();
-
-        # Independent values are in the data array or assumed?
-        if ($process_iv) {
-            $all_iv = array();
-        } else {
-            $all_iv = array(0, $this->num_data_rows - 1);
-        }
-
-        # Process all rows of data:
-        for ($i = 0; $i < $this->num_data_rows; $i++) {
-            $n_vals = $this->num_recs[$i];
-            $j = 1; # Skips label at [0]
-
-            if ($process_iv) {
-                $all_iv[] = (double)$this->data[$i][$j++];
-            }
-
-            if ($process_stacked) {
-                $all_dv = array(0, 0); # Min (always 0) and max
-            } else {
-                $all_dv = array();
-            }
-            while ($j < $n_vals) {
-                if (is_numeric($this->data[$i][$j])) {
-                    $val = (double)$this->data[$i][$j++];
-
-                    if ($err_bars) {
-                        $all_dv[] = $val + (double)$this->data[$i][$j++];
-                        $all_dv[] = $val - (double)$this->data[$i][$j++];
-                    } elseif ($process_stacked) {
-                        $all_dv[1] += abs($val);
-                    } elseif ($abs_val) {
-                        $all_dv[] = abs($val);
-                    } else {
-                        $all_dv[] = $val;
-                    }
-                } else {    # Missing DV value
-                  $j++;
-                  if ($err_bars) $j += 2;
-                }
-            }
-            if (!empty($all_dv)) {
-                $this->data_min[$i] = min($all_dv);  # Store per-row DV range
-                $this->data_max[$i] = max($all_dv);
-            }
-        }
-
-        if ($swapped_xy) {
-            // Assign min and max for swapped X/Y plots: IV=Y and DV=X
-            $this->min_y = min($all_iv);
-            $this->max_y = max($all_iv);
-            if (empty($this->data_min)) { # Guard against regressive case: No X at all
-                $this->min_x = 0;
-                $this->max_x = 0;
-            } else {
-                $this->min_x = min($this->data_min);  # Store global X range
-                $this->max_x = max($this->data_max);
-            }
-        } else {
-            // Assign min and max for normal plots: IV=X and DV=Y
-            $this->min_x = min($all_iv);
-            $this->max_x = max($all_iv);
-            if (empty($this->data_min)) { # Guard against regressive case: No Y at all
-                $this->min_y = 0;
-                $this->max_y = 0;
-            } else {
-                $this->min_y = min($this->data_min);  # Store global Y range
-                $this->max_y = max($this->data_max);
-            }
-        }
-
-        if ($this->GetCallback('debug_scale')) {
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'min_x' => $this->min_x, 'min_y' => $this->min_y,
-                'max_x' => $this->max_x, 'max_y' => $this->max_y));
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Calculates image margins on the fly from title positions and sizes,
-     * and tick labels positions and sizes.
-     *
-     * A picture of the locations of elements and spacing can be found in the
-     * PHPlot Reference Manual.
-     *
-     * Calculates the following (class variables unless noted):
-     *
-     * Plot area margins (see note below):
-     *     y_top_margin
-     *     y_bot_margin
-     *     x_left_margin
-     *     x_right_margin
-     *
-     * Title sizes (these are now local, not class variables, since they are not used elsewhere):
-     *     title_height : Height of main title
-     *     x_title_height : Height of X axis title, 0 if no X title
-     *     y_title_width : Width of Y axis title, 0 if no Y title
-     *
-     * Tick/Data label offsets, relative to plot_area:
-     *     x_label_top_offset, x_label_bot_offset, x_label_axis_offset
-     *     y_label_left_offset, y_label_right_offset, y_label_axis_offset
-     *
-     * Title offsets, relative to plot area:
-     *     x_title_top_offset, x_title_bot_offset
-     *     y_title_left_offset, y_title_left_offset
-     *     title_offset (for main title, relative to image edge)
-     *
-     *  Note: The margins are calculated, but not stored, if margins or plot area were
-     *  set by the user with SetPlotAreaPixels or SetMarginsPixels. The margin
-     *  calculation is mixed in with the offset variables, so it doesn't seem worth the
-     *  trouble to separate them.
-     *
-     * If the $maximize argument is true, we use the full image size, minus safe_margin
-     * and main title, for the plot. This is for pie charts which have no axes or X/Y titles.
-     */
-    protected function CalcMargins($maximize)
-    {
-        // This is the line-to-line or line-to-text spacing:
-        $gap = $this->safe_margin;
-        // Initial margin on each side takes into account a possible image border.
-        // For compatibility, if border is 1 or 2, don't increase the margins.
-        $base_margin = max($gap, $this->GetImageBorderWidth() + 3);
-        $this->title_offset = $base_margin;  // For use in DrawTitle
-
-        // Minimum margin on each side. This reduces the chance that the
-        // right-most tick label (for example) will run off the image edge
-        // if there are no titles on that side.
-        $min_margin = 2 * $gap + $base_margin;
-
-        // Calculate the title sizes:
-        list($unused, $title_height) = $this->SizeText($this->fonts['title'], 0, $this->title_txt);
-        list($unused, $x_title_height) = $this->SizeText($this->fonts['x_title'], 0, $this->x_title_txt);
-        list($y_title_width, $unused) = $this->SizeText($this->fonts['y_title'], 90, $this->y_title_txt);
-
-        // Special case for maximum area usage with no X/Y titles or labels, only main title:
-        if ($maximize) {
-            if (!isset($this->x_left_margin))
-                $this->x_left_margin = $base_margin;
-            if (!isset($this->x_right_margin))
-                $this->x_right_margin = $base_margin;
-            if (!isset($this->y_top_margin)) {
-                $this->y_top_margin = $base_margin;
-                if ($title_height > 0)
-                    $this->y_top_margin += $title_height + $gap;
-            }
-            if (!isset($this->y_bot_margin))
-                $this->y_bot_margin = $base_margin;
-
-            return TRUE;
-        }
-
-        // Make local variables for these. (They get used a lot and I'm tired of this, this, this.)
-        $x_tick_label_pos = $this->x_tick_label_pos;
-        $x_data_label_pos = $this->x_data_label_pos;
-        $x_tick_pos       = $this->x_tick_pos;
-        $x_tick_len       = $this->x_tick_length;
-        $y_tick_label_pos = $this->y_tick_label_pos;
-        $y_tick_pos       = $this->y_tick_pos;
-        $y_tick_len       = $this->y_tick_length;
-        $y_data_label_pos = $this->y_data_label_pos;
-
-        // For X/Y tick and label position of 'xaxis' or 'yaxis', determine if the axis happens to be
-        // on an edge of a plot. If it is, we need to account for the margins there.
-        if ($this->x_axis_position <= $this->plot_min_y)
-            $x_axis_pos = 'bottom';
-        elseif ($this->x_axis_position >= $this->plot_max_y)
-            $x_axis_pos = 'top';
-        else
-            $x_axis_pos = 'none';
-        if ($this->y_axis_position <= $this->plot_min_x)
-            $y_axis_pos = 'left';
-        elseif ($this->y_axis_position >= $this->plot_max_x)
-            $y_axis_pos = 'right';
-        else
-            $y_axis_pos = 'none';
-
-        // Calculate the heights for X tick and data labels, and the max (used if they are overlaid):
-        $x_data_label_height = ($x_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('x');
-        $x_tick_label_height = ($x_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('x');
-        $x_max_label_height = max($x_data_label_height, $x_tick_label_height);
-
-        // Calculate the space needed above and below the plot for X tick and X data labels:
-
-        // Above the plot:
-        $tick_labels_above = ($x_tick_label_pos == 'plotup' || $x_tick_label_pos == 'both'
-                          || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'top'));
-        $data_labels_above = ($x_data_label_pos == 'plotup' || $x_data_label_pos == 'both');
-        if ($tick_labels_above) {
-            if ($data_labels_above) {
-                $label_height_above = $x_max_label_height;
-            } else {
-                $label_height_above = $x_tick_label_height;
-            }
-        } elseif ($data_labels_above) {
-            $label_height_above = $x_data_label_height;
-        } else {
-            $label_height_above = 0;
-        }
-
-        // Below the plot:
-        $tick_labels_below = ($x_tick_label_pos == 'plotdown' || $x_tick_label_pos == 'both'
-                          || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'bottom'));
-        $data_labels_below = ($x_data_label_pos == 'plotdown' || $x_data_label_pos == 'both');
-        if ($tick_labels_below) {
-            if ($data_labels_below) {
-                $label_height_below = $x_max_label_height;
-            } else {
-                $label_height_below = $x_tick_label_height;
-            }
-        } elseif ($data_labels_below) {
-            $label_height_below = $x_data_label_height;
-        } else {
-            $label_height_below = 0;
-        }
-
-        // Calculate the width for Y tick and data labels, if on, and the max:
-        // Note CalcMaxDataLabelSize('y') returns 0 except for swapped X/Y plots.
-        $y_data_label_width = ($y_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('y');
-        $y_tick_label_width = ($y_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('y');
-        $y_max_label_width = max($y_data_label_width, $y_tick_label_width);
-
-        // Calculate the space needed left and right of the plot for Y tick and Y data labels:
-        // (Y data labels here are for swapped X/Y plots such has horizontal bars)
-
-        // Left of the plot:
-        $tick_labels_left = ($y_tick_label_pos == 'plotleft' || $y_tick_label_pos == 'both'
-                         || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'left'));
-        $data_labels_left = ($y_data_label_pos == 'plotleft' || $y_data_label_pos == 'both');
-        if ($tick_labels_left) {
-            if ($data_labels_left) {
-                $label_width_left = $y_max_label_width;
-            } else {
-                $label_width_left = $y_tick_label_width;
-            }
-        } elseif ($data_labels_left) {
-            $label_width_left = $y_data_label_width;
-        } else {
-            $label_width_left = 0;
-        }
-
-        // Right of the plot:
-        $tick_labels_right = ($y_tick_label_pos == 'plotright' || $y_tick_label_pos == 'both'
-                          || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'right'));
-        $data_labels_right = ($y_data_label_pos == 'plotright' || $y_data_label_pos == 'both');
-        if ($tick_labels_right) {
-            if ($data_labels_right) {
-                $label_width_right = $y_max_label_width;
-            } else {
-                $label_width_right = $y_tick_label_width;
-            }
-        } elseif ($data_labels_right) {
-            $label_width_right = $y_data_label_width;
-        } else {
-            $label_width_right = 0;
-        }
-
-        ///////// Calculate margins:
-
-        // Calculating Top and Bottom margins:
-        // y_top_margin: Main title, Upper X title, X ticks and tick labels, and X data labels:
-        // y_bot_margin: Lower title, ticks and tick labels, and data labels:
-        $top_margin = $base_margin;
-        $bot_margin = $base_margin;
-        $this->x_title_top_offset = $gap;
-        $this->x_title_bot_offset = $gap;
-
-        // Space for main title?
-        if ($title_height > 0)
-            $top_margin += $title_height + $gap;
-
-        // Space for X Title?
-        if ($x_title_height > 0) {
-            $pos = $this->x_title_pos;
-            if ($pos == 'plotup' || $pos == 'both')
-                $top_margin += $x_title_height + $gap;
-            if ($pos == 'plotdown' || $pos == 'both')
-                $bot_margin += $x_title_height + $gap;
-        }
-
-        // Space for X Labels above the plot?
-        if ($label_height_above > 0) {
-            $top_margin += $label_height_above + $gap;
-            $this->x_title_top_offset += $label_height_above + $gap;
-        }
-
-        // Space for X Labels below the plot?
-        if ($label_height_below > 0) {
-            $bot_margin += $label_height_below + $gap;
-            $this->x_title_bot_offset += $label_height_below + $gap;
-        }
-
-        // Space for X Ticks above the plot?
-        if ($x_tick_pos == 'plotup' || $x_tick_pos == 'both'
-           || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'top')) {
-            $top_margin += $x_tick_len;
-            $this->x_label_top_offset = $x_tick_len + $gap;
-            $this->x_title_top_offset += $x_tick_len;
-        } else {
-            // No X Ticks above the plot:
-            $this->x_label_top_offset = $gap;
-        }
-
-        // Space for X Ticks below the plot?
-        if ($x_tick_pos == 'plotdown' || $x_tick_pos == 'both'
-           || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'bottom')) {
-            $bot_margin += $x_tick_len;
-            $this->x_label_bot_offset = $x_tick_len + $gap;
-            $this->x_title_bot_offset += $x_tick_len;
-        } else {
-            // No X Ticks below the plot:
-            $this->x_label_bot_offset = $gap;
-        }
-        // Label offsets for on-axis ticks:
-        if ($x_tick_pos == 'xaxis') {
-            $this->x_label_axis_offset = $x_tick_len + $gap;
-        } else {
-            $this->x_label_axis_offset = $gap;
-        }
-
-        // Calculating Left and Right margins:
-        // x_left_margin: Left Y title, Y ticks and tick labels:
-        // x_right_margin: Right Y title, Y ticks and tick labels:
-        $left_margin = $base_margin;
-        $right_margin = $base_margin;
-        $this->y_title_left_offset = $gap;
-        $this->y_title_right_offset = $gap;
-
-        // Space for Y Title?
-        if ($y_title_width > 0) {
-            $pos = $this->y_title_pos;
-            if ($pos == 'plotleft' || $pos == 'both')
-                $left_margin += $y_title_width + $gap;
-            if ($pos == 'plotright' || $pos == 'both')
-                $right_margin += $y_title_width + $gap;
-        }
-
-        // Space for Y Labels left of the plot?
-        if ($label_width_left > 0) {
-            $left_margin += $label_width_left + $gap;
-            $this->y_title_left_offset += $label_width_left + $gap;
-        }
-
-        // Space for Y Labels right of the plot?
-        if ($label_width_right > 0) {
-            $right_margin += $label_width_right + $gap;
-            $this->y_title_right_offset += $label_width_right + $gap;
-        }
-
-        // Space for Y Ticks left of plot?
-        if ($y_tick_pos == 'plotleft' || $y_tick_pos == 'both'
-           || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'left')) {
-            $left_margin += $y_tick_len;
-            $this->y_label_left_offset = $y_tick_len + $gap;
-            $this->y_title_left_offset += $y_tick_len;
-        } else {
-            // No Y Ticks left of plot:
-            $this->y_label_left_offset = $gap;
-        }
-
-        // Space for Y Ticks right of plot?
-        if ($y_tick_pos == 'plotright' || $y_tick_pos == 'both'
-           || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'right')) {
-            $right_margin += $y_tick_len;
-            $this->y_label_right_offset = $y_tick_len + $gap;
-            $this->y_title_right_offset += $y_tick_len;
-        } else {
-            // No Y Ticks right of plot:
-            $this->y_label_right_offset = $gap;
-        }
-
-        // Label offsets for on-axis ticks:
-        if ($x_tick_pos == 'yaxis') {
-            $this->y_label_axis_offset = $y_tick_len + $gap;
-        } else {
-            $this->y_label_axis_offset = $gap;
-        }
-
-        // Apply the minimum margins and store in the object.
-        // Do not set margins which were user-defined (see note at top of function).
-        if (!isset($this->y_top_margin))
-            $this->y_top_margin = max($min_margin, $top_margin);
-        if (!isset($this->y_bot_margin))
-            $this->y_bot_margin = max($min_margin, $bot_margin);
-        if (!isset($this->x_left_margin))
-            $this->x_left_margin = max($min_margin, $left_margin);
-        if (!isset($this->x_right_margin))
-            $this->x_right_margin = max($min_margin, $right_margin);
-
-        if ($this->GetCallback('debug_scale')) {
-            // (Too bad compact() doesn't work on class member variables...)
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'label_height_above' => $label_height_above,
-                'label_height_below' => $label_height_below,
-                'label_width_left' => $label_width_left,
-                'label_width_right' => $label_width_right,
-                'x_tick_len' => $x_tick_len,
-                'y_tick_len' => $y_tick_len,
-                'x_left_margin' => $this->x_left_margin,
-                'x_right_margin' => $this->x_right_margin,
-                'y_top_margin' => $this->y_top_margin,
-                'y_bot_margin' => $this->y_bot_margin,
-                'x_label_top_offset' => $this->x_label_top_offset,
-                'x_label_bot_offset' => $this->x_label_bot_offset,
-                'y_label_left_offset' => $this->y_label_left_offset,
-                'y_label_right_offset' => $this->y_label_right_offset,
-                'x_title_top_offset' => $this->x_title_top_offset,
-                'x_title_bot_offset' => $this->x_title_bot_offset,
-                'y_title_left_offset' => $this->y_title_left_offset,
-                'y_title_right_offset' => $this->y_title_right_offset));
-        }
-
-        return TRUE;
-    }
-
-    /*
-     * Calculate the plot area (device coordinates) from the margins.
-     * (This used to be part of SetPlotAreaPixels.)
-     * The margins might come from SetMarginsPixels, SetPlotAreaPixels,
-     * or CalcMargins.
-     */
-    protected function CalcPlotAreaPixels()
-    {
-        $this->plot_area = array($this->x_left_margin, $this->y_top_margin,
-                                 $this->image_width - $this->x_right_margin,
-                                 $this->image_height - $this->y_bot_margin);
-        $this->plot_area_width = $this->plot_area[2] - $this->plot_area[0];
-        $this->plot_area_height = $this->plot_area[3] - $this->plot_area[1];
-
-        $this->DoCallback('debug_scale', __FUNCTION__, $this->plot_area);
-        return TRUE;
-    }
-
-
-    /*!
-     * Set the margins in pixels (left, right, top, bottom)
-     * This determines the plot area, equivalent to SetPlotAreaPixels().
-     * Deferred calculations now occur in CalcPlotAreaPixels().
-     */
-    function SetMarginsPixels($which_lm = NULL, $which_rm = NULL, $which_tm = NULL, $which_bm = NULL)
-    {
-        $this->x_left_margin = $which_lm;
-        $this->x_right_margin = $which_rm;
-        $this->y_top_margin = $which_tm;
-        $this->y_bot_margin = $which_bm;
-
-        return TRUE;
-    }
-
-    /*!
-     * Sets the limits for the plot area.
-     * This stores the margins, not the area. That may seem odd, but
-     * the idea is to make SetPlotAreaPixels and SetMarginsPixels two
-     * ways to accomplish the same thing, and the deferred calculations
-     * in CalcMargins and CalcPlotAreaPixels don't need to know which
-     * was used.
-     *   (x1, y1) - Upper left corner of the plot area
-     *   (x2, y2) - Lower right corner of the plot area
-     */
-    function SetPlotAreaPixels($x1 = NULL, $y1 = NULL, $x2 = NULL, $y2 = NULL)
-    {
-        $this->x_left_margin = $x1;
-        if (isset($x2)) $this->x_right_margin = $this->image_width - $x2;
-        else unset($this->x_right_margin);
-        $this->y_top_margin = $y1;
-        if (isset($y2)) $this->y_bot_margin = $this->image_height - $y2;
-        else unset($this->y_bot_margin);
-
-        return TRUE;
-    }
-
-    /*
-     * Calculate the World Coordinate limits of the plot area.
-     * This goes with SetPlotAreaWorld, but the calculations are
-     * deferred until the graph is being drawn.
-     * Uses and sets: plot_min_x, plot_max_x, plot_min_y, plot_max_y
-     * These can be user-supplied or NULL to auto-calculate.
-     * Pre-requisites: FindDataLimits() calculates min_x, max_x, min_y, max_y
-     * which are the limits of the data to be plotted.
-     *
-     * Note: $implied_y and $swapped_xy are currently equivalent, but in the
-     * future there may be a data type with swapped X/Y and explicit Y values.
-     * The 4 code blocks below for plot_min_x, plot_max_x, plot_min_y, and
-     * plot_max_y already contain logic for this case.
-     * The general method is this:
-     *   If any part of the range is user-defined (via SetPlotAreaWorld),
-     *      use the user-defined value.
-     *   Else, if this is an implicitly-defined independent variable,
-     *      use the fixed range of 0 to (max+1).
-     *   Else, if this is an explicitly-defined independent variable,
-     *      use the exact data range (min to max).
-     *   Else, this is the dependent variable, so define a range which
-     *      includes and exceeds the data range by a bit.
-     */
-    protected function CalcPlotAreaWorld()
-    {
-        list($swapped_xy, $implied_x, $implied_y) = $this->DecodeDataType();
-
-        if (isset($this->plot_min_x) && $this->plot_min_x !== '')
-            $xmin = $this->plot_min_x; // Use user-provided value
-        elseif ($implied_x)
-            $xmin = 0;          // Implied X starts at zero
-        elseif ($swapped_xy)
-            // If X is the dependent variable, leave some room below.
-            $xmin = floor($this->min_x - abs($this->min_x) * 0.1);
-        else
-            $xmin = $this->min_x;  // Otherwise just start at the min data X
-
-        if (isset($this->plot_max_x) && $this->plot_max_x !== '')
-            $xmax = $this->plot_max_x; // Use user-provided value
-        elseif ($implied_x)
-            $xmax = $this->max_x + 1; // Implied X ends after last value
-        elseif ($swapped_xy)
-            // If X is the dependent variable, leave some room above.
-            $xmax = ceil($this->max_x + abs($this->max_x) * 0.1);
-        else
-            $xmax = $this->max_x; // Otherwise just end at the max data X
-
-        if (isset($this->plot_min_y) && $this->plot_min_y !== '')
-            $ymin = $this->plot_min_y;  // Use user-provided value
-        elseif ($implied_y)
-            $ymin = 0;    // Implied Y starts at zero
-        elseif ($swapped_xy)
-            $ymin = $this->min_y; // Start at min data Y
-        else
-            // If Y is the dependent variable, leave some room below.
-            $ymin = floor($this->min_y - abs($this->min_y) * 0.1);
-
-        if (isset($this->plot_max_y) && $this->plot_max_y !== '')
-            $ymax = $this->plot_max_y; // Use user-provided value
-        elseif ($implied_y)
-            $ymax = $this->max_y + 1; // Implied Y ends after last value
-        elseif ($swapped_xy)
-            $ymax = $this->max_y;  // End at max data Y
-        else
-            // If Y is the dependent variable, leave some room above.
-            $ymax = ceil($this->max_y + abs($this->max_y) * 0.1);
-
-        // Error checking
-
-        if ($ymin == $ymax)
-            $ymax++;
-        if ($xmin == $xmax)
-            $xmax++;
-
-        if ($this->yscale_type == 'log') {
-            if ($ymin <= 0) {
-                $ymin = 1;
-            }
-            if ($ymax <= 0) {
-                // Note: Error messages reference the user function, not this function.
-                return $this->PrintError('SetPlotAreaWorld(): Log plots need data greater than 0');
-            }
-        }
-
-        if ($ymax <= $ymin) {
-            return $this->PrintError('SetPlotAreaWorld(): Error in data - max not greater than min');
-        }
-
-        $this->plot_min_x = $xmin;
-        $this->plot_max_x = $xmax;
-        $this->plot_min_y = $ymin;
-        $this->plot_max_y = $ymax;
-        if ($this->GetCallback('debug_scale')) {
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'plot_min_x' => $this->plot_min_x, 'plot_min_y' => $this->plot_min_y,
-                'plot_max_x' => $this->plot_max_x, 'plot_max_y' => $this->plot_max_y));
-        }
-
-        return TRUE;
-    }
-
-    /*!
-     * Stores the desired World Coordinate range of the plot.
-     * The user calls this to force one or more of the range limits to
-     * specific values. Anything not set will be calculated in CalcPlotAreaWorld().
-     */
-    function SetPlotAreaWorld($xmin=NULL, $ymin=NULL, $xmax=NULL, $ymax=NULL)
-    {
-        $this->plot_min_x = $xmin;
-        $this->plot_max_x = $xmax;
-        $this->plot_min_y = $ymin;
-        $this->plot_max_y = $ymax;
-        return TRUE;
-    } //function SetPlotAreaWorld
-
-
-    /*
-     * Calculate the width (or height) of bars for bar plots.
-     * This calculates:
-     *    record_bar_width : Allocated width for each bar (including gaps)
-     *    actual_bar_width : Actual drawn width of each bar
-     *    bar_adjust_gap  : Gap on each side of each bar (0 if they touch)
-     * For the case $verticals=False, horizontal bars are being drawn,
-     * but the same variable names are used. Think of "bar_width" as being
-     * the width if you are standing on the Y axis looking towards positive X.
-     */
-    protected function CalcBarWidths($verticals = True)
-    {
-        // group_width is the width of a group, including padding
-        if ($verticals) {
-            $group_width = $this->plot_area_width / $this->num_data_rows;
-        } else {
-            $group_width = $this->plot_area_height / $this->num_data_rows;
-        }
-
-        // Actual number of bar spaces in the group. This includes the drawn bars, and
-        // 'bar_extra_space'-worth of extra bars.
-        // Note that 'records_per_group' includes the label, so subtract one to get
-        // the number of points in the group. 'stackedbars' have 1 bar space per group.
-        if ($this->plot_type == 'stackedbars') {
-          $num_spots = 1 + $this->bar_extra_space;
-        } else {
-          $num_spots = $this->records_per_group - 1 + $this->bar_extra_space;
-        }
-
-        // record_bar_width is the width of each bar's allocated area.
-        // If bar_width_adjust=1 this is the width of the bar, otherwise
-        // the bar is centered inside record_bar_width.
-        // The equation is:
-        //   group_frac_width * group_width = record_bar_width * num_spots
-        $this->record_bar_width = $this->group_frac_width * $group_width / $num_spots;
-
-        // Note that the extra space due to group_frac_width and bar_extra_space will be
-        // evenly divided on each side of the group: the drawn bars are centered in the group.
-
-        // Within each bar's allocated space, if bar_width_adjust=1 the bar fills the
-        // space, otherwise it is centered.
-        // This is the actual drawn bar width:
-        $this->actual_bar_width = $this->record_bar_width * $this->bar_width_adjust;
-        // This is the gap on each side of the bar (0 if bar_width_adjust=1):
-        $this->bar_adjust_gap = ($this->record_bar_width - $this->actual_bar_width) / 2;
-
-        if ($this->GetCallback('debug_scale')) {
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'record_bar_width' => $this->record_bar_width,
-                'actual_bar_width' => $this->actual_bar_width,
-                'bar_adjust_gap' => $this->bar_adjust_gap));
-        }
-        return TRUE;
-    }
-
-    /*
-     * Calculate X and Y Axis Positions, world coordinates.
-     * This needs the min/max x/y range set by CalcPlotAreaWorld.
-     * It adjusts or sets x_axis_position and y_axis_position per the data.
-     * Empty string means the values need to be calculated; otherwise they
-     * are supplied but need to be validated against the World area.
-     *
-     * Note: This used to be in CalcTranslation, but CalcMargins needs it too.
-     * This does not calculate the pixel values of the axes. That happens in
-     * CalcTranslation, after scaling is set up (which has to happen after
-     * margins are set up).
-     */
-    protected function CalcAxisPositions()
-    {
-        // If no user-provided Y axis position, default to axis on left side.
-        // Otherwise, make sure user-provided position is inside the plot area.
-        if ($this->y_axis_position === '')
-            $this->y_axis_position = $this->plot_min_x;
-        else
-            $this->y_axis_position = min(max($this->plot_min_x, $this->y_axis_position), $this->plot_max_x);
-
-        // Validate user-provided X axis position, or auto-calculate if not:
-        if ($this->x_axis_position !== '') {
-            // User-provided X axis position: make sure it is inside the range.
-            $this->x_axis_position = min(max($this->plot_min_y, $this->x_axis_position), $this->plot_max_y);
-        } elseif ($this->yscale_type == 'log') {
-            // Always use 1 for X axis position on log scale plots.
-            $this->x_axis_position = 1;
-        } elseif ($this->plot_min_y <= 0 && 0 <= $this->plot_max_y) {
-            // Plot range includes Y=0, so use that for X axis:
-            $this->x_axis_position = 0;
-        } elseif ($this->plot_min_y > 0) {
-            // The entire Y range is > 0, so use the bottom for the X axis:
-            $this->x_axis_position = $this->plot_min_y;
-        } else {
-            // The entire Y range is < 0, so use the top for the X axis:
-            $this->x_axis_position = $this->plot_max_y;
-        }
-
-        if ($this->GetCallback('debug_scale')) {
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'x_axis_position' => $this->x_axis_position,
-                'y_axis_position' => $this->y_axis_position));
-        }
-
-        return TRUE;
-    }
-
-    /*!
-     * Calculates scaling stuff...
-     */
-    protected function CalcTranslation()
-    {
-        if ($this->plot_max_x - $this->plot_min_x == 0) { // Check for div by 0
-            $this->xscale = 0;
-        } else {
-            if ($this->xscale_type == 'log') {
-                $this->xscale = ($this->plot_area_width)/(log10($this->plot_max_x) - log10($this->plot_min_x));
-            } else {
-                $this->xscale = ($this->plot_area_width)/($this->plot_max_x - $this->plot_min_x);
-            }
-        }
-
-        if ($this->plot_max_y - $this->plot_min_y == 0) { // Check for div by 0
-            $this->yscale = 0;
-        } else {
-            if ($this->yscale_type == 'log') {
-                $this->yscale = ($this->plot_area_height)/(log10($this->plot_max_y) - log10($this->plot_min_y));
-            } else {
-                $this->yscale = ($this->plot_area_height)/($this->plot_max_y - $this->plot_min_y);
-            }
-        }
-        // GD defines x = 0 at left and y = 0 at TOP so -/+ respectively
-        if ($this->xscale_type == 'log') {
-            $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * log10($this->plot_min_x) );
-        } else {
-            $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * $this->plot_min_x);
-        }
-        if ($this->yscale_type == 'log') {
-            $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * log10($this->plot_min_y));
-        } else {
-            $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * $this->plot_min_y);
-        }
-
-        // Convert axis positions to device coordinates:
-        $this->y_axis_x_pixels = $this->xtr($this->y_axis_position);
-        $this->x_axis_y_pixels = $this->ytr($this->x_axis_position);
-
-        if ($this->GetCallback('debug_scale')) {
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'xscale' => $this->xscale, 'yscale' => $this->yscale,
-                'plot_origin_x' => $this->plot_origin_x, 'plot_origin_y' => $this->plot_origin_y,
-                'y_axis_x_pixels' => $this->y_axis_x_pixels,
-                'x_axis_y_pixels' => $this->x_axis_y_pixels));
-        }
-
-        return TRUE;
-    } // function CalcTranslation()
-
-
-    /*!
-     * Translate X world coordinate into pixel coordinate
-     * See CalcTranslation() for calculation of xscale.
-     */
-    function xtr($x_world)
-    {
-        if ($this->xscale_type == 'log') {
-            $x_pixels = $this->plot_origin_x + log10($x_world) * $this->xscale ;
-        } else {
-            $x_pixels = $this->plot_origin_x + $x_world * $this->xscale ;
-        }
-        return round($x_pixels);
-    }
-
-
-    /*!
-     * Translate Y world coordinate into pixel coordinate.
-     * See CalcTranslation() for calculation of yscale.
-     */
-    function ytr($y_world)
-    {
-        if ($this->yscale_type == 'log') {
-            //minus because GD defines y = 0 at top. doh!
-            $y_pixels =  $this->plot_origin_y - log10($y_world) * $this->yscale ;
-        } else {
-            $y_pixels =  $this->plot_origin_y - $y_world * $this->yscale ;
-        }
-        return round($y_pixels);
-    }
-
-    /* A public interface to xtr and ytr. Translates (x,y) in world coordinates
-     * to (x,y) in device coordinates and returns them as an array.
-     * Usage is: list($x_pixel, $y_pixel) = $plot->GetDeviceXY($x_world, $y_world)
-     */
-    function GetDeviceXY($x_world, $y_world)
-    {
-        if (!isset($this->xscale)) {
-            return $this->PrintError("GetDeviceXY() was called before translation factors were calculated");
-        }
-        return array($this->xtr($x_world), $this->ytr($y_world));
-    }
-
-    /*
-     * Calculate tick parameters: Start, end, and delta values. This is used
-     * by both DrawXTicks() and DrawYTicks().
-     * This currently uses the same simplistic method previously used by
-     * PHPlot (basically just range/10), but splitting this out into its
-     * own function is the first step in replacing the method.
-     * This is also used by CalcMaxTickSize() for CalcMargins().
-     *
-     *   $which : 'x' or 'y' : Which tick parameters to calculate
-     *
-     * Returns an array of 3 elements: tick_start, tick_end, tick_step
-     */
-    protected function CalcTicks($which)
-    {
-        if ($which == 'x') {
-            $num_ticks = $this->num_x_ticks;
-            $tick_inc = $this->x_tick_inc;
-            $data_max = $this->plot_max_x;
-            $data_min = $this->plot_min_x;
-            $skip_lo = $this->skip_left_tick;
-            $skip_hi = $this->skip_right_tick;
-        } elseif ($which == 'y') {
-            $num_ticks = $this->num_y_ticks;
-            $tick_inc = $this->y_tick_inc;
-            $data_max = $this->plot_max_y;
-            $data_min = $this->plot_min_y;
-            $skip_lo = $this->skip_bottom_tick;
-            $skip_hi = $this->skip_top_tick;
-        } else {
-          return $this->PrintError("CalcTicks: Invalid usage ($which)");
-        }
-
-        if (!empty($tick_inc)) {
-            $tick_step = $tick_inc;
-        } elseif (!empty($num_ticks)) {
-            $tick_step = ($data_max - $data_min) / $num_ticks;
-        } else {
-            $tick_step = ($data_max - $data_min) / 10;
-        }
-
-        // NOTE: When working with floats, because of approximations when adding $tick_step,
-        // the value may not quite reach the end, or may exceed it very slightly.
-        // So apply a "fudge" factor.
-        $tick_start = (double)$data_min;
-        $tick_end = (double)$data_max + ($data_max - $data_min) / 10000.0;
-
-        if ($skip_lo)
-            $tick_start += $tick_step;
-
-        if ($skip_hi)
-            $tick_end -= $tick_step;
-
-        return array($tick_start, $tick_end, $tick_step);
-    }
-
-    /*
-     * Calculate the size of the biggest tick label. This is used by CalcMargins().
-     * For 'x' ticks, it returns the height . For 'y' ticks, it returns the width.
-     * This means height along Y, or width along X - not relative to the text angle.
-     * That is what we need to calculate the needed margin space.
-     * (Previous versions of PHPlot estimated this, using the maximum X or Y value,
-     * or maybe the longest string. That doesn't work. -10 is longer than 9, etc.
-     * So this gets the actual size of each label, slow as that may be.
-     */
-    protected function CalcMaxTickLabelSize($which)
-    {
-        list($tick_start, $tick_end, $tick_step) = $this->CalcTicks($which);
-
-        if ($which == 'x') {
-          $font = $this->fonts['x_label'];
-          $angle = $this->x_label_angle;
-        } elseif ($which == 'y') {
-          $font = $this->fonts['y_label'];
-          $angle = $this->y_label_angle;
-        } else {
-          return $this->PrintError("CalcMaxTickLabelSize: Invalid usage ($which)");
-        }
-
-        $max_width = 0;
-        $max_height = 0;
-
-        // Loop over ticks, same as DrawXTicks and DrawYTicks:
-        // Avoid cumulative round-off errors from $val += $delta
-        $n = 0;
-        $tick_val = $tick_start;
-        while ($tick_val <= $tick_end) {
-            $tick_label = $this->FormatLabel($which, $tick_val);
-            list($width, $height) = $this->SizeText($font, $angle, $tick_label);
-            if ($width > $max_width) $max_width = $width;
-            if ($height > $max_height) $max_height = $height;
-            $tick_val = $tick_start + ++$n * $tick_step;
-        }
-        if ($this->GetCallback('debug_scale')) {
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'which' => $which, 'height' => $max_height, 'width' => $max_width));
-        }
-
-        if ($which == 'x')
-            return $max_height;
-        return $max_width;
-    }
-
-    /*
-     * Calculate the size of the biggest data label. This is used by CalcMargins().
-     * For $which='x', it returns the height of labels along the top or bottom.
-     * For $which='y', it returns the width of labels along the left or right sides.
-     * There is only one set of data labels (the first position in each data record).
-     * They normally go along the top or bottom (or both). If the data type indicates
-     * X/Y swapping (which is used for horizontal bar charts), the data labels go
-     * along the sides instead. So CalcMaxDataLabelSize('x') returns 0 if the
-     * data is X/Y swapped, and CalcMaxDataLabelSize('y') returns 0 if the data is
-     * is not X/Y swapped.
-     */
-    protected function CalcMaxDataLabelSize($which = 'x')
-    {
-        list($swapped_xy) = $this->DecodeDataType();
-        if ($which == 'x') {
-          if ($swapped_xy)
-              return 0; // Shortcut: labels aren't on top/bottom.
-          $font = $this->fonts['x_label'];
-          $angle = $this->x_data_label_angle;
-          $format_code = 'xd';
-        } elseif ($which == 'y') {
-          if (!$swapped_xy)
-              return 0; // Shortcut: labels aren't on left/right.
-          $font = $this->fonts['y_label'];
-          $angle = $this->y_data_label_angle;
-          $format_code = 'yd';
-        } else {
-          return $this->PrintError("CalcMaxDataLabelSize: Invalid usage ($which)");
-        }
-        $max_width = 0;
-        $max_height = 0;
-
-        // Loop over all data labels and find the biggest:
-        for ($i = 0; $i < $this->num_data_rows; $i++) {
-            $label = $this->FormatLabel($format_code, $this->data[$i][0]);
-            list($width, $height) = $this->SizeText($font, $angle, $label);
-            if ($width > $max_width) $max_width = $width;
-            if ($height > $max_height) $max_height = $height;
-        }
-        if ($this->GetCallback('debug_scale')) {
-            $this->DoCallback('debug_scale', __FUNCTION__, array(
-                'height' => $max_height, 'width' => $max_width));
-        }
-
-        if ($swapped_xy)
-            return $max_width;
-        return $max_height;
-    }
-
-    /*
-     * Set grid control defaults.
-     * X grid defaults off, Y grid defaults on, except the reverse is true
-     * with swapped graphs such as horizontal bars.
-     */
-    protected function CalcGridSettings()
-    {
-        list($swapped_xy) = $this->DecodeDataType();
-        if (!isset($this->draw_x_grid))
-            $this->draw_x_grid = $swapped_xy;
-        if (!isset($this->draw_y_grid))
-            $this->draw_y_grid = !$swapped_xy;
-    }
-
-    /*
-     * Helper for CheckLabels() - determine if there are any non-empty labels.
-     * Returns True if all data labels are empty, else False.
-     */
-    protected function CheckLabelsAllEmpty()
-    {
-        for ($i = 0; $i < $this->num_data_rows; $i++)
-            if ($this->data[$i][0] !== '') return False;
-        return True;
-    }
-
-    /*
-     * Check and set label parameters. This handles deferred processing for label
-     * positioning and other label-related parameters.
-     *   Copy label_format from 'x' to 'xd', and 'y' to 'yd', if not already set.
-     *   Set x_data_label_angle from x_label_angle, if not already set.
-     *   Apply defaults to X and Y tick and data label positions.
-     * Note: the label strings in the data array are used as X data labels in
-     * the normal case, but as Y data labels in the swapped X/Y case.
-     */
-    protected function CheckLabels()
-    {
-        // The X and Y data labels are formatted the same as X and Y tick labels,
-        // unless overridden. Check and apply defaults for FormatLabel here:
-        if (empty($this->label_format['xd']) && !empty($this->label_format['x']))
-            $this->label_format['xd'] = $this->label_format['x'];
-        if (empty($this->label_format['yd']) && !empty($this->label_format['y']))
-            $this->label_format['yd'] = $this->label_format['y'];
-
-        // The X tick label angle setting controls X data label angles too,
-        // unless overridden. Check and apply the default here:
-        if (!isset($this->x_data_label_angle))
-            $this->x_data_label_angle = $this->x_label_angle;
-        // Note: Y data label angle defaults to zero, unlike X,
-        // for compatibility with older releases.
-
-        list($swapped_xy) = $this->DecodeDataType(); // Determine if X->Y or Y->X.
-
-        // X Label position fixups, for x_data_label_pos and x_tick_label_pos:
-        if ($swapped_xy) {
-            // Just apply defaults - there is no position conflict for X labels.
-            if (!isset($this->x_tick_label_pos))
-                $this->x_tick_label_pos = 'plotdown';
-            if (!isset($this->x_data_label_pos))
-                $this->x_data_label_pos = 'none';
-        } else {
-            // Apply defaults but do not allow conflict between tick and data labels.
-            if (isset($this->x_data_label_pos)) {
-                if (!isset($this->x_tick_label_pos)) {
-                    // Case: data_label_pos is set, tick_label_pos needs a default:
-                    if ($this->x_data_label_pos == 'none')
-                        $this->x_tick_label_pos = 'plotdown';
-                    else
-                        $this->x_tick_label_pos = 'none';
-                }
-            } elseif (isset($this->x_tick_label_pos)) {
-                // Case: tick_label_pos is set, data_label_pos needs a default:
-                if ($this->x_tick_label_pos == 'none')
-                    $this->x_data_label_pos = 'plotdown';
-                else
-                    $this->x_data_label_pos = 'none';
-            } else {
-                // Case: Neither tick_label_pos nor data_label_pos is set.
-                // We do not want them to be both on (as PHPlot used to do in this case).
-                // Turn on data labels if any were supplied, else tick labels.
-                if ($this->CheckLabelsAllEmpty()) {
-                    $this->x_data_label_pos = 'none';
-                    $this->x_tick_label_pos = 'plotdown';
-                } else {
-                    $this->x_data_label_pos = 'plotdown';
-                    $this->x_tick_label_pos = 'none';
-                }
-            }
-        }
-
-        // Y Label position fixups, for y_data_label_pos and y_tick_label_pos:
-        if (!$swapped_xy) {
-            // Just apply defaults - there is no position conflict.
-            if (!isset($this->y_tick_label_pos))
-                $this->y_tick_label_pos = 'plotleft';
-            if (!isset($this->y_data_label_pos))
-                $this->y_data_label_pos = 'none';
-        } else {
-            // Apply defaults but do not allow conflict between tick and data labels.
-            if (isset($this->y_data_label_pos)) {
-                if (!isset($this->y_tick_label_pos)) {
-                    // Case: data_label_pos is set, tick_label_pos needs a default:
-                    if ($this->y_data_label_pos == 'none')
-                        $this->y_tick_label_pos = 'plotleft';
-                    else
-                        $this->y_tick_label_pos = 'none';
-                }
-            } elseif (isset($this->y_tick_label_pos)) {
-                // Case: tick_label_pos is set, data_label_pos needs a default:
-                if ($this->y_tick_label_pos == 'none')
-                    $this->y_data_label_pos = 'plotleft';
-                else
-                    $this->y_data_label_pos = 'none';
-            } else {
-                // Case: Neither tick_label_pos nor data_label_pos is set.
-                // Turn on data labels if any were supplied, else tick labels.
-                if ($this->CheckLabelsAllEmpty()) {
-                    $this->y_data_label_pos = 'none';
-                    $this->y_tick_label_pos = 'plotleft';
-                } else {
-                    $this->y_data_label_pos = 'plotleft';
-                    $this->y_tick_label_pos = 'none';
-                }
-            }
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Formats a tick or data label.
-     *    which_pos - 'x', 'xd', 'y', or 'yd', selects formatting controls.
-     *        x, y are for tick labels; xd, yd are for data labels.
-     *    which_lab - String to format as a label.
-     * Credits: Time formatting suggested by Marlin Viss
-     *          Custom formatting suggested by zer0x333
-     * Notes:
-     *   Type 'title' is obsolete and retained for compatibility.
-     *   Class variable 'data_units_text' is retained as a suffix for 'data' type formatting for
-     *      backward compatibility. Since there was never a function/method to set it, there
-     *      could be somebody out there who sets it directly in the object.
-     */
-    protected function FormatLabel($which_pos, $which_lab)
-    {
-        // Assign a reference shortcut to the label format controls.
-        // Note CheckLabels() made sure the 'xd' and 'yd' arrays are set.
-        $format =& $this->label_format[$which_pos];
-
-        // Don't format empty strings (especially as time or numbers), or if no type was set.
-        if ($which_lab !== '' && !empty($format['type'])) {
-            switch ($format['type']) {
-            case 'title':  // Note: This is obsolete
-                $which_lab = @ $this->data[$which_lab][0];
-                break;
-            case 'data':
-                $which_lab = $format['prefix']
-                           . $this->number_format($which_lab, $format['precision'])
-                           . $this->data_units_text  // Obsolete
-                           . $format['suffix'];
-                break;
-            case 'time':
-                $which_lab = strftime($format['time_format'], $which_lab);
-                break;
-            case 'printf':
-                $which_lab = sprintf($format['printf_format'], $which_lab);
-                break;
-            case 'custom':
-                $which_lab = call_user_func($format['custom_callback'], $which_lab, $format['custom_arg']);
-                break;
-
-            }
-        }
-        return $which_lab;
-    } //function FormatLabel
-
-/////////////////////////////////////////////
-///////////////                         TICKS
-/////////////////////////////////////////////
-
-    /*!
-     * Use either this or SetNumXTicks() to set where to place x tick marks
-     */
-    function SetXTickIncrement($which_ti='')
-    {
-        $this->x_tick_inc = $which_ti;
-        if (!empty($which_ti)) {
-            $this->num_x_ticks = ''; //either use num_x_ticks or x_tick_inc, not both
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Use either this or SetNumYTicks() to set where to place y tick marks
-     */
-    function SetYTickIncrement($which_ti='')
-    {
-        $this->y_tick_inc = $which_ti;
-        if (!empty($which_ti)) {
-            $this->num_y_ticks = ''; //either use num_y_ticks or y_tick_inc, not both
-        }
-        return TRUE;
-    }
-
-
-    function SetNumXTicks($which_nt)
-    {
-        $this->num_x_ticks = $which_nt;
-        if (!empty($which_nt)) {
-            $this->x_tick_inc = '';  //either use num_x_ticks or x_tick_inc, not both
-        }
-        return TRUE;
-    }
-
-    function SetNumYTicks($which_nt)
-    {
-        $this->num_y_ticks = $which_nt;
-        if (!empty($which_nt)) {
-            $this->y_tick_inc = '';  //either use num_y_ticks or y_tick_inc, not both
-        }
-        return TRUE;
-    }
-
-    /*!
-     *
-     */
-    function SetYTickPos($which_tp)
-    {
-        $this->y_tick_pos = $this->CheckOption($which_tp, 'plotleft, plotright, both, yaxis, none', __FUNCTION__);
-        return (boolean)$this->y_tick_pos;
-    }
-    /*!
-     *
-     */
-    function SetXTickPos($which_tp)
-    {
-        $this->x_tick_pos = $this->CheckOption($which_tp, 'plotdown, plotup, both, xaxis, none', __FUNCTION__);
-        return (boolean)$this->x_tick_pos;
-    }
-
-    /*!
-     * \param skip bool
-     */
-    function SetSkipTopTick($skip)
-    {
-        $this->skip_top_tick = (bool)$skip;
-        return TRUE;
-    }
-
-    /*!
-     * \param skip bool
-     */
-    function SetSkipBottomTick($skip)
-    {
-        $this->skip_bottom_tick = (bool)$skip;
-        return TRUE;
-    }
-
-    /*!
-     * \param skip bool
-     */
-    function SetSkipLeftTick($skip)
-    {
-        $this->skip_left_tick = (bool)$skip;
-        return TRUE;
-    }
-
-    /*!
-     * \param skip bool
-     */
-    function SetSkipRightTick($skip)
-    {
-        $this->skip_right_tick = (bool)$skip;
-        return TRUE;
-    }
-
-    function SetXTickLength($which_xln)
-    {
-        $this->x_tick_length = $which_xln;
-        return TRUE;
-    }
-
-    function SetYTickLength($which_yln)
-    {
-        $this->y_tick_length = $which_yln;
-        return TRUE;
-    }
-
-    function SetXTickCrossing($which_xc)
-    {
-        $this->x_tick_cross = $which_xc;
-        return TRUE;
-    }
-
-    function SetYTickCrossing($which_yc)
-    {
-        $this->y_tick_cross = $which_yc;
-        return TRUE;
-    }
-
-
-/////////////////////////////////////////////
-////////////////////          GENERIC DRAWING
-/////////////////////////////////////////////
-
-    /*!
-     * Fills the background.
-     * Note: This method should be 'protected', but is called from test script(s).
-     */
-    function DrawBackground()
-    {
-        // Don't draw this twice if drawing two plots on one image
-        if (! $this->background_done) {
-            if (isset($this->bgimg)) {    // If bgimg is defined, use it
-                $this->tile_img($this->bgimg, 0, 0, $this->image_width, $this->image_height, $this->bgmode);
-            } else {                        // Else use solid color
-                ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height,
-                                     $this->ndx_bg_color);
-            }
-            $this->background_done = TRUE;
-        }
-        return TRUE;
-    }
-
-
-    /*!
-     * Fills the plot area background.
-     */
-    protected function DrawPlotAreaBackground()
-    {
-        if (isset($this->plotbgimg)) {
-            $this->tile_img($this->plotbgimg, $this->plot_area[0], $this->plot_area[1],
-                            $this->plot_area_width, $this->plot_area_height, $this->plotbgmode);
-        }
-        else {
-            if ($this->draw_plot_area_background) {
-                ImageFilledRectangle($this->img, $this->plot_area[0], $this->plot_area[1],
-                                     $this->plot_area[2], $this->plot_area[3], $this->ndx_plot_bg_color);
-            }
-        }
-
-        return TRUE;
-    }
-
-
-    /*
-     * Tiles an image at some given coordinates.
-     *
-     * $file   string Filename of the picture to be used as tile.
-     * $xorig  int    X coordinate of the plot where the tile is to begin.
-     * $yorig  int    Y coordinate of the plot where the tile is to begin.
-     * $width  int    Width of the area to be tiled.
-     * $height int    Height of the area to be tiled.
-     * $mode   string One of 'centeredtile', 'tile', 'scale'.
-     */
-    protected function tile_img($file, $xorig, $yorig, $width, $height, $mode)
-    {
-        $im = $this->GetImage($file, $tile_width, $tile_height);
-        if (!$im)
-            return FALSE;  // GetImage already produced an error message.
-
-        if ($mode == 'scale') {
-            imagecopyresampled($this->img, $im, $xorig, $yorig, 0, 0, $width, $height,
-                               $tile_width, $tile_height);
-            return TRUE;
-        }
-
-        if ($mode == 'centeredtile') {
-            $x0 = - floor($tile_width/2);   // Make the tile look better
-            $y0 = - floor($tile_height/2);
-        } else {      // Accept anything else as $mode == 'tile'
-            $x0 = 0;
-            $y0 = 0;
-        }
-
-        // Actually draw the tile
-
-        // But first on a temporal image.
-        $tmp = imagecreate($width, $height);
-        if (! $tmp)
-            return $this->PrintError('tile_img(): Could not create image resource.');
-
-        for ($x = $x0; $x < $width; $x += $tile_width)
-            for ($y = $y0; $y < $height; $y += $tile_height)
-                imagecopy($tmp, $im, $x, $y, 0, 0, $tile_width, $tile_height);
-
-        // Copy the temporal image onto the final one.
-        imagecopy($this->img, $tmp, $xorig, $yorig, 0,0, $width, $height);
-
-        // Free resources
-        imagedestroy($tmp);
-        imagedestroy($im);
-
-        return TRUE;
-    }  // function tile_img
-
-
-    /*
-     * Return the image border width.
-     * This is used by CalcMargins() and DrawImageBorder().
-     */
-    protected function GetImageBorderWidth()
-    {
-        if ($this->image_border_type == 'none')
-            return 0; // No border
-        if (!empty($this->image_border_width))
-            return $this->image_border_width; // Specified border width
-        if ($this->image_border_type == 'raised')
-            return 2; // Default for raised border is 2 pixels.
-        return 1; // Default for other border types is 1 pixel.
-    }
-
-    /*
-     * Draws a border around the final image.
-     * Note: 'plain' draws a flat border using the dark shade of the border color.
-     * This probably should have been written to use the actual border color, but
-     * it is too late to fix it without changing plot appearances. Therefore a
-     * new type 'solid' was added to use the SetImageBorderColor color.
-     */
-    protected function DrawImageBorder()
-    {
-        if ($this->image_border_type == 'none')
-            return TRUE; // Early test for default case.
-        $width = $this->GetImageBorderWidth();
-        $color1 = $this->ndx_i_border;
-        $color2 = $this->ndx_i_border_dark;
-        $ex = $this->image_width - 1;
-        $ey = $this->image_height - 1;
-        switch ($this->image_border_type) {
-        case 'raised':
-            // Top and left lines use border color, right and bottom use the darker shade.
-            // Drawing order matters in the upper right and lower left corners.
-            for ($i = 0; $i < $width; $i++, $ex--, $ey--) {
-                imageline($this->img, $i,  $i,  $ex, $i,  $color1); // Top
-                imageline($this->img, $ex, $i,  $ex, $ey, $color2); // Right
-                imageline($this->img, $i,  $i,  $i,  $ey, $color1); // Left
-                imageline($this->img, $i,  $ey, $ex, $ey, $color2); // Bottom
-            }
-            break;
-        case 'plain': // See note above re colors
-            $color1 = $color2;
-            // Fall through
-        case 'solid':
-            for ($i = 0; $i < $width; $i++, $ex--, $ey--) {
-                imagerectangle($this->img, $i, $i, $ex, $ey, $color1);
-            }
-            break;
-        default:
-            return $this->PrintError("DrawImageBorder(): unknown image_border_type: '$this->image_border_type'");
-        }
-        return TRUE;
-    }
-
-
-    /*
-     * Draws the main title on the graph.
-     * The title must not be drawn more than once (in the case of multiple plots
-     * on the image), because TTF text antialiasing makes it look bad.
-     */
-    protected function DrawTitle()
-    {
-        if (isset($this->title_done) || $this->title_txt === '')
-            return TRUE;
-
-        // Center of the image:
-        $xpos = $this->image_width / 2;
-
-        // Place it at almost at the top
-        $ypos = $this->title_offset;
-
-        $this->DrawText($this->fonts['title'], 0, $xpos, $ypos,
-                        $this->ndx_title_color, $this->title_txt, 'center', 'top');
-
-        $this->title_done = TRUE;
-        return TRUE;
-    }
-
-
-    /*!
-     * Draws the X-Axis Title
-     */
-    protected function DrawXTitle()
-    {
-        if ($this->x_title_pos == 'none')
-            return TRUE;
-
-        // Center of the plot
-        $xpos = ($this->plot_area[2] + $this->plot_area[0]) / 2;
-
-        // Upper title
-        if ($this->x_title_pos == 'plotup' || $this->x_title_pos == 'both') {
-            $ypos = $this->plot_area[1] - $this->x_title_top_offset;
-            $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_title_color,
-                            $this->x_title_txt, 'center', 'bottom');
-        }
-        // Lower title
-        if ($this->x_title_pos == 'plotdown' || $this->x_title_pos == 'both') {
-            $ypos = $this->plot_area[3] + $this->x_title_bot_offset;
-            $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_title_color,
-                            $this->x_title_txt, 'center', 'top');
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Draws the Y-Axis Title
-     */
-    protected function DrawYTitle()
-    {
-        if ($this->y_title_pos == 'none')
-            return TRUE;
-
-        // Center the title vertically to the plot area
-        $ypos = ($this->plot_area[3] + $this->plot_area[1]) / 2;
-
-        if ($this->y_title_pos == 'plotleft' || $this->y_title_pos == 'both') {
-            $xpos = $this->plot_area[0] - $this->y_title_left_offset;
-            $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_title_color,
-                            $this->y_title_txt, 'right', 'center');
-        }
-        if ($this->y_title_pos == 'plotright' || $this->y_title_pos == 'both') {
-            $xpos = $this->plot_area[2] + $this->y_title_right_offset;
-            $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_title_color,
-                            $this->y_title_txt, 'left', 'center');
-        }
-
-        return TRUE;
-    }
-
-
-    /*
-     * \note Horizontal grid lines overwrite horizontal axis with y=0, so call this first, then DrawXAxis()
-     */
-    protected function DrawYAxis()
-    {
-        // Draw ticks, labels and grid, if any
-        $this->DrawYTicks();
-
-        // Draw Y axis at X = y_axis_x_pixels
-        ImageLine($this->img, $this->y_axis_x_pixels, $this->plot_area[1],
-                  $this->y_axis_x_pixels, $this->plot_area[3], $this->ndx_grid_color);
-
-        return TRUE;
-    }
-
-    /*
-     *
-     */
-    protected function DrawXAxis()
-    {
-        // Draw ticks, labels and grid
-        $this->DrawXTicks();
-
-        /* This tick and label tend to overlap with regular Y Axis labels,
-         * as Mike Pullen pointed out.
-         *
-        //Draw Tick and Label for X axis
-        if (! $this->skip_bottom_tick) {
-            $ylab =$this->FormatLabel('y', $this->x_axis_position);
-            $this->DrawYTick($ylab, $this->x_axis_y_pixels);
-        }
-        */
-        //Draw X Axis at Y = x_axis_y_pixels
-        ImageLine($this->img, $this->plot_area[0]+1, $this->x_axis_y_pixels,
-                  $this->plot_area[2]-1, $this->x_axis_y_pixels, $this->ndx_grid_color);
-
-        return TRUE;
-    }
-
-    /*!
-     * Draw one Y tick mark and its tick label. Called from DrawYTicks() and DrawXAxis()
-     */
-    protected function DrawYTick($which_ylab, $which_ypix)
-    {
-        // Ticks on Y axis
-        if ($this->y_tick_pos == 'yaxis') {
-            ImageLine($this->img, $this->y_axis_x_pixels - $this->y_tick_length, $which_ypix,
-                      $this->y_axis_x_pixels + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
-        }
-
-        // Ticks to the left of the Plot Area
-        if (($this->y_tick_pos == 'plotleft') || ($this->y_tick_pos == 'both') ) {
-            ImageLine($this->img, $this->plot_area[0] - $this->y_tick_length, $which_ypix,
-                      $this->plot_area[0] + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
-        }
-
-        // Ticks to the right of the Plot Area
-        if (($this->y_tick_pos == 'plotright') || ($this->y_tick_pos == 'both') ) {
-            ImageLine($this->img, $this->plot_area[2] + $this->y_tick_length, $which_ypix,
-                      $this->plot_area[2] - $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
-        }
-
-        // Labels on Y axis
-        if ($this->y_tick_label_pos == 'yaxis') {
-            $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
-                            $this->y_axis_x_pixels - $this->y_label_axis_offset, $which_ypix,
-                            $this->ndx_text_color, $which_ylab, 'right', 'center');
-        }
-
-        // Labels to the left of the plot area
-        if ($this->y_tick_label_pos == 'plotleft' || $this->y_tick_label_pos == 'both') {
-            $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
-                            $this->plot_area[0] - $this->y_label_left_offset, $which_ypix,
-                            $this->ndx_text_color, $which_ylab, 'right', 'center');
-        }
-        // Labels to the right of the plot area
-        if ($this->y_tick_label_pos == 'plotright' || $this->y_tick_label_pos == 'both') {
-            $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
-                            $this->plot_area[2] + $this->y_label_right_offset, $which_ypix,
-                            $this->ndx_text_color, $which_ylab, 'left', 'center');
-        }
-        return TRUE;
-    } // Function DrawYTick()
-
-
-    /*!
-     * Draws Grid, Ticks and Tick Labels along Y-Axis
-     * Ticks and ticklabels can be left of plot only, right of plot only,
-     * both on the left and right of plot, or crossing a user defined Y-axis
-     */
-    protected function DrawYTicks()
-    {
-        // Sets the line style for IMG_COLOR_STYLED lines (grid)
-        if ($this->dashed_grid) {
-            $this->SetDashedStyle($this->ndx_light_grid_color);
-            $style = IMG_COLOR_STYLED;
-        } else {
-            $style = $this->ndx_light_grid_color;
-        }
-
-        // Calculate the tick start, end, and step:
-        list($y_start, $y_end, $delta_y) = $this->CalcTicks('y');
-
-        // Loop, avoiding cumulative round-off errors from $y_tmp += $delta_y
-        $n = 0;
-        $y_tmp = $y_start;
-        while ($y_tmp <= $y_end) {
-            $ylab = $this->FormatLabel('y', $y_tmp);
-            $y_pixels = $this->ytr($y_tmp);
-
-            // Horizontal grid line
-            if ($this->draw_y_grid) {
-                ImageLine($this->img, $this->plot_area[0]+1, $y_pixels, $this->plot_area[2]-1, $y_pixels, $style);
-            }
-
-            // Draw tick mark(s)
-            $this->DrawYTick($ylab, $y_pixels);
-
-            // Step to next Y, without accumulating error
-            $y_tmp = $y_start + ++$n * $delta_y;
-        }
-        return TRUE;
-    } // function DrawYTicks
-
-    /*!
-     * Draw one X tick mark and its tick label.
-     */
-    protected function DrawXTick($which_xlab, $which_xpix)
-    {
-        // Ticks on X axis
-        if ($this->x_tick_pos == 'xaxis') {
-            ImageLine($this->img, $which_xpix, $this->x_axis_y_pixels - $this->x_tick_cross,
-                      $which_xpix, $this->x_axis_y_pixels + $this->x_tick_length, $this->ndx_tick_color);
-        }
-
-        // Ticks on top of the Plot Area
-        if ($this->x_tick_pos == 'plotup' || $this->x_tick_pos == 'both') {
-            ImageLine($this->img, $which_xpix, $this->plot_area[1] - $this->x_tick_length,
-                      $which_xpix, $this->plot_area[1] + $this->x_tick_cross, $this->ndx_tick_color);
-        }
-
-        // Ticks on bottom of Plot Area
-        if ($this->x_tick_pos == 'plotdown' || $this->x_tick_pos == 'both') {
-            ImageLine($this->img, $which_xpix, $this->plot_area[3] + $this->x_tick_length,
-                      $which_xpix, $this->plot_area[3] - $this->x_tick_cross, $this->ndx_tick_color);
-        }
-
-        // Label on X axis
-        if ($this->x_tick_label_pos == 'xaxis') {
-            $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
-                            $which_xpix, $this->x_axis_y_pixels + $this->x_label_axis_offset,
-                            $this->ndx_text_color, $which_xlab, 'center', 'top');
-        }
-
-        // Label on top of the Plot Area
-        if ($this->x_tick_label_pos == 'plotup' || $this->x_tick_label_pos == 'both') {
-            $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
-                            $which_xpix, $this->plot_area[1] - $this->x_label_top_offset,
-                            $this->ndx_text_color, $which_xlab, 'center', 'bottom');
-        }
-
-        // Label on bottom of the Plot Area
-        if ($this->x_tick_label_pos == 'plotdown' || $this->x_tick_label_pos == 'both') {
-            $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
-                            $which_xpix, $this->plot_area[3] + $this->x_label_bot_offset,
-                            $this->ndx_text_color, $which_xlab, 'center', 'top');
-        }
-        return TRUE;
-    }
-
-    /*!
-     * Draws Grid, Ticks and Tick Labels along X-Axis
-     * Ticks and tick labels can be down of plot only, up of plot only,
-     * both on up and down of plot, or crossing a user defined X-axis
-     *
-     * \note Original vertical code submitted by Marlin Viss
-     */
-    protected function DrawXTicks()
-    {
-        // Sets the line style for IMG_COLOR_STYLED lines (grid)
-        if ($this->dashed_grid) {
-            $this->SetDashedStyle($this->ndx_light_grid_color);
-            $style = IMG_COLOR_STYLED;
-        } else {
-            $style = $this->ndx_light_grid_color;
-        }
-
-        // Calculate the tick start, end, and step:
-        list($x_start, $x_end, $delta_x) = $this->CalcTicks('x');
-
-        // Loop, avoiding cumulative round-off errors from $x_tmp += $delta_x
-        $n = 0;
-        $x_tmp = $x_start;
-        while ($x_tmp <= $x_end) {
-            $xlab = $this->FormatLabel('x', $x_tmp);
-            $x_pixels = $this->xtr($x_tmp);
-
-            // Vertical grid lines
-            if ($this->draw_x_grid) {
-                ImageLine($this->img, $x_pixels, $this->plot_area[1], $x_pixels, $this->plot_area[3], $style);
-            }
-
-            // Draw tick mark(s)
-            $this->DrawXTick($xlab, $x_pixels);
-
-            // Step to next X, without accumulating error
-            $x_tmp = $x_start + ++$n * $delta_x;
-        }
-        return TRUE;
-    } // function DrawXTicks
-
-
-    /*
-     *  Draw a border around the plot area. See SetPlotBorderType.
-     *  Note: SetPlotBorderType sets plot_border_type to an array, but
-     *  it won't be an array if it defaults or is set directly (backward compatibility).
-     */
-    protected function DrawPlotBorder()
-    {
-        $pbt = (array)$this->plot_border_type;
-        $sides = 0;  // Bitmap: 1=left 2=top 4=right 8=bottom
-        $map = array('left' => 1, 'plotleft' => 1, 'right' => 4, 'plotright' => 4, 'top' => 2,
-                      'bottom' => 8, 'both' => 5, 'sides' => 5, 'full' => 15, 'none' => 0);
-        foreach ($pbt as $option) $sides |= $map[$option];
-        if ($sides == 15) { // Border on all 4 sides
-            imagerectangle($this->img, $this->plot_area[0], $this->plot_area[1],
-                           $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
-        } else {
-            if ($sides & 1) // Left
-                imageline($this->img, $this->plot_area[0], $this->plot_area[1],
-                                      $this->plot_area[0], $this->plot_area[3], $this->ndx_grid_color);
-            if ($sides & 2) // Top
-                imageline($this->img, $this->plot_area[0], $this->plot_area[1],
-                                      $this->plot_area[2], $this->plot_area[1], $this->ndx_grid_color);
-            if ($sides & 4) // Right
-                imageline($this->img, $this->plot_area[2], $this->plot_area[1],
-                                      $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
-            if ($sides & 8) // Bottom
-                imageline($this->img, $this->plot_area[0], $this->plot_area[3],
-                                      $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
-        }
-        return TRUE;
-    }
-
-
-    /*!
-     * Draws the data label associated with a point in the plot at specified x/y world position.
-     * This is currently only used for Y data labels for bar charts.
-     */
-    protected function DrawDataLabel($which_font, $which_angle, $x_world, $y_world, $which_color, $which_text,
-                      $which_halign = 'center', $which_valign = 'bottom', $x_adjustment=0, $y_adjustment=0)
-    {
-        $this->DrawText($which_font, $which_angle,
-                        $this->xtr($x_world) + $x_adjustment, $this->ytr($y_world) + $y_adjustment,
-                        $which_color, $this->FormatLabel('yd', $which_text), $which_halign, $which_valign);
-
-        return TRUE;
-    }
-
-    /*!
-     * Draws the data label associated with a point in the plot.
-     * This is different from x_labels drawn by DrawXTicks() and care
-     * should be taken not to draw both, as they'd probably overlap.
-     * Calling of this function in DrawLines(), etc is decided after x_data_label_pos value.
-     * Leave the last parameter out, to avoid the drawing of vertical lines, no matter
-     * what the setting is (for plots that need it, like DrawSquared())
-     */
-    protected function DrawXDataLabel($xlab, $xpos, $row=FALSE)
-    {
-        $xlab = $this->FormatLabel('xd', $xlab);
-
-        // Labels below the plot area
-        if ($this->x_data_label_pos == 'plotdown' || $this->x_data_label_pos == 'both')
-            $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle,
-                            $xpos, $this->plot_area[3] + $this->x_label_bot_offset,
-                            $this->ndx_text_color, $xlab, 'center', 'top');
-
-        // Labels above the plot area
-        if ($this->x_data_label_pos == 'plotup' || $this->x_data_label_pos == 'both')
-            $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle,
-                            $xpos, $this->plot_area[1] - $this->x_label_top_offset,
-                            $this->ndx_text_color, $xlab, 'center', 'bottom');
-
-        // $row=0 means this is the first row. $row=FALSE means don't do any rows.
-        if ($row !== FALSE && $this->draw_x_data_label_lines)
-            $this->DrawXDataLine($xpos, $row);
-        return TRUE;
-    }
-
-    /*
-     * Draw a data label along the Y axis or side.
-     * This is only used by horizontal bar charts.
-     */
-    protected function DrawYDataLabel($ylab, $ypos)
-    {
-        $ylab = $this->FormatLabel('yd', $ylab);
-
-        // Labels left of the plot area
-        if ($this->y_data_label_pos == 'plotleft' || $this->y_data_label_pos == 'both')
-            $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle,
-                            $this->plot_area[0] - $this->y_label_left_offset, $ypos,
-                            $this->ndx_text_color, $ylab, 'right', 'center');
-
-        // Labels right of the plot area
-        if ($this->y_data_label_pos == 'plotright' || $this->y_data_label_pos == 'both')
-            $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle,
-                            $this->plot_area[2] + $this->y_label_right_offset, $ypos,
-                            $this->ndx_text_color, $ylab, 'left', 'center');
-        return TRUE;
-    }
-
-    /*!
-     * Draws Vertical lines from data points up and down.
-     * Which lines are drawn depends on the value of x_data_label_pos,
-     * and whether this is at all done or not, on draw_x_data_label_lines
-     *
-     * \param xpos int position in pixels of the line.
-     * \param row int index of the data row being drawn.
-     */
-    protected function DrawXDataLine($xpos, $row)
-    {
-        // Sets the line style for IMG_COLOR_STYLED lines (grid)
-        if($this->dashed_grid) {
-            $this->SetDashedStyle($this->ndx_light_grid_color);
-            $style = IMG_COLOR_STYLED;
-        } else {
-            $style = $this->ndx_light_grid_color;
-        }
-
-        // Lines from the bottom up
-        if ($this->x_data_label_pos == 'both') {
-            ImageLine($this->img, $xpos, $this->plot_area[3], $xpos, $this->plot_area[1], $style);
-        }
-        // Lines from the bottom of the plot up to the max Y value at this X:
-        else if ($this->x_data_label_pos == 'plotdown' && isset($this->data_max[$row])) {
-            $ypos = $this->ytr($this->data_max[$row]);
-            ImageLine($this->img, $xpos, $ypos, $xpos, $this->plot_area[3], $style);
-        }
-        // Lines from the top of the plot down to the min Y value at this X:
-        else if ($this->x_data_label_pos == 'plotup' && isset($this->data_min[$row])) {
-            $ypos = $this->ytr($this->data_min[$row]);
-            ImageLine($this->img, $xpos, $this->plot_area[1], $xpos, $ypos, $style);
-        }
-        return TRUE;
-    }
-
-
-    /*!
-     * Draws the graph legend
-     *
-     * \note Base code submitted by Marlin Viss
-     */
-    protected function DrawLegend()
-    {
-        $font = &$this->fonts['legend'];
-
-        // Find maximum legend label line width.
-        $max_width = 0;
-        foreach ($this->legend as $line) {
-            list($width, $unused) = $this->SizeText($font, 0, $line);
-            if ($width > $max_width) $max_width = $width;
-        }
-
-        // Use the font parameters to size the color boxes:
-        $char_w = $font['width'];
-        $char_h = $font['height'];
-        $line_spacing = $this->GetLineSpacing($font);
-
-        // Normalize text alignment and colorbox alignment variables:
-        $text_align = isset($this->legend_text_align) ? $this->legend_text_align : 'right';
-        $colorbox_align = isset($this->legend_colorbox_align) ? $this->legend_colorbox_align : 'right';
-
-        // Sizing parameters:
-        $v_margin = $char_h/2;                   // Between vertical borders and labels
-        $dot_height = $char_h + $line_spacing;   // Height of the small colored boxes
-        // Overall legend box width e.g.: | space colorbox space text space |
-        // where colorbox and each space are 1 char width.
-        if ($colorbox_align != 'none') {
-            $width = $max_width + 4 * $char_w;
-            $draw_colorbox = True;
-        } else {
-            $width = $max_width + 2 * $char_w;
-            $draw_colorbox = False;
-        }
-
-        //////// Calculate box position
-        // User-defined position specified?
-        if ( !isset($this->legend_x_pos) || !isset($this->legend_y_pos)) {
-            // No, use default
-            $box_start_x = $this->plot_area[2] - $width - $this->safe_margin;
-            $box_start_y = $this->plot_area[1] + $this->safe_margin;
-        } elseif (isset($this->legend_xy_world)) {
-            // User-defined position in world-coordinates (See SetLegendWorld).
-            $box_start_x = $this->xtr($this->legend_x_pos);
-            $box_start_y = $this->ytr($this->legend_y_pos);
-            unset($this->legend_xy_world);
-        } else {
-            // User-defined position in pixel coordinates.
-            $box_start_x = $this->legend_x_pos;
-            $box_start_y = $this->legend_y_pos;
-        }
-
-        // Lower right corner
-        $box_end_y = $box_start_y + $dot_height*(count($this->legend)) + 2*$v_margin;
-        $box_end_x = $box_start_x + $width;
-
-        // Draw outer box
-        ImageFilledRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y, $this->ndx_bg_color);
-        ImageRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y, $this->ndx_grid_color);
-
-        $color_index = 0;
-        $max_color_index = count($this->ndx_data_colors) - 1;
-
-        // Calculate color box and text horizontal positions.
-        if (!$draw_colorbox) {
-            if ($text_align == 'left')
-                $x_pos = $box_start_x + $char_w;
-            else
-                $x_pos = $box_end_x - $char_w;
-        } elseif ($colorbox_align == 'left') {
-            $dot_left_x = $box_start_x + $char_w;
-            $dot_right_x = $dot_left_x + $char_w;
-            if ($text_align == 'left')
-                $x_pos = $dot_left_x + 2 * $char_w;
-            else
-                $x_pos = $box_end_x - $char_w;
-        } else {
-            $dot_left_x = $box_end_x - 2 * $char_w;
-            $dot_right_x = $dot_left_x + $char_w;
-            if ($text_align == 'left')
-                $x_pos = $box_start_x + $char_w;
-            else
-                $x_pos = $dot_left_x - $char_w;
-        }
-
-        // Calculate starting position of first text line.  The bottom of each color box
-        // lines up with the bottom (baseline) of its text line.
-        $y_pos = $box_start_y + $v_margin + $dot_height;
-
-        foreach ($this->legend as $leg) {
-            // Draw text with requested alignment:
-            $this->DrawText($font, 0, $x_pos, $y_pos, $this->ndx_text_color, $leg, $text_align, 'bottom');
-            if ($draw_colorbox) {
-                // Draw a box in the data color
-                $y1 = $y_pos - $dot_height + 1;
-                $y2 = $y_pos - 1;
-                ImageFilledRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2,
-                                     $this->ndx_data_colors[$color_index]);
-                // Draw a rectangle around the box
-                ImageRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2,
-                               $this->ndx_text_color);
-            }
-            $y_pos += $dot_height;
-
-            $color_index++;
-            if ($color_index > $max_color_index)
-                $color_index = 0;
-        }
-        return TRUE;
-    } // Function DrawLegend()
-
-
-/////////////////////////////////////////////
-////////////////////             PLOT DRAWING
-/////////////////////////////////////////////
-
-
-    /*!
-     * Draws a pie chart. Data is 'text-data', 'data-data', or 'text-data-single'.
-     *
-     *  For text-data-single, the data array contains records with an ignored label,
-     *  and one Y value. Each record defines a sector of the pie, as a portion of
-     *  the sum of all Y values.
-     *
-     *  For text-data and data-data, the data array contains records with an ignored label,
-     *  an ignored X value (for data-data only), and N (N>=1) Y values per record.
-     *  The pie chart will be produced with N segments. The relative size of the first
-     *  sector of the pie is the sum of the first Y data value in each record, etc.
-     *  
-     *  Note: With text-data-single, the data labels could be used, but are not currently.
-     *
-     *  If there are no valid data points > 0 at all, just draw nothing. It may seem more correct to
-     *  raise an error, but all of the other plot types handle it this way implicitly. DrawGraph
-     *  checks for an empty data array, but this is different: a non-empty data array with no Y values,
-     *  or all Y=0.
-     */
-    protected function DrawPieChart()
-    {
-        if (!$this->CheckDataType('text-data, text-data-single, data-data'))
-            return FALSE;
-
-        $xpos = $this->plot_area[0] + $this->plot_area_width/2;
-        $ypos = $this->plot_area[1] + $this->plot_area_height/2;
-        $diameter = min($this->plot_area_width, $this->plot_area_height);
-        $radius = $diameter/2;
-
-        if ($this->data_type == 'text-data') {
-            // Get sum of each column - One pie slice per column:
-            $num_slices = $this->records_per_group - 1;  // records_per_group is the maximum row size
-            if ($num_slices < 1) return TRUE;            // Give up early if there is no data at all.
-            $sumarr = array_fill(0, $num_slices, 0);
-            for ($i = 0; $i < $this->num_data_rows; $i++) {
-                for ($j = 1; $j < $this->num_recs[$i]; $j++) {  // Skip label at [0]
-                    if (is_numeric($this->data[$i][$j]))
-                        $sumarr[$j-1] += abs($this->data[$i][$j]);
-                }
-            }
-        } elseif ($this->data_type == 'text-data-single') {
-            // Or only one column per row, one pie slice per row:
-            $num_slices = $this->num_data_rows;
-            if ($num_slices < 1) return TRUE;            // Give up early if there is no data at all.
-            $sumarr = array_fill(0, $num_slices, 0);
-            for ($i = 0; $i < $num_slices; $i++) {
-                // $legend[$i] = $this->data[$i][0];                // Note: Labels are not used yet
-                if (is_numeric($this->data[$i][1]))
-                    $sumarr[$i] = abs($this->data[$i][1]);
-            }
-        } else {          // $this->data_type == 'data-data'
-            $num_slices = $this->records_per_group - 2;  // records_per_group is the maximum row size
-            if ($num_slices < 1) return TRUE;            // Give up early if there is no data at all.
-            $sumarr = array_fill(0, $num_slices, 0);
-            for ($i = 0; $i < $this->num_data_rows; $i++) {
-                for ($j = 2; $j < $this->num_recs[$i]; $j++) {  // Skip label at [0] an X and [1]
-                    if (is_numeric($this->data[$i][$j]))
-                        $sumarr[$j-2] += abs($this->data[$i][$j]);
-                }
-            }
-        }
-
-        $total = array_sum($sumarr);
-
-        if ($total == 0) {
-            // There are either no valid data points, or all are 0.
-            // See top comment about why not to make this an error.
-            return TRUE;
-        }
-
-        if ($this->shading) {
-            $diam2 = $diameter / 2;
-        } else {
-            $diam2 = $diameter;
-        }
-        $max_data_colors = count ($this->data_colors);
-
-        // Use the Y label format precision, with default value:
-        if (isset($this->label_format['y']['precision']))
-            $precision = $this->label_format['y']['precision'];
-        else
-            $precision = 1;
-
-
-        for ($h = $this->shading; $h >= 0; $h--) {
-            $color_index = 0;
-            $start_angle = 0;
-            $end_angle = 0;
-            for ($j = 0; $j < $num_slices; $j++) {
-                $val = $sumarr[$j];
-
-                // For shaded pies: the last one (at the top of the "stack") has a brighter color:
-                if ($h == 0)
-                    $slicecol = $this->ndx_data_colors[$color_index];
-                else
-                    $slicecol = $this->ndx_data_dark_colors[$color_index];
-
-                $label_txt = $this->number_format(($val / $total * 100), $precision) . '%';
-                $val = 360 * ($val / $total);
-
-                // NOTE that imagefilledarc measures angles CLOCKWISE (go figure why),
-                // so the pie chart would start clockwise from 3 o'clock, would it not be
-                // for the reversal of start and end angles in imagefilledarc()
-                // Also note ImageFilledArc only takes angles in integer degrees, and if the
-                // the start and end angles match then you get a full circle not a zero-width
-                // pie. This is bad. So skip any zero-size wedge. On the other hand, we cannot
-                // let cumulative error from rounding to integer result in missing wedges. So
-                // keep the running total as a float, and round the angles. It should not
-                // be necessary to check that the last wedge ends at 360 degrees.
-                $start_angle = $end_angle;
-                $end_angle += $val;
-                // This method of conversion to integer - truncate after reversing it - was
-                // chosen to match the implicit method of PHPlot<=5.0.4 to get the same slices.
-                $arc_start_angle = (int)(360 - $start_angle);
-                $arc_end_angle = (int)(360 - $end_angle);
-
-                if ($arc_start_angle > $arc_end_angle) {
-                    $mid_angle = deg2rad($end_angle - ($val / 2));
-
-                    // Draw the slice
-                    ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
-                                   $arc_end_angle, $arc_start_angle,
-                                   $slicecol, IMG_ARC_PIE);
-
-                    // Draw the labels only once
-                    if ($h == 0) {
-                        // Draw the outline
-                        if (! $this->shading)
-                            ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
-                                           $arc_end_angle, $arc_start_angle,
-                                           $this->ndx_grid_color, IMG_ARC_PIE | IMG_ARC_EDGED |IMG_ARC_NOFILL);
-
-
-                        // The '* 1.2' trick is to get labels out of the pie chart so there are more
-                        // chances they can be seen in small sectors.
-                        $label_x = $xpos + ($diameter * 1.2 * cos($mid_angle)) * $this->label_scale_position;
-                        $label_y = $ypos+$h - ($diam2 * 1.2 * sin($mid_angle)) * $this->label_scale_position;
-
-                        $this->DrawText($this->fonts['generic'], 0, $label_x, $label_y, $this->ndx_grid_color,
-                                        $label_txt, 'center', 'center');
-                    }
-                }
-                if (++$color_index >= $max_data_colors)
-                    $color_index = 0;
-            }   // end for
-        }   // end for
-        return TRUE;
-    }
-
-
-    /*
-     * Draw the points and errors bars for an error plot of types points and linepoints
-     * Supports only data-data-error format, with each row of the form
-     *   array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...)
-     * Note: plot type and data type were already checked by the calling function.
-     */
-    protected function DrawDotsError()
-    {
-        // Adjust the point shapes and point sizes arrays:
-        $this->CheckPointParams();
-
-        // Suppress duplicate X data labels in linepoints mode; let DrawLinesError() do them.
-        $do_labels = ($this->plot_type != 'linepoints');
-
-        for($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
-            $record = 1;                                // Skip record #0 (title)
-
-            $x_now = $this->data[$row][$record++];  // Read it, advance record index
-
-            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates.
-
-            // Draw X Data labels?
-            if ($this->x_data_label_pos != 'none' && $do_labels)
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
-            // Now go for Y, E+, E-
-            for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
-                if (is_numeric($this->data[$row][$record])) {         // Allow for missing Y data
-
-                    // Y:
-                    $y_now = $this->data[$row][$record++];
-                    $this->DrawDot($x_now, $y_now, $idx, $this->ndx_data_colors[$idx]);
-
-                    // Error +
-                    $val = $this->data[$row][$record++];
-                    $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape,
-                                         $this->ndx_error_bar_colors[$idx]);
-                    // Error -
-                    $val = $this->data[$row][$record++];
-                    $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape,
-                                         $this->ndx_error_bar_colors[$idx]);
-                } else {
-                    $record += 3;  // Skip over missing Y and its error values
-                }
-            }
-        }
-        return TRUE;
-    } // function DrawDotsError()
-
-
-    /*
-     * Draw the points for plots of type points and linepoints
-     * Supported data types:
-     *  - data-data ("title", x, y1, y2, y3, ...)
-     *  - text-data ("title", y1, y2, y3, ...)
-     */
-    protected function DrawDots()
-    {
-        if (!$this->CheckDataType('text-data, data-data'))
-            return FALSE;
-
-        // Adjust the point shapes and point sizes arrays:
-        $this->CheckPointParams();
-
-        // Suppress duplicate X data labels in linepoints mode; let DrawLines() do them.
-        $do_labels = ($this->plot_type != 'linepoints');
-
-        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
-            $rec = 1;                    // Skip record #0 (data label)
-
-            // Do we have a value for X?
-            if ($this->data_type == 'data-data')
-                $x_now = $this->data[$row][$rec++];  // Read it, advance record index
-            else
-                $x_now = 0.5 + $cnt++;       // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
-            $x_now_pixels = $this->xtr($x_now);
-
-            // Draw X Data labels?
-            if ($this->x_data_label_pos != 'none' && $do_labels)
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
-            // Proceed with Y values
-            for($idx = 0;$rec < $this->num_recs[$row]; $rec++, $idx++) {
-                if (is_numeric($this->data[$row][$rec])) {              // Allow for missing Y data
-                    $this->DrawDot($x_now, $this->data[$row][$rec],
-                                   $idx, $this->ndx_data_colors[$idx]);
-                }
-            }
-        }
-        return TRUE;
-    } //function DrawDots
-
-
-    /*
-     * Draw a Thin Bar Line plot, also known as an Impulse plot.
-     * A clean, fast routine for when you just want charts like stock volume charts
-     * Supports data-data and text-data formats.
-     */
-    protected function DrawThinBarLines()
-    {
-        if (!$this->CheckDataType('text-data, data-data'))
-            return FALSE;
-
-        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
-            $rec = 1;                    // Skip record #0 (data label)
-
-            // Do we have a value for X?
-            if ($this->data_type == 'data-data')
-                $x_now = $this->data[$row][$rec++];  // Read it, advance record index
-            else
-                $x_now = 0.5 + $cnt++;       // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
-            $x_now_pixels = $this->xtr($x_now);
-
-            // Draw X Data labels?
-            if ($this->x_data_label_pos != 'none')
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
-
-            // Proceed with Y values
-            for($idx = 0;$rec < $this->num_recs[$row]; $rec++, $idx++) {
-                if (is_numeric($this->data[$row][$rec])) {              // Allow for missing Y data
-                    ImageSetThickness($this->img, $this->line_widths[$idx]);
-                    // Draws a line from user defined x axis position up to ytr($val)
-                    ImageLine($this->img, $x_now_pixels, $this->x_axis_y_pixels, $x_now_pixels,
-                              $this->ytr($this->data[$row][$rec]), $this->ndx_data_colors[$idx]);
-                }
-            }
-        }
-
-        ImageSetThickness($this->img, 1);
-        return TRUE;
-    }  //function DrawThinBarLines
-
-    /*
-     *  Draw an Error Bar set. Used by DrawDotsError and DrawLinesError
-     */
-    protected function DrawYErrorBar($x_world, $y_world, $error_height, $error_bar_type, $color)
-    {
-        /*
-        // TODO: add a parameter to show datalabels next to error bars?
-        // something like this:
-        if ($this->x_data_label_pos == 'plot')
-            $this->DrawText($this->fonts['error'], 90, $x1, $y2,
-                            $color, $label, 'center', 'bottom');
-        */
-
-        $x1 = $this->xtr($x_world);
-        $y1 = $this->ytr($y_world);
-        $y2 = $this->ytr($y_world+$error_height) ;
-
-        ImageSetThickness($this->img, $this->error_bar_line_width);
-        ImageLine($this->img, $x1, $y1 , $x1, $y2, $color);
-
-        switch ($error_bar_type) {
-        case 'line':
-            break;
-        case 'tee':
-            ImageLine($this->img, $x1-$this->error_bar_size, $y2, $x1+$this->error_bar_size, $y2, $color);
-            break;
-        default:
-            ImageLine($this->img, $x1-$this->error_bar_size, $y2, $x1+$this->error_bar_size, $y2, $color);
-            break;
-        }
-
-        ImageSetThickness($this->img, 1);
-        return TRUE;
-    }
-
-    /*
-     * Draws a styled dot. Uses world coordinates.
-     * The list of supported shapes can also be found in SetPointShapes().
-     * All shapes are drawn using a 3x3 grid, centered on the data point.
-     * The center is (x_mid, y_mid) and the corners are (x1, y1) and (x2, y2).
-     *   $record is the 0-based index that selects the shape and size.
-     */
-    protected function DrawDot($x_world, $y_world, $record, $color)
-    {
-        $index = $record % $this->point_counts;
-        $point_size = $this->point_sizes[$index];
-
-        $half_point = (int)($point_size / 2);
-
-        $x_mid = $this->xtr($x_world);
-        $y_mid = $this->ytr($y_world);
-
-        $x1 = $x_mid - $half_point;
-        $x2 = $x_mid + $half_point;
-        $y1 = $y_mid - $half_point;
-        $y2 = $y_mid + $half_point;
-
-        switch ($this->point_shapes[$index]) {
-        case 'halfline':
-            ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color);
-            break;
-        case 'line':
-            ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
-            break;
-        case 'plus':
-            ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
-            ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color);
-            break;
-        case 'cross':
-            ImageLine($this->img, $x1, $y1, $x2, $y2, $color);
-            ImageLine($this->img, $x1, $y2, $x2, $y1, $color);
-            break;
-        case 'circle':
-            ImageArc($this->img, $x_mid, $y_mid, $point_size, $point_size, 0, 360, $color);
-            break;
-        case 'dot':
-            ImageFilledEllipse($this->img, $x_mid, $y_mid, $point_size, $point_size, $color);
-            break;
-        case 'diamond':
-            $arrpoints = array( $x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2);
-            ImageFilledPolygon($this->img, $arrpoints, 4, $color);
-            break;
-        case 'triangle':
-            $arrpoints = array( $x1, $y_mid, $x2, $y_mid, $x_mid, $y2);
-            ImageFilledPolygon($this->img, $arrpoints, 3, $color);
-            break;
-        case 'trianglemid':
-            $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y_mid);
-            ImageFilledPolygon($this->img, $arrpoints, 3, $color);
-            break;
-        case 'yield':
-            $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y2);
-            ImageFilledPolygon($this->img, $arrpoints, 3, $color);
-            break;
-        case 'delta':
-            $arrpoints = array( $x1, $y2, $x2, $y2, $x_mid, $y1);
-            ImageFilledPolygon($this->img, $arrpoints, 3, $color);
-            break;
-        case 'star':
-            ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
-            ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color);
-            ImageLine($this->img, $x1, $y1, $x2, $y2, $color);
-            ImageLine($this->img, $x1, $y2, $x2, $y1, $color);
-            break;
-        case 'hourglass':
-            $arrpoints = array( $x1, $y1, $x2, $y1, $x1, $y2, $x2, $y2);
-            ImageFilledPolygon($this->img, $arrpoints, 4, $color);
-            break;
-        case 'bowtie':
-            $arrpoints = array( $x1, $y1, $x1, $y2, $x2, $y1, $x2, $y2);
-            ImageFilledPolygon($this->img, $arrpoints, 4, $color);
-            break;
-        case 'target':
-            ImageFilledRectangle($this->img, $x1, $y1, $x_mid, $y_mid, $color);
-            ImageFilledRectangle($this->img, $x_mid, $y_mid, $x2, $y2, $color);
-            ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color);
-            break;
-        case 'box':
-            ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color);
-            break;
-        case 'home': /* As in: "home plate" (baseball), also looks sort of like a house. */
-            $arrpoints = array( $x1, $y2, $x2, $y2, $x2, $y_mid, $x_mid, $y1, $x1, $y_mid);
-            ImageFilledPolygon($this->img, $arrpoints, 5, $color);
-            break;
-        case 'up':
-            ImagePolygon($this->img, array($x_mid, $y1, $x2, $y2, $x1, $y2), 3, $color);
-            break;
-        case 'down':
-            ImagePolygon($this->img, array($x_mid, $y2, $x1, $y1, $x2, $y1), 3, $color);
-            break;
-        case 'none': /* Special case, no point shape here */
-            break;
-        default: /* Also 'rect' */
-            ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color);
-            break;
-        }
-        return TRUE;
-    }
-
-    /*
-     * Draw an 'area' or 'stacked area' plot.
-     * Both of these fill the area between lines, but in the stacked area graph the Y values
-     * are accumulated for each X, same as stacked bars. In the regular area graph, the areas
-     * are filled in order from the X axis up to each Y (so the Y values for each X need to be
-     * in decreasing order in this case).
-     * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
-     * Notes:
-     *   All Y values must be >= 0. (If any Y<0 the absolute value is used.)
-     *   Missing data points are NOT handled. (They are counted as 0.)
-     *   All rows must have the same number of Y points, or an error image will be produced.
-     */
-    protected function DrawArea($do_stacked = False)
-    {
-        if (!$this->CheckDataType('text-data, data-data'))
-            return FALSE;
-
-        $n = $this->num_data_rows;  // Number of X values
-
-        // These arrays store the device X and Y coordinates for all lines:
-        $xd = array();
-        $yd = array();
-        if ($this->data_type == 'data-data') { // Explicit X values?
-            $x_supplied = True;
-            $skip_index = 2;
-        } else {
-            $x_supplied = False;
-            $skip_index = 1;
-        }
-        $num_recs = max($this->num_recs);  // Number of 'records' (label + x + y's) for each X.
-        $num_points = $num_recs - $skip_index; // Number of Y values per X, max
-        $min_points = min($this->num_recs) - $skip_index; // To check for uniform number of Y values
-        if ($num_points != $min_points) {
-            return $this->PrintError("DrawArea(): Data array must contain the same number"
-                      . " of Y values for each X ($num_points != $min_points)");
-        }
-
-        // Calculate the Y value for each X, and store the device
-        // coordinates into the xd and yd arrays.
-        // For stacked area plots, the Y values accumulate.
-        for ($row = 0; $row < $n; $row++) {
-            $rec = 1;                                       // Skip record #0 (data label)
-
-            if ($x_supplied)
-                $x_now = $this->data[$row][$rec++];
-            else
-                $x_now = 0.5 + $row;
-
-            $x_now_pixels = $this->xtr($x_now);
-
-            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
-
-            // Store the X value.
-            // There is an artificial Y value at the axis. For 'area' it goes
-            // at the end; for stackedarea it goes before the start.
-            $xd[$row] = $x_now_pixels;
-            $yd[$row] = array();
-            if ($do_stacked)
-                $yd[$row][] = $this->x_axis_y_pixels;
-
-            // Store the Y values for this X.
-            // All Y values are clipped to the x axis which should be zero but can be moved.
-            $y = 0;
-            while ($rec < $num_recs) {
-                if (is_numeric($this->data[$row][$rec])) {  // Treat missing values as 0.
-                    $y += abs($this->data[$row][$rec]);
-                }
-                $yd[$row][] = $this->ytr(max($this->x_axis_position, $y));
-                if (!$do_stacked) $y = 0;
-                $rec++;
-            }
-
-            if (!$do_stacked)
-                $yd[$row][] = $this->x_axis_y_pixels;
-        }
-
-        // Now draw the filled polygons.
-        $prev_row = 0;
-        for ($row = 1; $row <= $num_points; $row++) { // 1 extra for X axis artificial row
-            $pts = array();
-            // Previous data set forms top (for area) or bottom (for stackedarea):
-            for ($j = 0; $j < $n; $j++) {
-                $pts[] = $xd[$j];
-                $pts[] = $yd[$j][$prev_row];
-            }
-            // Current data set forms bottom (for area) or top (for stackedarea):
-            for ($j = $n- 1; $j >= 0; $j--) {
-                $pts[] = $xd[$j];
-                $pts[] = $yd[$j][$row];
-            }
-            // Draw it:
-            ImageFilledPolygon($this->img, $pts, $n * 2, $this->ndx_data_colors[$prev_row]);
-
-            $prev_row = $row;
-        }
-        return TRUE;
-    } // function DrawArea()
-
-
-    /*
-     * Draw a Line plot
-     * Supported data-types are 'data-data' and 'text-data'.
-     */
-    protected function DrawLines()
-    {
-        if (!$this->CheckDataType('text-data, data-data'))
-            return FALSE;
-
-        // Flag array telling if the current point is valid, one element per plot line.
-        // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point.
-        $start_lines = array_fill(0, $this->records_per_group, FALSE);
-
-        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
-            $record = 1;                                    // Skip record #0 (data label)
-
-            if ($this->data_type == 'data-data')            // Do we have a value for X?
-                $x_now = $this->data[$row][$record++];      // Read it, advance record index
-            else
-                $x_now = 0.5 + $cnt++;                      // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
-            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates
-
-            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
-            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
-                if (($line_style = $this->line_styles[$idx]) == 'none')
-                    continue; //Allow suppressing entire line, useful with linepoints
-                if (is_numeric($this->data[$row][$record])) {           //Allow for missing Y data
-                    $y_now_pixels = $this->ytr($this->data[$row][$record]);
-
-                    if ($start_lines[$idx]) {
-                        // Set line width, revert it to normal at the end
-                        ImageSetThickness($this->img, $this->line_widths[$idx]);
-
-                        if ($line_style == 'dashed') {
-                            $this->SetDashedStyle($this->ndx_data_colors[$idx]);
-                            ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
-                                      IMG_COLOR_STYLED);
-                        } else {
-                            ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
-                                      $this->ndx_data_colors[$idx]);
-                        }
-
-                    }
-                    $lasty[$idx] = $y_now_pixels;
-                    $lastx[$idx] = $x_now_pixels;
-                    $start_lines[$idx] = TRUE;
-                }
-                // Y data missing... should we leave a blank or not?
-                else if ($this->draw_broken_lines) {
-                    $start_lines[$idx] = FALSE;
-                }
-            }   // end for
-        }   // end for
-
-        ImageSetThickness($this->img, 1);       // Revert to original state for lines to be drawn later.
-        return TRUE;
-    } // function DrawLines()
-
-
-    /*
-     * Draw lines with error bars for an error plot of types lines and linepoints
-     * Supports only data-data-error format, with each row of the form
-     *   array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...)
-     * Note: plot type and data type were already checked by the calling function.
-     */
-    protected function DrawLinesError()
-    {
-        $start_lines = array_fill(0, $this->records_per_group, FALSE);
-
-        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
-            $record = 1;                                    // Skip record #0 (data label)
-
-            $x_now = $this->data[$row][$record++];          // Read X value, advance record index
-
-            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates.
-
-
-            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
-            // Now go for Y, E+, E-
-            for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
-                if (($line_style = $this->line_styles[$idx]) == 'none')
-                    continue; //Allow suppressing entire line, useful with linepoints
-                if (is_numeric($this->data[$row][$record])) {    // Allow for missing Y data
-
-                    // Y
-                    $y_now = $this->data[$row][$record++];
-                    $y_now_pixels = $this->ytr($y_now);
-
-                    if ($start_lines[$idx]) {
-                        ImageSetThickness($this->img, $this->line_widths[$idx]);
-
-                        if ($line_style == 'dashed') {
-                            $this->SetDashedStyle($this->ndx_data_colors[$idx]);
-                            ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
-                                      IMG_COLOR_STYLED);
-                        } else {
-                            ImageLine($this->img, $x_now_pixels, $y_now_pixels, $lastx[$idx], $lasty[$idx],
-                                      $this->ndx_data_colors[$idx]);
-                        }
-                    }
-
-                    // Error+
-                    $val = $this->data[$row][$record++];
-                    $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape,
-                                         $this->ndx_error_bar_colors[$idx]);
-
-                    // Error-
-                    $val = $this->data[$row][$record++];
-                    $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape,
-                                         $this->ndx_error_bar_colors[$idx]);
-
-                    // Update indexes:
-                    $start_lines[$idx] = TRUE;   // Tells us if we already drew the first column of points,
-                                             // thus having $lastx and $lasty ready for the next column.
-                    $lastx[$idx] = $x_now_pixels;
-                    $lasty[$idx] = $y_now_pixels;
-
-                } else {
-                    $record += 3;  // Skip over missing Y and its error values
-                    if ($this->draw_broken_lines) {
-                        $start_lines[$idx] = FALSE;
-                    }
-                }
-            }   // end for
-        }   // end for
-
-        ImageSetThickness($this->img, 1);   // Revert to original state for lines to be drawn later.
-        return TRUE;
-    }   // function DrawLinesError()
-
-
-
-    /*
-     * Draw a Squared Line plot.
-     * Supported data-types are 'data-data' and 'text-data'.
-     * This is based on DrawLines(), with one more line drawn for each point.
-     */
-    protected function DrawSquared()
-    {
-        if (!$this->CheckDataType('text-data, data-data'))
-            return FALSE;
-
-        // Flag array telling if the current point is valid, one element per plot line.
-        // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point.
-        $start_lines = array_fill(0, $this->records_per_group, FALSE);
-
-        for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
-            $record = 1;                                    // Skip record #0 (data label)
-
-            if ($this->data_type == 'data-data')            // Do we have a value for X?
-                $x_now = $this->data[$row][$record++];      // Read it, advance record index
-            else
-                $x_now = 0.5 + $cnt++;                      // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
-            $x_now_pixels = $this->xtr($x_now);             // Absolute coordinates
-
-            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); // notice there is no last param.
-
-            // Draw Lines
-            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
-                if (is_numeric($this->data[$row][$record])) {               // Allow for missing Y data
-                    $y_now_pixels = $this->ytr($this->data[$row][$record]);
-
-                    if ($start_lines[$idx] == TRUE) {
-                        // Set line width, revert it to normal at the end
-                        ImageSetThickness($this->img, $this->line_widths[$idx]);
-
-                        if ($this->line_styles[$idx] == 'dashed') {
-                            $this->SetDashedStyle($this->ndx_data_colors[$idx]);
-                            ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx],
-                                      IMG_COLOR_STYLED);
-                            ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels,
-                                      IMG_COLOR_STYLED);
-                        } else {
-                            ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx],
-                                      $this->ndx_data_colors[$idx]);
-                            ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels,
-                                      $this->ndx_data_colors[$idx]);
-                        }
-                    }
-                    $lastx[$idx] = $x_now_pixels;
-                    $lasty[$idx] = $y_now_pixels;
-                    $start_lines[$idx] = TRUE;
-                }
-                // Y data missing... should we leave a blank or not?
-                else if ($this->draw_broken_lines) {
-                    $start_lines[$idx] = FALSE;
-                }
-            }
-        }   // end while
-
-        ImageSetThickness($this->img, 1);
-        return TRUE;
-    } // function DrawSquared()
-
-
-    /*
-     * Draw a Bar chart
-     * Supports only text-data format, with each row in the form array("title", y1, y2, y3, ...)
-     */
-    protected function DrawBars()
-    {
-        if (!$this->CheckDataType('text-data'))
-            return False;
-
-        // This is the X offset from the bar group's label center point to the left side of the first bar
-        // in the group. See also CalcBarWidths above.
-        $x_first_bar = (($this->records_per_group - 1) * $this->record_bar_width) / 2 - $this->bar_adjust_gap;
-
-        for ($row = 0; $row < $this->num_data_rows; $row++) {
-            $record = 1;                                    // Skip record #0 (data label)
-
-            $x_now_pixels = $this->xtr(0.5 + $row);         // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
-            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
-
-            // Lower left X of first bar in the group:
-            $x1 = $x_now_pixels - $x_first_bar;
-
-            // Draw the bars in the group:
-            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
-                if (is_numeric($this->data[$row][$record])) {       // Allow for missing Y data
-                    $x2 = $x1 + $this->actual_bar_width;
-
-                    if ($this->data[$row][$record] < $this->x_axis_position) {
-                        $y1 = $this->x_axis_y_pixels;
-                        $y2 = $this->ytr($this->data[$row][$record]);
-                        $upgoing_bar = False;
-                    } else {
-                        $y1 = $this->ytr($this->data[$row][$record]);
-                        $y2 = $this->x_axis_y_pixels;
-                        $upgoing_bar = True;
-                    }
-
-                    // Draw the bar
-                    ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $this->ndx_data_colors[$idx]);
-
-                    if ($this->shading) {                           // Draw the shade?
-                        ImageFilledPolygon($this->img, array($x1, $y1,
-                                                       $x1 + $this->shading, $y1 - $this->shading,
-                                                       $x2 + $this->shading, $y1 - $this->shading,
-                                                       $x2 + $this->shading, $y2 - $this->shading,
-                                                       $x2, $y2,
-                                                       $x2, $y1),
-                                           6, $this->ndx_data_dark_colors[$idx]);
-                    }
-                    // Or draw a border?
-                    else {
-                        ImageRectangle($this->img, $x1, $y1, $x2,$y2, $this->ndx_data_border_colors[$idx]);
-                    }
-
-                    // Draw optional data labels above the bars (or below, for negative values).
-                    if ( $this->y_data_label_pos == 'plotin') {
-                        if ($upgoing_bar) {
-                          $v_align = 'bottom';
-                          $y_offset = -5 - $this->shading;
-                        } else {
-                          $v_align = 'top';
-                          $y_offset = 2;
-                        }
-                        $this->DrawDataLabel($this->fonts['y_label'], $this->y_data_label_angle,
-                                $row+0.5, $this->data[$row][$record], $this->ndx_title_color,
-                                $this->data[$row][$record], 'center', $v_align,
-                                ($idx + 0.5) * $this->record_bar_width - $x_first_bar, $y_offset);
-                    }
-
-                }
-                // Step to next bar in group:
-                $x1 += $this->record_bar_width;
-            }   // end for
-        }   // end for
-        return TRUE;
-    } //function DrawBars
-
-    /*
-     * Draw a Horizontal Bar chart
-     * Supports only text-data-yx format, with each row in the form array("title", x1, x2, x3, ...)
-     * This is an unusual case, because the data values are X not Y.
-     * Note: plot type and data type were already checked by the calling function.
-     */
-    protected function DrawHorizBars()
-    {
-        // This is the Y offset from the bar group's label center point to the bottom of the first bar
-        // in the group. See also CalcBarWidths above.
-        $y_first_bar = (($this->records_per_group - 1) * $this->record_bar_width) / 2 - $this->bar_adjust_gap;
-
-        for ($row = 0; $row < $this->num_data_rows; $row++) {
-            $record = 1;                                    // Skip record #0 (data label)
-
-            $y_now_pixels = $this->ytr(0.5 + $row);         // Place bars at Y=0.5, 1.5, 2.5, etc...
-
-            if ($this->y_data_label_pos != 'none')          // Draw Y Data Labels?
-                $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels);
-
-            // Lower left Y of first bar in the group:
-            $y1 = $y_now_pixels + $y_first_bar;
-
-            // Draw the bars in the group:
-            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
-                if (is_numeric($this->data[$row][$record])) {       // Allow for missing X data
-                    $y2 = $y1 - $this->actual_bar_width;
-
-                    if ($this->data[$row][$record] < $this->y_axis_position) {
-                        $x1 = $this->y_axis_x_pixels;
-                        $x2 = $this->xtr($this->data[$row][$record]);
-                        $rightwards_bar = False;
-                    } else {
-                        $x1 = $this->xtr($this->data[$row][$record]);
-                        $x2 = $this->y_axis_x_pixels;
-                        $rightwards_bar = True;
-                    }
-
-                    // Draw the bar
-                    ImageFilledRectangle($this->img, $x2, $y2, $x1, $y1, $this->ndx_data_colors[$idx]);
-
-                    if ($this->shading) {                           // Draw the shade?
-                        ImageFilledPolygon($this->img, array($x2, $y2,
-                                                       $x2 + $this->shading, $y2 - $this->shading,
-                                                       $x1 + $this->shading, $y2 - $this->shading,
-                                                       $x1 + $this->shading, $y1 - $this->shading,
-                                                       $x1, $y1,
-                                                       $x1, $y2),
-                                           6, $this->ndx_data_dark_colors[$idx]);
-                    }
-                    // Or draw a border?
-                    else {
-                        ImageRectangle($this->img, $x1, $y1, $x2,$y2, $this->ndx_data_border_colors[$idx]);
-                    }
-
-                    // Draw optional data labels above the bars (or below, for negative values).
-                    // DELETED
-
-                }
-                // Step to next bar in group:
-                $y1 -= $this->record_bar_width;
-            }   // end for
-        }   // end for
-
-        return TRUE;
-    }
-
-    /*
-     * Draw a Stacked Bar chart
-     * Supports only text-data format, with each row in the form array("title", y1, y2, y3, ...)
-     * Original stacked bars idea by Laurent Kruk < lolok at users.sourceforge.net >
-     */
-    protected function DrawStackedBars()
-    {
-        if (!$this->CheckDataType('text-data'))
-            return False;
-
-        // This is the X offset from the bar's label center point to the left side of the bar.
-        $x_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap;
-
-        // Copy shading value to local variable
-        $shade = $this->shading;
-
-        // Determine if any data labels are on:
-        if ($this->y_data_label_pos == 'plotin') {
-            $data_labels_above = True;
-            $data_labels_within = False;
-        } elseif ($this->y_data_label_pos == 'plotstack') {
-            $data_labels_above = True;
-            $data_labels_within = True;
-            // Get the text label height, plus a little bit, so we can omit labels in
-            // segments that are too short for the label to fit.
-            $data_labels_min_height = $this->fonts['y_label']['height'] + 2;
-        } else {
-            $data_labels_above = False;
-            $data_labels_within = False;
-        }
-        if ($data_labels_above || $data_labels_within) {
-            $data_label_y_offset = -5 - $shade;
-        }
-
-        for ($row = 0; $row < $this->num_data_rows; $row++) {
-            $record = 1;                                    // Skip record #0 (data label)
-
-            $x_now_pixels = $this->xtr(0.5 + $row);         // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
-            if ($this->x_data_label_pos != 'none')          // Draw X Data labels?
-                $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
-
-            // Lower left and lower right X of the bars in this stack:
-            $x1 = $x_now_pixels - $x_first_bar;
-            $x2 = $x1 + $this->actual_bar_width;
-
-            // Draw the bar segments in this stack. The first segment is drawn from the X axis to Y1.
-            // Each additional segment is drawn from the top of the previous segment to the new
-            // cumulative Y. Skip over any segment of 0 size or part below the X axis.
-            $wy1 = 0;                       // World coordinates Y1, upper value
-            $wy2 = $this->x_axis_position;  // World coordinates Y2, lower value
-
-            for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
-
-                // Skip missing Y values, and ignore Y=0 values.
-                if (is_numeric($this->data[$row][$record])
-                    && ($this_y = abs($this->data[$row][$record])) > 0) {
-
-                    $wy1 += $this_y;  // Accumulate Y value in world coordinates - top of current segment.
-
-                    // Draw nothing if top of segment is below X axis.
-                    // Bottom (wy2) will not go below X axis, so we will get a partial
-                    // segment from X axis up if the segment would cross the X axis.
-                    if ($wy1 > $this->x_axis_position) {
-
-                        $y1 = $this->ytr($wy1);
-                        $y2 = $this->ytr($wy2);
-
-                        // Draw the bar
-                        ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $this->ndx_data_colors[$idx]);
-
-                        if ($shade > 0) {                           // Draw the shade?
-                            ImageFilledPolygon($this->img,
-                                               array($x1, $y1, $x1 + $shade, $y1 - $shade,
-                                                     $x2 + $shade, $y1 - $shade, $x2 + $shade, $y2 - $shade,
-                                                     $x2, $y2, $x2, $y1),
-                                               6, $this->ndx_data_dark_colors[$idx]);
-                        } else {        // Or draw a border?
-                            ImageRectangle($this->img, $x1, $y1, $x2,$y2, $this->ndx_data_border_colors[$idx]);
-                        }
-
-                        // Draw optional data label for this bar segment just below the line.
-                        // Text value is the current Y, but position is the cumulative Y.
-                        // Skip the label if the segment is too short for the label to fit.
-                        if ($data_labels_within && ($y2 - $y1) >= $data_labels_min_height) {
-                            $this->DrawDataLabel($this->fonts['y_label'], $this->y_data_label_angle,
-                                    $row+0.5, $wy1, $this->ndx_title_color,
-                                    $this_y, 'center', 'top', 0, 3);
-                        }
-                    }
-                    // Make the top of this segment become the bottom of the next segment, but not if
-                    // it is still below the X axis.
-                    $wy2 = max($this->x_axis_position, $wy1);
-                }
-            }   // end for
-
-            // Draw optional data label above the bar with the total value.
-            // Value is wy1, but position is wy2. This only makes a difference when
-            // the stacked bar ends completely below the X axis. Then we see the actual
-            // cumulative value (wy1), positioned above the axis, with no bar at all.
-            if ($data_labels_above) {
-                $this->DrawDataLabel($this->fonts['y_label'], $this->y_data_label_angle,
-                        $row+0.5, $wy2, $this->ndx_title_color,
-                        $wy1, 'center', 'bottom', 0, $data_label_y_offset);
-            }
-        }   // end for
-        return TRUE;
-    } //function DrawStackedBars
-
-
-    /*
-     * Draw the graph.
-     * This is the function that performs the actual drawing, after all
-     * the parameters and data are set up.
-     * It also outputs the finished image, unless told not to.
-     */
-    function DrawGraph()
-    {
-        // Test for missing image, missing data, empty data:
-        if (! $this->img) {
-            return $this->PrintError('DrawGraph(): No image resource allocated');
-        }
-        if (empty($this->data) || ! is_array($this->data)) {
-            return $this->PrintError("DrawGraph(): No data array");
-        }
-        if ($this->total_records == 0) {
-            return $this->PrintError('DrawGraph(): Empty data set');
-        }
-
-        // For pie charts: don't draw grid or border or axes, and maximize area usage.
-        // These controls can be split up in the future if needed.
-        $draw_axes = ($this->plot_type != 'pie');
-
-        // Get maxima and minima for scaling:
-        if (!$this->FindDataLimits())
-            return FALSE;
-
-        // Set plot area world values (plot_max_x, etc.):
-        if (!$this->CalcPlotAreaWorld())
-            return FALSE;
-
-        // Calculate X and Y axis positions in World Coordinates:
-        $this->CalcAxisPositions();
-
-        // Process label-related parameters:
-        $this->CheckLabels();
-
-        // Apply grid defaults:
-        $this->CalcGridSettings();
-
-        // Calculate the plot margins, if needed.
-        // For pie charts, set the $maximize argument to maximize space usage.
-        $this->CalcMargins(!$draw_axes);
-
-        // Calculate the actual plot area in device coordinates:
-        $this->CalcPlotAreaPixels();
-
-        // Calculate the mapping between world and device coordinates:
-        $this->CalcTranslation();
-
-        // Pad color and style arrays to fit records per group:
-        $this->PadArrays();
-        $this->DoCallback('draw_setup');
-
-        $this->DrawBackground();
-        $this->DrawImageBorder();
-        $this->DoCallback('draw_image_background');
-
-        $this->DrawPlotAreaBackground();
-        $this->DoCallback('draw_plotarea_background', $this->plot_area);
-
-        $this->DrawTitle();
-        if ($draw_axes) {  // If no axes (pie chart), no axis titles either
-            $this->DrawXTitle();
-            $this->DrawYTitle();
-        }
-        $this->DoCallback('draw_titles');
-
-        if ($draw_axes && ! $this->grid_at_foreground) {   // Usually one wants grids to go back, but...
-            $this->DrawYAxis();     // Y axis must be drawn before X axis (see DrawYAxis())
-            $this->DrawXAxis();
-            $this->DoCallback('draw_axes');
-        }
-
-        switch ($this->plot_type) {
-        case 'thinbarline':
-            $this->DrawThinBarLines();
-            break;
-        case 'area':
-            $this->DrawArea();
-            break;
-        case 'squared':
-            $this->DrawSquared();
-            break;
-        case 'lines':
-            if ( $this->data_type == 'data-data-error') {
-                $this->DrawLinesError();
-            } else {
-                $this->DrawLines();
-            }
-            break;
-        case 'linepoints':
-            if ( $this->data_type == 'data-data-error') {
-                $this->DrawLinesError();
-                $this->DrawDotsError();
-            } else {
-                $this->DrawLines();
-                $this->DrawDots();
-            }
-            break;
-        case 'points';
-            if ( $this->data_type == 'data-data-error') {
-                $this->DrawDotsError();
-            } else {
-                $this->DrawDots();
-            }
-            break;
-        case 'pie':
-            $this->DrawPieChart();
-            break;
-        case 'stackedbars':
-            $this->CalcBarWidths();
-            $this->DrawStackedBars();
-            break;
-        case 'stackedarea':
-            $this->DrawArea(True);
-            break;
-        // case 'bars':
-        default:
-            $this->plot_type = 'bars';  // Make sure it is set
-            if ($this->data_type == 'text-data-yx') {
-                $this->CalcBarWidths(False);
-                $this->DrawHorizBars();
-            } else {
-                $this->CalcBarWidths();
-                $this->DrawBars();
-            }
-            break;
-        }   // end switch
-        $this->DoCallback('draw_graph', $this->plot_area);
-
-        if ($draw_axes && $this->grid_at_foreground) {   // Usually one wants grids to go back, but...
-            $this->DrawYAxis();     // Y axis must be drawn before X axis (see DrawYAxis())
-            $this->DrawXAxis();
-            $this->DoCallback('draw_axes');
-        }
-
-        if ($draw_axes) {
-            $this->DrawPlotBorder();
-            $this->DoCallback('draw_border');
-        }
-
-        if ($this->legend) {
-            $this->DrawLegend();
-            $this->DoCallback('draw_legend');
-        }
-        $this->DoCallback('draw_all', $this->plot_area);
-
-        if ($this->print_image && !$this->PrintImage())
-            return FALSE;
-
-        return TRUE;
-    } //function DrawGraph()
-
-/////////////////////////////////////////////
-//////////////////         DEPRECATED METHODS
-/////////////////////////////////////////////
-
-    /*!
-     * Deprecated, use SetYTickPos()
-     */
-    function SetDrawVertTicks($which_dvt)
-    {
-        if ($which_dvt != 1)
-            $this->SetYTickPos('none');
-        return TRUE;
-    }
-
-    /*!
-     * Deprecated, use SetXTickPos()
-     */
-    function SetDrawHorizTicks($which_dht)
-    {
-        if ($which_dht != 1)
-           $this->SetXTickPos('none');
-        return TRUE;
-    }
-
-    /*!
-     * \deprecated Use SetNumXTicks()
-     */
-    function SetNumHorizTicks($n)
-    {
-        return $this->SetNumXTicks($n);
-    }
-
-    /*!
-     * \deprecated Use SetNumYTicks()
-     */
-    function SetNumVertTicks($n)
-    {
-        return $this->SetNumYTicks($n);
-    }
-
-    /*!
-     * \deprecated Use SetXTickIncrement()
-     */
-    function SetHorizTickIncrement($inc)
-    {
-        return $this->SetXTickIncrement($inc);
-    }
-
-
-    /*!
-     * \deprecated Use SetYTickIncrement()
-     */
-    function SetVertTickIncrement($inc)
-    {
-        return $this->SetYTickIncrement($inc);
-    }
-
-    /*!
-     * \deprecated Use SetYTickPos()
-     */
-    function SetVertTickPosition($which_tp)
-    {
-        return $this->SetYTickPos($which_tp);
-    }
-
-    /*!
-     * \deprecated Use SetXTickPos()
-     */
-    function SetHorizTickPosition($which_tp)
-    {
-        return $this->SetXTickPos($which_tp);
-    }
-
-    /*!
-     * \deprecated Use SetFont()
-     */
-    function SetTitleFontSize($which_size)
-    {
-        return $this->SetFont('title', $which_size);
-    }
-
-    /*!
-     * \deprecated Use SetFont()
-     */
-    function SetAxisFontSize($which_size)
-    {
-        $this->SetFont('x_label', $which_size);
-        $this->SetFont('y_label', $which_size);
-    }
-
-    /*!
-     * \deprecated Use SetFont()
-     */
-    function SetSmallFontSize($which_size)
-    {
-        return $this->SetFont('generic', $which_size);
-    }
-
-    /*!
-     * \deprecated Use SetFont()
-     */
-    function SetXLabelFontSize($which_size)
-    {
-        return $this->SetFont('x_title', $which_size);
-    }
-
-    /*!
-     * \deprecated Use SetFont()
-     */
-    function SetYLabelFontSize($which_size)
-    {
-        return $this->SetFont('y_title', $which_size);
-    }
-
-    /*!
-     * \deprecated Use SetXTitle()
-     */
-    function SetXLabel($which_xlab)
-    {
-        return $this->SetXTitle($which_xlab);
-    }
-
-    /*!
-     * \deprecated Use SetYTitle()
-     */
-    function SetYLabel($which_ylab)
-    {
-        return $this->SetYTitle($which_ylab);
-    }
-
-    /*!
-     * \deprecated Use SetXTickLength() and SetYTickLength() instead.
-     */
-    function SetTickLength($which_tl)
-    {
-        $this->SetXTickLength($which_tl);
-        $this->SetYTickLength($which_tl);
-        return TRUE;
-    }
-
-    /*!
-     * \deprecated  Use SetYLabelType()
-     */
-    function SetYGridLabelType($which_yglt)
-    {
-        return $this->SetYLabelType($which_yglt);
-    }
-
-    /*!
-     * \deprecated  Use SetXLabelType()
-     */
-    function SetXGridLabelType($which_xglt)
-    {
-        return $this->SetXLabelType($which_xglt);
-    }
-    /*!
-     * \deprecated Use SetYTickLabelPos()
-     */
-    function SetYGridLabelPos($which_yglp)
-    {
-        return $this->SetYTickLabelPos($which_yglp);
-    }
-    /*!
-     * \deprecated Use SetXTickLabelPos()
-     */
-    function SetXGridLabelPos($which_xglp)
-    {
-        return $this->SetXTickLabelPos($which_xglp);
-    }
-
-
-    /*!
-     * \deprecated Use SetXtitle()
-     */
-    function SetXTitlePos($xpos)
-    {
-        $this->x_title_pos = $xpos;
-        return TRUE;
-    }
-
-    /*!
-     * \deprecated Use SetYTitle()
-     */
-    function SetYTitlePos($xpos)
-    {
-        $this->y_title_pos = $xpos;
-        return TRUE;
-    }
-
-    /*!
-     * Draw Labels (not grid labels) on X Axis, following data points. Default position is
-     * down of plot. Care must be taken not to draw these and x_tick_labels as they'd probably overlap.
-     *
-     * \deprecated Use SetXDataLabelPos()
-     */
-    function SetDrawXDataLabels($which_dxdl)
-    {
-        if ($which_dxdl == '1' )
-            $this->SetXDataLabelPos('plotdown');
-        else
-            $this->SetXDataLabelPos('none');
-    }
-
-    /*!
-     * \deprecated
-     */
-    function SetNewPlotAreaPixels($x1, $y1, $x2, $y2)
-    {
-        //Like in GD 0, 0 is upper left set via pixel Coordinates
-        $this->plot_area = array($x1, $y1, $x2, $y2);
-        $this->plot_area_width = $this->plot_area[2] - $this->plot_area[0];
-        $this->plot_area_height = $this->plot_area[3] - $this->plot_area[1];
-        $this->y_top_margin = $this->plot_area[1];
-
-        if (isset($this->plot_max_x))
-            $this->CalcTranslation();
-
-        return TRUE;
-    }
-
-    /*!
-     * \deprecated Use _SetRGBColor()
-     */
-    function SetColor($which_color)
-    {
-        $this->SetRGBColor($which_color);
-        return TRUE;
-    }
-
-    /*
-     * \deprecated Use SetLineWidths().
-     */
-    function SetLineWidth($which_lw)
-    {
-
-        $this->SetLineWidths($which_lw);
-
-        if (!$this->error_bar_line_width) {
-            $this->SetErrorBarLineWidth($which_lw);
-        }
-        return TRUE;
-    }
-
-    /*
-     * \deprecated Use SetPointShapes().
-     */
-    function SetPointShape($which_pt)
-    {
-        $this->SetPointShapes($which_pt);
-        return TRUE;
-    }
-
-    /*
-     * \deprecated Use SetPointSizes().
-     */
-    function SetPointSize($which_ps)
-    {
-        $this->SetPointSizes($which_ps);
-        return TRUE;
-    }
-}  // class PHPlot
-
-
-/*
- * The PHPlot_truecolor class extends PHPlot to use GD truecolor images.
- */
-
-class PHPlot_truecolor extends PHPlot {
-    /*
-     * PHPlot Truecolor variation constructor: Create a PHPlot_truecolor object and initialize it.
-     * Note this does NOT call the parent (PHPlot) constructor. It duplicates the code here.
-     * Everything is the same as the PHPlot constructor except for imagecreatetruecolor.
-     *
-     * Parameters are the same as PHPlot:
-     * which_width, which_height       Image width and height in pixels.
-     * which_output_file               Optional filename for output.
-     * which_input_file                Optional path to a file to be used as background.
-     *
-     */
-    function __construct($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
-    {
-        $this->SetRGBArray($this->color_array);
-
-        if ($which_output_file)
-            $this->SetOutputFile($which_output_file);
-
-        if ($which_input_file)
-            $this->SetInputFile($which_input_file);
-        else {
-            $this->image_width = $which_width;
-            $this->image_height = $which_height;
-
-            $this->img = imagecreatetruecolor($this->image_width, $this->image_height);
-            if (! $this->img)
-                return $this->PrintError('PHPlot_truecolor(): Could not create image resource.');
-        }
-
-        $this->SetDefaultStyles();
-        $this->SetDefaultFonts();
-    }
-}
diff --git a/gosa-core/include/phplot-5.1.2/phplot_data.php b/gosa-core/include/phplot-5.1.2/phplot_data.php
deleted file mode 100644 (file)
index d42c27a..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-<?php
-/* $Id: phplot_data.php,v 1.13 2009/10/29 01:13:17 lbayuk Exp $ */
-/*
- * This file extends PHPlot by adding additional routines that can be used
- * to modify the data arrays.
- *
- * ---------------------------------------------------------------------
- * Copyright (C) 1998-2009 Afan Ottenheimer
- *
- * This 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;
- * version 2.1 of the License.
- *
- * This software 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 software; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * ---------------------------------------------------------------------
- *
- * Data must be a *numerical* array. This is enforced in SetDataValues()
- */
-
-require_once("phplot.php");
-
-class PHPlot_Data extends PHPlot
-{
-    /*!
-     * Constructor
-     */
-    function PHPlot_Data($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
-    {
-        if (! isset($this->img)) {
-            $this->PHPlot($which_width, $which_height, $which_output_file, $which_input_file);
-        }
-    }
-
-    /*!
-     * Will scale all data rows
-     * Maybe later I will do a function that only scales some rows
-     * if $even is TRUE, data will be scaled with "even" factors.
-     * \note Original code by Thiemo Nagel
-     */
-    function DoScaleData($even, $show_in_legend)
-    {
-        $offset = 0;        // We use this not to read labels in text-data
-
-        if ($this->data_type == 'text-data') {
-            $offset = 1;
-        } elseif ($this->data_type != 'data-data') {
-            $this->DrawError('wrong data type!!');
-            return FALSE;
-        }
-
-        // Determine maxima for each data row in array $max
-        // Put maximum of the maxima in $maxmax
-        $maxmax = 0;
-        for($i=0; $i < $this->num_data_rows; $i++) {
-            $rowsize = count($this->data[$i]);
-            for ($j=$offset; $j < $rowsize; $j++) {
-                if ($this->data[$i][$j] > @ $max[$j])
-                    $max[$j] = $this->data[$i][$j];
-                if (@ $max[$j] > $maxmax)
-                    $maxmax = $max[$j];
-            }
-        }
-
-        // determine amplification factor $amplify
-        $end = count($max) + $offset;
-        for ($i=$offset; $i < $end; $i++) {
-            if ($max[$i] == 0 || $max[$i] == $maxmax) {
-                $amplify[$i] = 1;  // no divide by zero
-            } else {
-                if ($even) {
-                    $amp = pow(10,round(log10($maxmax / $max[$i]))-1);
-                    if ($amp * $max[$i] * 5 < $maxmax) {
-                        $amp *= 5;
-                    } elseif ($amp * $max[$i] * 2 < $maxmax) {
-                        $amp *= 2;
-                    }
-                } else {
-                    $amp = $maxmax / $max[$i];
-                    $digits = floor(log10($amp));
-                    $amp = round($amp/pow(10,$digits-1))*pow(10,$digits-1);
-                }
-                $amplify[$i] = $amp;
-            }
-            if ($amplify[$i] != 1 && $show_in_legend)
-                @ $this->legend[$i] .= "*$amplify[$i]";
-        }
-
-        // Amplify data
-        // On my machine, running 1000 iterations over 1000 rows of 12 elements each,
-        // the for loops were 43.2% faster (MBD)
-        for ($i = 0; $i < $this->num_data_rows; $i++) {
-            $rowsize = count($this->data[$i]);
-            for ($j=$offset; $j < $rowsize; $j++) {
-                $this->data[$i][$j] *= $amplify[$j];
-            }
-        }
-
-        //Re-Scale Vertical Ticks if not already set
-        //Removed; does nothing and wrong variable name?
-        // if ( ! $this->y_tick_increment) {
-        //     $this->SetYTickIncrement() ;
-        // }
-
-        return TRUE;
-    } //function DoScaleData
-
-
-    /*!
-     * Computes a moving average of strength $interval for
-     * data row number $datarow, where 0 denotes the first
-     * row of y-data.
-     *
-     *  \param int    datarow  Index of the row whereupon to make calculations
-     *  \param int    interval Number of elements to use in average ("strength")
-     *  \param bool   show     Whether to tell about the moving average in the legend.
-     *  \param string color    Color for the line to be drawn. This color is darkened.
-     *                         Can be named or #RRGGBB.
-     *  \param int    width    Width of the line to be drawn.
-     *
-     *  \note Original idea by Theimo Nagel
-     */
-    function DoMovingAverage($datarow, $interval, $show=TRUE, $color=NULL, $width=NULL)
-    {
-        $off = 1;               // Skip record #0 (data label)
-
-        $this->PadArrays();
-
-        if ($interval == 0) {
-            $this->DrawError('DoMovingAverage(): interval can\'t be 0');
-            return FALSE;
-        }
-
-        if ($datarow >= $this->records_per_group) {
-            $this->DrawError("DoMovingAverage(): Data row out of bounds ($datarow >= $this->records_per_group)");
-            return FALSE;
-        }
-
-        if ($this->data_type == 'text-data') {
-            // Ok. No need to set the offset to skip more records.
-        } elseif ($this->data_type == 'data-data') {
-            $off++;             // first Y value at $data[][2]
-        } else {
-            $this->DrawError('DoMovingAverage(): wrong data type!!');
-            return FALSE;
-        }
-
-        // Set color:
-        if ($color) {
-            array_push($this->ndx_data_colors, $this->SetIndexDarkColor($color));
-        } else {
-            array_push($this->ndx_data_colors, $this->SetIndexDarkColor($this->data_colors[$datarow]));
-        }
-        // Set line width:
-        if ($width) {
-            array_push($this->line_widths, $width);
-        } else {
-            array_push($this->line_widths,  $this->line_widths[$datarow] * 2);
-        }
-        // Show in legend?
-        if ($show) {
-            $this->legend[$this->records_per_group-1] = "(MA[$datarow]:$interval)";
-        }
-
-        $datarow += $off;
-        for ($i = 0; $i < $this->num_data_rows; $i++) {
-            $storage[$i % $interval] = @ $this->data[$i][$datarow];
-            $ma = array_sum($storage);
-            $ma /= count($storage);
-            array_push($this->data[$i], $ma);   // Push the data onto the array
-            $this->num_recs[$i]++;              // Tell the drawing functions it is there
-        }
-        $this->records_per_group++;
-//        $this->FindDataLimits();
-        return TRUE;
-    } //function DoMovingAverage()
-
-
-    /**
-     * Computes an exponentially smoothed moving average.
-     * @param int perc "smoothing percentage"
-     * FIXME!!! I haven't checked this.
-     */
-    function DoExponentialMovingAverage($datarow, $perc, $show_in_legend)
-    {
-        if ($this->data_type == 'text-data') {
-            $datarow++;
-        } elseif ($this->data_type != 'data-data') {
-            $this->DrawError('DoWeightedMovingAverage(): wrong data type!!');
-            return FALSE;
-        }
-
-        if ($show_in_legend) {
-            $this->legend[$datarow] .= " (MA: $interval)";
-        }
-
-        $storage[0] = $this->data[0][$datarow];
-        for ($i=1;$i < $this->num_data_rows; $i++) {
-            $storage[$i] = @ $storage[$i-1] + $perc * ($this->data[$i][$datarow] - $storage[$i-1]);
-            $ma = array_sum($storage);
-            $ma /= count($storage);
-            $this->data[$i][$datarow] = $ma;
-        }
-        return TRUE;
-    } // function DoExponentialMovingAverage()
-
-
-    /*!
-     * Removes the DataSet of number $index
-     */
-    function DoRemoveDataSet($index)
-    {
-        $offset = 1;
-        if ($this->data_type == 'data-data') {
-            $offset++;
-        } elseif ($this->data_type != 'text-data') {
-            $this->DrawError('wrong data type!!');
-            return FALSE;
-        }
-
-        $index += $offset;
-        foreach ($this->data as $key=>$val) {
-            foreach ($val as $key2=>$val2) {
-                if ($key2 >= $index) {
-                    if (isset($this->data[$key][$key2+1])) {
-                        $this->data[$key][$key2] = $this->data[$key][$key2+1];
-                    } else {
-                        unset($this->data[$key][$key2]);
-                    }
-                }
-            }
-        }
-    } // function DoRemoveDataSet
-
-
-    /*!
-     * Computes row x divided by row y, stores the result in row x
-     * and deletes row y
-     */
-    function DoDivision($x,$y)
-    {
-        $offset = 1;
-        if ($this->data_type == 'data-data') {
-            $offset++;
-        } elseif ($this->data_type != 'text-data') {
-            $this->DrawError('wrong data type!!');
-            return FALSE;
-        }
-
-        $x += $offset; $y += $offset;
-        reset($this->data);
-        while (list($key, $val) = each($this->data)) {
-            if ($this->data[$key][$y] == 0) {
-                $this->data[$key][$x] = 0;
-            } else {
-                $this->data[$key][$x] /= $this->data[$key][$y];
-            }
-        }
-
-        $this->DoRemoveDataSet($y-$offset);
-    } // function DoDivision
-
-} // class PHPlot_Data extends PHPlot
diff --git a/gosa-core/include/phplot-5.1.2/rgb.inc.php b/gosa-core/include/phplot-5.1.2/rgb.inc.php
deleted file mode 100644 (file)
index 41256ee..0000000
+++ /dev/null
@@ -1,752 +0,0 @@
-<?php
-/* $Id: rgb.inc.php,v 1.2 2009/06/12 01:58:35 lbayuk Exp $ */
-/*
- * This is a large color map which can be used by PHPlot via
- *     $plot->SetRGBArray('large')
- * For more information on PHPlot see http://sourceforge.net/projects/phplot/
- *
- * rgb.inc.php comes with PHPlot but is derived from the X11 rgb.txt color
- * database file, which contains no specific copyright notice. It may be
- * covered by X.Org, XFree86, or MIT/X11 copyright and license, all of which
- * allow redistribution on terms which are less strict than the LGPL which
- * covers PHPlot.
- */
-$ColorArray = array(
-       "snow"                  => array(255, 250, 250),
-       "ghost white"   => array(248, 248, 255),
-       "GhostWhite"    => array(248, 248, 255),
-       "white smoke"   => array(245, 245, 245),
-       "WhiteSmoke"    => array(245, 245, 245),
-       "gainsboro"             => array(220, 220, 220),
-       "floral white"  => array(255, 250, 240),
-       "FloralWhite"   => array(255, 250, 240),
-       "old lace"              => array(253, 245, 230),
-       "OldLace"               => array(253, 245, 230),
-       "linen"                 => array(250, 240, 230),
-       "antique white" => array(250, 235, 215),
-       "AntiqueWhite"  => array(250, 235, 215),
-       "papaya whip"   => array(255, 239, 213),
-       "PapayaWhip"    => array(255, 239, 213),
-       "blanched almond"       => array(255, 235, 205),
-       "BlanchedAlmond"        => array(255, 235, 205),
-       "bisque"                => array(255, 228, 196),
-       "peach puff"    => array(255, 218, 185),
-       "PeachPuff"             => array(255, 218, 185),
-       "navajo white"  => array(255, 222, 173),
-       "NavajoWhite"   => array(255, 222, 173),
-       "moccasin"              => array(255, 228, 181),
-       "cornsilk"              => array(255, 248, 220),
-       "ivory"                 => array(255, 255, 240),
-       "lemon chiffon" => array(255, 250, 205),
-       "LemonChiffon"  => array(255, 250, 205),
-       "seashell"              => array(255, 245, 238),
-       "honeydew"              => array(240, 255, 240),
-       "mint cream"    => array(245, 255, 250),
-       "MintCream"             => array(245, 255, 250),
-       "azure"                 => array(240, 255, 255),
-       "alice blue"    => array(240, 248, 255),
-       "AliceBlue"             => array(240, 248, 255),
-       "lavender"              => array(230, 230, 250),
-       "lavender blush"        => array(255, 240, 245),
-       "LavenderBlush"         => array(255, 240, 245),
-       "misty rose"            => array(255, 228, 225),
-       "MistyRose"             => array(255, 228, 225),
-       "white"                 => array(255, 255, 255),
-       "black"                 => array(  0,   0,   0),
-       "dark slate gray"       => array( 47,  79,  79),
-       "DarkSlateGray"         => array( 47,  79,  79),
-       "dark slate grey"       => array( 47,  79,  79),
-       "DarkSlateGrey"         => array( 47,  79,  79),
-       "dim gray"                      => array(105, 105, 105),
-       "DimGray"                       => array(105, 105, 105),
-       "dim grey"                      => array(105, 105, 105),
-       "DimGrey"                       => array(105, 105, 105),
-       "slate gray"            => array(112, 128, 144),
-       "SlateGray"                     => array(112, 128, 144),
-       "slate grey"            => array(112, 128, 144),
-       "SlateGrey"                     => array(112, 128, 144),
-       "light slate gray"      => array(119, 136, 153),
-       "LightSlateGray"        => array(119, 136, 153),
-       "light slate grey"      => array(119, 136, 153),
-       "LightSlateGrey"        => array(119, 136, 153),
-       "gray"                  => array(190, 190, 190),
-       "grey"                  => array(190, 190, 190),
-       "light grey"            => array(211, 211, 211),
-       "LightGrey"                     => array(211, 211, 211),
-       "light gray"            => array(211, 211, 211),
-       "LightGray"                     => array(211, 211, 211),
-       "midnight blue"         => array( 25,  25, 112),
-       "MidnightBlue"          => array( 25,  25, 112),
-       "navy"                  => array(  0,   0, 128),
-       "navy blue"                     => array(  0,   0, 128),
-       "NavyBlue"                      => array(  0,   0, 128),
-       "cornflower blue"       => array(100, 149, 237),
-       "CornflowerBlue"        => array(100, 149, 237),
-       "dark slate blue"       => array( 72,  61, 139),
-       "DarkSlateBlue"         => array( 72,  61, 139),
-       "slate blue"            => array(106,  90, 205),
-       "SlateBlue"                     => array(106,  90, 205),
-       "medium slate blue"     => array(123, 104, 238),
-       "MediumSlateBlue"       => array(123, 104, 238),
-       "light slate blue"      => array(132, 112, 255),
-       "LightSlateBlue"        => array(132, 112, 255),
-       "medium blue"           => array(  0,   0, 205),
-       "MediumBlue"            => array(  0,   0, 205),
-       "royal blue"            => array( 65, 105, 225),
-       "RoyalBlue"                     => array( 65, 105, 225),
-       "blue"                  => array(  0,   0, 255),
-       "dodger blue"           => array( 30, 144, 255),
-       "DodgerBlue"            => array( 30, 144, 255),
-       "deep sky blue"         => array(  0, 191, 255),
-       "DeepSkyBlue"           => array(  0, 191, 255),
-       "sky blue"                      => array(135, 206, 235),
-       "SkyBlue"                       => array(135, 206, 235),
-       "light sky blue"        => array(135, 206, 250),
-       "LightSkyBlue"          => array(135, 206, 250),
-       "steel blue"            => array( 70, 130, 180),
-       "SteelBlue"                     => array( 70, 130, 180),
-       "light steel blue"      => array(176, 196, 222),
-       "LightSteelBlue"        => array(176, 196, 222),
-       "light blue"            => array(173, 216, 230),
-       "LightBlue"                     => array(173, 216, 230),
-       "powder blue"           => array(176, 224, 230),
-       "PowderBlue"            => array(176, 224, 230),
-       "pale turquoise"        => array(175, 238, 238),
-       "PaleTurquoise"         => array(175, 238, 238),
-       "dark turquoise"        => array(  0, 206, 209),
-       "DarkTurquoise"         => array(  0, 206, 209),
-       "medium turquoise"      => array( 72, 209, 204),
-       "MediumTurquoise"       => array( 72, 209, 204),
-       "turquoise"                     => array( 64, 224, 208),
-       "cyan"                  => array(  0, 255, 255),
-       "light cyan"            => array(224, 255, 255),
-       "LightCyan"                     => array(224, 255, 255),
-       "cadet blue"            => array( 95, 158, 160),
-       "CadetBlue"                     => array( 95, 158, 160),
-       "medium aquamarine"     => array(102, 205, 170),
-       "MediumAquamarine"      => array(102, 205, 170),
-       "aquamarine"            => array(127, 255, 212),
-       "dark green"            => array(  0, 100,   0),
-       "DarkGreen"                     => array(  0, 100,   0),
-       "dark olive green"      => array( 85, 107,  47),
-       "DarkOliveGreen"        => array( 85, 107,  47),
-       "dark sea green"        => array(143, 188, 143),
-       "DarkSeaGreen"          => array(143, 188, 143),
-       "sea green"                     => array( 46, 139,  87),
-       "SeaGreen"                      => array( 46, 139,  87),
-       "medium sea green"      => array( 60, 179, 113),
-       "MediumSeaGreen"        => array( 60, 179, 113),
-       "light sea green"       => array( 32, 178, 170),
-       "LightSeaGreen"         => array( 32, 178, 170),
-       "pale green"            => array(152, 251, 152),
-       "PaleGreen"                     => array(152, 251, 152),
-       "spring green"          => array(  0, 255, 127),
-       "SpringGreen"           => array(  0, 255, 127),
-       "lawn green"            => array(124, 252,   0),
-       "LawnGreen"                     => array(124, 252,   0),
-       "green"                 => array(  0, 255,   0),
-       "chartreuse"            => array(127, 255,   0),
-       "medium spring green"   => array(  0, 250, 154),
-       "MediumSpringGreen"             => array(  0, 250, 154),
-       "green yellow"                  => array(173, 255,  47),
-       "GreenYellow"                   => array(173, 255,  47),
-       "lime green"                    => array( 50, 205,  50),
-       "LimeGreen"                     => array( 50, 205,  50),
-       "yellow green"                  => array(154, 205,  50),
-       "YellowGreen"                   => array(154, 205,  50),
-       "forest green"                  => array( 34, 139,  34),
-       "ForestGreen"                   => array( 34, 139,  34),
-       "olive drab"                    => array(107, 142,  35),
-       "OliveDrab"                     => array(107, 142,  35),
-       "dark khaki"            => array(189, 183, 107),
-       "DarkKhaki"                     => array(189, 183, 107),
-       "khaki"                 => array(240, 230, 140),
-       "pale goldenrod"        => array(238, 232, 170),
-       "PaleGoldenrod"         => array(238, 232, 170),
-       "light goldenrod yellow"        => array(250, 250, 210),
-       "LightGoldenrodYellow"          => array(250, 250, 210),
-       "light yellow"                  => array(255, 255, 224),
-       "LightYellow"                   => array(255, 255, 224),
-       "yellow"                        => array(255, 255,   0),
-       "gold"                  => array(255, 215,   0),
-       "light goldenrod"                       => array(238, 221, 130),
-       "LightGoldenrod"                        => array(238, 221, 130),
-       "goldenrod"                     => array(218, 165,  32),
-       "dark goldenrod"                        => array(184, 134,  11),
-       "DarkGoldenrod"                 => array(184, 134,  11),
-       "rosy brown"                    => array(188, 143, 143),
-       "RosyBrown"                     => array(188, 143, 143),
-       "indian red"                    => array(205,  92,  92),
-       "IndianRed"                     => array(205,  92,  92),
-       "saddle brown"                  => array(139,  69,  19),
-       "SaddleBrown"                   => array(139,  69,  19),
-       "sienna"                        => array(160,  82,  45),
-       "peru"                  => array(205, 133,  63),
-       "burlywood"                     => array(222, 184, 135),
-       "beige"                 => array(245, 245, 220),
-       "wheat"                 => array(245, 222, 179),
-       "sandy brown"                   => array(244, 164,  96),
-       "SandyBrown"                    => array(244, 164,  96),
-       "tan"                   => array(210, 180, 140),
-       "chocolate"                     => array(210, 105,  30),
-       "firebrick"                     => array(178,  34,  34),
-       "brown"                 => array(165,  42,  42),
-       "dark salmon"                   => array(233, 150, 122),
-       "DarkSalmon"                    => array(233, 150, 122),
-       "salmon"                        => array(250, 128, 114),
-       "light salmon"                  => array(255, 160, 122),
-       "LightSalmon"                   => array(255, 160, 122),
-       "orange"                        => array(255, 165,   0),
-       "dark orange"                   => array(255, 140,   0),
-       "DarkOrange"                    => array(255, 140,   0),
-       "coral"                 => array(255, 127,  80),
-       "light coral"                   => array(240, 128, 128),
-       "LightCoral"                    => array(240, 128, 128),
-       "tomato"                        => array(255,  99,  71),
-       "orange red"                    => array(255,  69,   0),
-       "OrangeRed"                     => array(255,  69,   0),
-       "red"                   => array(255,   0,   0),
-       "hot pink"                      => array(255, 105, 180),
-       "HotPink"                       => array(255, 105, 180),
-       "deep pink"                     => array(255,  20, 147),
-       "DeepPink"                      => array(255,  20, 147),
-       "pink"                  => array(255, 192, 203),
-       "light pink"            => array(255, 182, 193),
-       "LightPink"                     => array(255, 182, 193),
-       "pale violet red"       => array(219, 112, 147),
-       "PaleVioletRed"         => array(219, 112, 147),
-       "maroon"                        => array(176,  48,  96),
-       "medium violet red"     => array(199,  21, 133),
-       "MediumVioletRed"       => array(199,  21, 133),
-       "violet red"            => array(208,  32, 144),
-       "VioletRed"                     => array(208,  32, 144),
-       "magenta"                       => array(255,   0, 255),
-       "violet"                        => array(238, 130, 238),
-       "plum"                  => array(221, 160, 221),
-       "orchid"                        => array(218, 112, 214),
-       "medium orchid"         => array(186,  85, 211),
-       "MediumOrchid"          => array(186,  85, 211),
-       "dark orchid"           => array(153,  50, 204),
-       "DarkOrchid"            => array(153,  50, 204),
-       "dark violet"           => array(148,   0, 211),
-       "DarkViolet"            => array(148,   0, 211),
-       "blue violet"           => array(138,  43, 226),
-       "BlueViolet"            => array(138,  43, 226),
-       "purple"                        => array(160,  32, 240),
-       "medium purple"         => array(147, 112, 219),
-       "MediumPurple"          => array(147, 112, 219),
-       "thistle"                       => array(216, 191, 216),
-       "snow1"                 => array(255, 250, 250),
-       "snow2"                 => array(238, 233, 233),
-       "snow3"                 => array(205, 201, 201),
-       "snow4"                 => array(139, 137, 137),
-       "seashell1"                     => array(255, 245, 238),
-       "seashell2"                     => array(238, 229, 222),
-       "seashell3"                     => array(205, 197, 191),
-       "seashell4"                     => array(139, 134, 130),
-       "AntiqueWhite1"                 => array(255, 239, 219),
-       "AntiqueWhite2"                 => array(238, 223, 204),
-       "AntiqueWhite3"                 => array(205, 192, 176),
-       "AntiqueWhite4"                 => array(139, 131, 120),
-       "bisque1"                       => array(255, 228, 196),
-       "bisque2"                       => array(238, 213, 183),
-       "bisque3"                       => array(205, 183, 158),
-       "bisque4"                       => array(139, 125, 107),
-       "PeachPuff1"                    => array(255, 218, 185),
-       "PeachPuff2"                    => array(238, 203, 173),
-       "PeachPuff3"                    => array(205, 175, 149),
-       "PeachPuff4"                    => array(139, 119, 101),
-       "NavajoWhite1"                  => array(255, 222, 173),
-       "NavajoWhite2"                  => array(238, 207, 161),
-       "NavajoWhite3"                  => array(205, 179, 139),
-       "NavajoWhite4"                  => array(139, 121,  94),
-       "LemonChiffon1"                 => array(255, 250, 205),
-       "LemonChiffon2"                 => array(238, 233, 191),
-       "LemonChiffon3"                 => array(205, 201, 165),
-       "LemonChiffon4"                 => array(139, 137, 112),
-       "cornsilk1"                     => array(255, 248, 220),
-       "cornsilk2"                     => array(238, 232, 205),
-       "cornsilk3"                     => array(205, 200, 177),
-       "cornsilk4"                     => array(139, 136, 120),
-       "ivory1"                        => array(255, 255, 240),
-       "ivory2"                        => array(238, 238, 224),
-       "ivory3"                        => array(205, 205, 193),
-       "ivory4"                        => array(139, 139, 131),
-       "honeydew1"                     => array(240, 255, 240),
-       "honeydew2"                     => array(224, 238, 224),
-       "honeydew3"                     => array(193, 205, 193),
-       "honeydew4"                     => array(131, 139, 131),
-       "LavenderBlush1"        => array(255, 240, 245),
-       "LavenderBlush2"        => array(238, 224, 229),
-       "LavenderBlush3"        => array(205, 193, 197),
-       "LavenderBlush4"        => array(139, 131, 134),
-       "MistyRose1"            => array(255, 228, 225),
-       "MistyRose2"            => array(238, 213, 210),
-       "MistyRose3"            => array(205, 183, 181),
-       "MistyRose4"            => array(139, 125, 123),
-       "azure1"                        => array(240, 255, 255),
-       "azure2"                        => array(224, 238, 238),
-       "azure3"                        => array(193, 205, 205),
-       "azure4"                        => array(131, 139, 139),
-       "SlateBlue1"            => array(131, 111, 255),
-       "SlateBlue2"            => array(122, 103, 238),
-       "SlateBlue3"            => array(105,  89, 205),
-       "SlateBlue4"            => array( 71,  60, 139),
-       "RoyalBlue1"            => array( 72, 118, 255),
-       "RoyalBlue2"            => array( 67, 110, 238),
-       "RoyalBlue3"            => array( 58,  95, 205),
-       "RoyalBlue4"            => array( 39,  64, 139),
-       "blue1"                 => array(  0,   0, 255),
-       "blue2"                 => array(  0,   0, 238),
-       "blue3"                 => array(  0,   0, 205),
-       "blue4"                 => array(  0,   0, 139),
-       "DodgerBlue1"           => array( 30, 144, 255),
-       "DodgerBlue2"           => array( 28, 134, 238),
-       "DodgerBlue3"           => array( 24, 116, 205),
-       "DodgerBlue4"           => array( 16,  78, 139),
-       "SteelBlue1"            => array( 99, 184, 255),
-       "SteelBlue2"            => array( 92, 172, 238),
-       "SteelBlue3"            => array( 79, 148, 205),
-       "SteelBlue4"            => array( 54, 100, 139),
-       "DeepSkyBlue1"          => array(  0, 191, 255),
-       "DeepSkyBlue2"          => array(  0, 178, 238),
-       "DeepSkyBlue3"          => array(  0, 154, 205),
-       "DeepSkyBlue4"          => array(  0, 104, 139),
-       "SkyBlue1"                      => array(135, 206, 255),
-       "SkyBlue2"                      => array(126, 192, 238),
-       "SkyBlue3"                      => array(108, 166, 205),
-       "SkyBlue4"                      => array( 74, 112, 139),
-       "LightSkyBlue1"         => array(176, 226, 255),
-       "LightSkyBlue2"         => array(164, 211, 238),
-       "LightSkyBlue3"         => array(141, 182, 205),
-       "LightSkyBlue4"         => array( 96, 123, 139),
-       "SlateGray1"            => array(198, 226, 255),
-       "SlateGray2"            => array(185, 211, 238),
-       "SlateGray3"            => array(159, 182, 205),
-       "SlateGray4"            => array(108, 123, 139),
-       "LightSteelBlue1"       => array(202, 225, 255),
-       "LightSteelBlue2"       => array(188, 210, 238),
-       "LightSteelBlue3"       => array(162, 181, 205),
-       "LightSteelBlue4"       => array(110, 123, 139),
-       "LightBlue1"            => array(191, 239, 255),
-       "LightBlue2"            => array(178, 223, 238),
-       "LightBlue3"            => array(154, 192, 205),
-       "LightBlue4"            => array(104, 131, 139),
-       "LightCyan1"            => array(224, 255, 255),
-       "LightCyan2"            => array(209, 238, 238),
-       "LightCyan3"            => array(180, 205, 205),
-       "LightCyan4"            => array(122, 139, 139),
-       "PaleTurquoise1"        => array(187, 255, 255),
-       "PaleTurquoise2"        => array(174, 238, 238),
-       "PaleTurquoise3"        => array(150, 205, 205),
-       "PaleTurquoise4"        => array(102, 139, 139),
-       "CadetBlue1"            => array(152, 245, 255),
-       "CadetBlue2"            => array(142, 229, 238),
-       "CadetBlue3"            => array(122, 197, 205),
-       "CadetBlue4"            => array( 83, 134, 139),
-       "turquoise1"            => array(  0, 245, 255),
-       "turquoise2"            => array(  0, 229, 238),
-       "turquoise3"            => array(  0, 197, 205),
-       "turquoise4"            => array(  0, 134, 139),
-       "cyan1"                 => array(  0, 255, 255),
-       "cyan2"                 => array(  0, 238, 238),
-       "cyan3"                 => array(  0, 205, 205),
-       "cyan4"                 => array(  0, 139, 139),
-       "DarkSlateGray1"        => array(151, 255, 255),
-       "DarkSlateGray2"        => array(141, 238, 238),
-       "DarkSlateGray3"        => array(121, 205, 205),
-       "DarkSlateGray4"        => array( 82, 139, 139),
-       "aquamarine1"           => array(127, 255, 212),
-       "aquamarine2"           => array(118, 238, 198),
-       "aquamarine3"           => array(102, 205, 170),
-       "aquamarine4"           => array( 69, 139, 116),
-       "DarkSeaGreen1"         => array(193, 255, 193),
-       "DarkSeaGreen2"         => array(180, 238, 180),
-       "DarkSeaGreen3"         => array(155, 205, 155),
-       "DarkSeaGreen4"         => array(105, 139, 105),
-       "SeaGreen1"                     => array( 84, 255, 159),
-       "SeaGreen2"                     => array( 78, 238, 148),
-       "SeaGreen3"                     => array( 67, 205, 128),
-       "SeaGreen4"                     => array( 46, 139,  87),
-       "PaleGreen1"            => array(154, 255, 154),
-       "PaleGreen2"            => array(144, 238, 144),
-       "PaleGreen3"            => array(124, 205, 124),
-       "PaleGreen4"            => array( 84, 139,  84),
-       "SpringGreen1"          => array(  0, 255, 127),
-       "SpringGreen2"          => array(  0, 238, 118),
-       "SpringGreen3"          => array(  0, 205, 102),
-       "SpringGreen4"          => array(  0, 139,  69),
-       "green1"                        => array(  0, 255,   0),
-       "green2"                        => array(  0, 238,   0),
-       "green3"                        => array(  0, 205,   0),
-       "green4"                        => array(  0, 139,   0),
-       "chartreuse1"           => array(127, 255,   0),
-       "chartreuse2"           => array(118, 238,   0),
-       "chartreuse3"           => array(102, 205,   0),
-       "chartreuse4"           => array( 69, 139,   0),
-       "OliveDrab1"            => array(192, 255,  62),
-       "OliveDrab2"            => array(179, 238,  58),
-       "OliveDrab3"            => array(154, 205,  50),
-       "OliveDrab4"            => array(105, 139,  34),
-       "DarkOliveGreen1"       => array(202, 255, 112),
-       "DarkOliveGreen2"       => array(188, 238, 104),
-       "DarkOliveGreen3"       => array(162, 205,  90),
-       "DarkOliveGreen4"       => array(110, 139,  61),
-       "khaki1"                        => array(255, 246, 143),
-       "khaki2"                        => array(238, 230, 133),
-       "khaki3"                        => array(205, 198, 115),
-       "khaki4"                        => array(139, 134,  78),
-       "LightGoldenrod1"       => array(255, 236, 139),
-       "LightGoldenrod2"       => array(238, 220, 130),
-       "LightGoldenrod3"       => array(205, 190, 112),
-       "LightGoldenrod4"       => array(139, 129,  76),
-       "LightYellow1"          => array(255, 255, 224),
-       "LightYellow2"          => array(238, 238, 209),
-       "LightYellow3"          => array(205, 205, 180),
-       "LightYellow4"          => array(139, 139, 122),
-       "yellow1"                       => array(255, 255,   0),
-       "yellow2"                       => array(238, 238,   0),
-       "yellow3"                       => array(205, 205,   0),
-       "yellow4"                       => array(139, 139,   0),
-       "gold1"                 => array(255, 215,   0),
-       "gold2"                 => array(238, 201,   0),
-       "gold3"                 => array(205, 173,   0),
-       "gold4"                 => array(139, 117,   0),
-       "goldenrod1"            => array(255, 193,  37),
-       "goldenrod2"            => array(238, 180,  34),
-       "goldenrod3"            => array(205, 155,  29),
-       "goldenrod4"            => array(139, 105,  20),
-       "DarkGoldenrod1"        => array(255, 185,  15),
-       "DarkGoldenrod2"        => array(238, 173,  14),
-       "DarkGoldenrod3"        => array(205, 149,  12),
-       "DarkGoldenrod4"        => array(139, 101,   8),
-       "RosyBrown1"            => array(255, 193, 193),
-       "RosyBrown2"            => array(238, 180, 180),
-       "RosyBrown3"            => array(205, 155, 155),
-       "RosyBrown4"            => array(139, 105, 105),
-       "IndianRed1"            => array(255, 106, 106),
-       "IndianRed2"            => array(238,  99,  99),
-       "IndianRed3"            => array(205,  85,  85),
-       "IndianRed4"            => array(139,  58,  58),
-       "sienna1"                       => array(255, 130,  71),
-       "sienna2"                       => array(238, 121,  66),
-       "sienna3"                       => array(205, 104,  57),
-       "sienna4"                       => array(139,  71,  38),
-       "burlywood1"            => array(255, 211, 155),
-       "burlywood2"            => array(238, 197, 145),
-       "burlywood3"            => array(205, 170, 125),
-       "burlywood4"            => array(139, 115,  85),
-       "wheat1"                        => array(255, 231, 186),
-       "wheat2"                        => array(238, 216, 174),
-       "wheat3"                        => array(205, 186, 150),
-       "wheat4"                        => array(139, 126, 102),
-       "tan1"                  => array(255, 165,  79),
-       "tan2"                  => array(238, 154,  73),
-       "tan3"                  => array(205, 133,  63),
-       "tan4"                  => array(139,  90,  43),
-       "chocolate1"            => array(255, 127,  36),
-       "chocolate2"            => array(238, 118,  33),
-       "chocolate3"            => array(205, 102,  29),
-       "chocolate4"            => array(139,  69,  19),
-       "firebrick1"            => array(255,  48,  48),
-       "firebrick2"            => array(238,  44,  44),
-       "firebrick3"            => array(205,  38,  38),
-       "firebrick4"            => array(139,  26,  26),
-       "brown1"                        => array(255,  64,  64),
-       "brown2"                        => array(238,  59,  59),
-       "brown3"                        => array(205,  51,  51),
-       "brown4"                        => array(139,  35,  35),
-       "salmon1"                       => array(255, 140, 105),
-       "salmon2"                       => array(238, 130,  98),
-       "salmon3"                       => array(205, 112,  84),
-       "salmon4"                       => array(139,  76,  57),
-       "LightSalmon1"          => array(255, 160, 122),
-       "LightSalmon2"          => array(238, 149, 114),
-       "LightSalmon3"          => array(205, 129,  98),
-       "LightSalmon4"          => array(139,  87,  66),
-       "orange1"                       => array(255, 165,   0),
-       "orange2"                       => array(238, 154,   0),
-       "orange3"                       => array(205, 133,   0),
-       "orange4"                       => array(139,  90,   0),
-       "DarkOrange1"           => array(255, 127,   0),
-       "DarkOrange2"           => array(238, 118,   0),
-       "DarkOrange3"           => array(205, 102,   0),
-       "DarkOrange4"           => array(139,  69,   0),
-       "coral1"                        => array(255, 114,  86),
-       "coral2"                        => array(238, 106,  80),
-       "coral3"                        => array(205,  91,  69),
-       "coral4"                        => array(139,  62,  47),
-       "tomato1"                       => array(255,  99,  71),
-       "tomato2"                       => array(238,  92,  66),
-       "tomato3"                       => array(205,  79,  57),
-       "tomato4"                       => array(139,  54,  38),
-       "OrangeRed1"            => array(255,  69,   0),
-       "OrangeRed2"            => array(238,  64,   0),
-       "OrangeRed3"            => array(205,  55,   0),
-       "OrangeRed4"            => array(139,  37,   0),
-       "red1"                  => array(255,   0,   0),
-       "red2"                  => array(238,   0,   0),
-       "red3"                  => array(205,   0,   0),
-       "red4"                  => array(139,   0,   0),
-       "DeepPink1"                     => array(255,  20, 147),
-       "DeepPink2"                     => array(238,  18, 137),
-       "DeepPink3"                     => array(205,  16, 118),
-       "DeepPink4"                     => array(139,  10,  80),
-       "HotPink1"                      => array(255, 110, 180),
-       "HotPink2"                      => array(238, 106, 167),
-       "HotPink3"                      => array(205,  96, 144),
-       "HotPink4"                      => array(139,  58,  98),
-       "pink1"                 => array(255, 181, 197),
-       "pink2"                 => array(238, 169, 184),
-       "pink3"                 => array(205, 145, 158),
-       "pink4"                 => array(139,  99, 108),
-       "LightPink1"            => array(255, 174, 185),
-       "LightPink2"            => array(238, 162, 173),
-       "LightPink3"            => array(205, 140, 149),
-       "LightPink4"            => array(139,  95, 101),
-       "PaleVioletRed1"        => array(255, 130, 171),
-       "PaleVioletRed2"        => array(238, 121, 159),
-       "PaleVioletRed3"        => array(205, 104, 137),
-       "PaleVioletRed4"        => array(139,  71,  93),
-       "maroon1"                       => array(255,  52, 179),
-       "maroon2"                       => array(238,  48, 167),
-       "maroon3"                       => array(205,  41, 144),
-       "maroon4"                       => array(139,  28,  98),
-       "VioletRed1"            => array(255,  62, 150),
-       "VioletRed2"            => array(238,  58, 140),
-       "VioletRed3"            => array(205,  50, 120),
-       "VioletRed4"            => array(139,  34,  82),
-       "magenta1"                      => array(255,   0, 255),
-       "magenta2"                      => array(238,   0, 238),
-       "magenta3"                      => array(205,   0, 205),
-       "magenta4"                      => array(139,   0, 139),
-       "orchid1"                       => array(255, 131, 250),
-       "orchid2"                       => array(238, 122, 233),
-       "orchid3"                       => array(205, 105, 201),
-       "orchid4"                       => array(139,  71, 137),
-       "plum1"                 => array(255, 187, 255),
-       "plum2"                 => array(238, 174, 238),
-       "plum3"                 => array(205, 150, 205),
-       "plum4"                 => array(139, 102, 139),
-       "MediumOrchid1"         => array(224, 102, 255),
-       "MediumOrchid2"         => array(209,  95, 238),
-       "MediumOrchid3"         => array(180,  82, 205),
-       "MediumOrchid4"         => array(122,  55, 139),
-       "DarkOrchid1"           => array(191,  62, 255),
-       "DarkOrchid2"           => array(178,  58, 238),
-       "DarkOrchid3"           => array(154,  50, 205),
-       "DarkOrchid4"           => array(104,  34, 139),
-       "purple1"                       => array(155,  48, 255),
-       "purple2"                       => array(145,  44, 238),
-       "purple3"                       => array(125,  38, 205),
-       "purple4"                       => array( 85,  26, 139),
-       "MediumPurple1"         => array(171, 130, 255),
-       "MediumPurple2"         => array(159, 121, 238),
-       "MediumPurple3"         => array(137, 104, 205),
-       "MediumPurple4"         => array( 93,  71, 139),
-       "thistle1"                      => array(255, 225, 255),
-       "thistle2"                      => array(238, 210, 238),
-       "thistle3"                      => array(205, 181, 205),
-       "thistle4"                      => array(139, 123, 139),
-       "gray0"                 => array(  0,   0,   0),
-       "grey0"                 => array(  0,   0,   0),
-       "gray1"                 => array(  3,   3,   3),
-       "grey1"                 => array(  3,   3,   3),
-       "gray2"                 => array(  5,   5,   5),
-       "grey2"                 => array(  5,   5,   5),
-       "gray3"                 => array(  8,   8,   8),
-       "grey3"                 => array(  8,   8,   8),
-       "gray4"                 => array( 10,  10,  10),
-       "grey4"                 => array( 10,  10,  10),
-       "gray5"                 => array( 13,  13,  13),
-       "grey5"                 => array( 13,  13,  13),
-       "gray6"                 => array( 15,  15,  15),
-       "grey6"                 => array( 15,  15,  15),
-       "gray7"                 => array( 18,  18,  18),
-       "grey7"                 => array( 18,  18,  18),
-       "gray8"                 => array( 20,  20,  20),
-       "grey8"                 => array( 20,  20,  20),
-       "gray9"                 => array( 23,  23,  23),
-       "grey9"                 => array( 23,  23,  23),
-       "gray10"                        => array( 26,  26,  26),
-       "grey10"                        => array( 26,  26,  26),
-       "gray11"                        => array( 28,  28,  28),
-       "grey11"                        => array( 28,  28,  28),
-       "gray12"                        => array( 31,  31,  31),
-       "grey12"                        => array( 31,  31,  31),
-       "gray13"                        => array( 33,  33,  33),
-       "grey13"                        => array( 33,  33,  33),
-       "gray14"                        => array( 36,  36,  36),
-       "grey14"                        => array( 36,  36,  36),
-       "gray15"                        => array( 38,  38,  38),
-       "grey15"                        => array( 38,  38,  38),
-       "gray16"                        => array( 41,  41,  41),
-       "grey16"                        => array( 41,  41,  41),
-       "gray17"                        => array( 43,  43,  43),
-       "grey17"                        => array( 43,  43,  43),
-       "gray18"                        => array( 46,  46,  46),
-       "grey18"                        => array( 46,  46,  46),
-       "gray19"                        => array( 48,  48,  48),
-       "grey19"                        => array( 48,  48,  48),
-       "gray20"                        => array( 51,  51,  51),
-       "grey20"                        => array( 51,  51,  51),
-       "gray21"                        => array( 54,  54,  54),
-       "grey21"                        => array( 54,  54,  54),
-       "gray22"                        => array( 56,  56,  56),
-       "grey22"                        => array( 56,  56,  56),
-       "gray23"                        => array( 59,  59,  59),
-       "grey23"                        => array( 59,  59,  59),
-       "gray24"                        => array( 61,  61,  61),
-       "grey24"                        => array( 61,  61,  61),
-       "gray25"                        => array( 64,  64,  64),
-       "grey25"                        => array( 64,  64,  64),
-       "gray26"                        => array( 66,  66,  66),
-       "grey26"                        => array( 66,  66,  66),
-       "gray27"                        => array( 69,  69,  69),
-       "grey27"                        => array( 69,  69,  69),
-       "gray28"                        => array( 71,  71,  71),
-       "grey28"                        => array( 71,  71,  71),
-       "gray29"                        => array( 74,  74,  74),
-       "grey29"                        => array( 74,  74,  74),
-       "gray30"                        => array( 77,  77,  77),
-       "grey30"                        => array( 77,  77,  77),
-       "gray31"                        => array( 79,  79,  79),
-       "grey31"                        => array( 79,  79,  79),
-       "gray32"                        => array( 82,  82,  82),
-       "grey32"                        => array( 82,  82,  82),
-       "gray33"                        => array( 84,  84,  84),
-       "grey33"                        => array( 84,  84,  84),
-       "gray34"                        => array( 87,  87,  87),
-       "grey34"                        => array( 87,  87,  87),
-       "gray35"                        => array( 89,  89,  89),
-       "grey35"                        => array( 89,  89,  89),
-       "gray36"                        => array( 92,  92,  92),
-       "grey36"                        => array( 92,  92,  92),
-       "gray37"                        => array( 94,  94,  94),
-       "grey37"                        => array( 94,  94,  94),
-       "gray38"                        => array( 97,  97,  97),
-       "grey38"                        => array( 97,  97,  97),
-       "gray39"                        => array( 99,  99,  99),
-       "grey39"                        => array( 99,  99,  99),
-       "gray40"                        => array(102, 102, 102),
-       "grey40"                        => array(102, 102, 102),
-       "gray41"                        => array(105, 105, 105),
-       "grey41"                        => array(105, 105, 105),
-       "gray42"                        => array(107, 107, 107),
-       "grey42"                        => array(107, 107, 107),
-       "gray43"                        => array(110, 110, 110),
-       "grey43"                        => array(110, 110, 110),
-       "gray44"                        => array(112, 112, 112),
-       "grey44"                        => array(112, 112, 112),
-       "gray45"                        => array(115, 115, 115),
-       "grey45"                        => array(115, 115, 115),
-       "gray46"                        => array(117, 117, 117),
-       "grey46"                        => array(117, 117, 117),
-       "gray47"                        => array(120, 120, 120),
-       "grey47"                        => array(120, 120, 120),
-       "gray48"                        => array(122, 122, 122),
-       "grey48"                        => array(122, 122, 122),
-       "gray49"                        => array(125, 125, 125),
-       "grey49"                        => array(125, 125, 125),
-       "gray50"                        => array(127, 127, 127),
-       "grey50"                        => array(127, 127, 127),
-       "gray51"                        => array(130, 130, 130),
-       "grey51"                        => array(130, 130, 130),
-       "gray52"                        => array(133, 133, 133),
-       "grey52"                        => array(133, 133, 133),
-       "gray53"                        => array(135, 135, 135),
-       "grey53"                        => array(135, 135, 135),
-       "gray54"                        => array(138, 138, 138),
-       "grey54"                        => array(138, 138, 138),
-       "gray55"                        => array(140, 140, 140),
-       "grey55"                        => array(140, 140, 140),
-       "gray56"                        => array(143, 143, 143),
-       "grey56"                        => array(143, 143, 143),
-       "gray57"                        => array(145, 145, 145),
-       "grey57"                        => array(145, 145, 145),
-       "gray58"                        => array(148, 148, 148),
-       "grey58"                        => array(148, 148, 148),
-       "gray59"                        => array(150, 150, 150),
-       "grey59"                        => array(150, 150, 150),
-       "gray60"                        => array(153, 153, 153),
-       "grey60"                        => array(153, 153, 153),
-       "gray61"                        => array(156, 156, 156),
-       "grey61"                        => array(156, 156, 156),
-       "gray62"                        => array(158, 158, 158),
-       "grey62"                        => array(158, 158, 158),
-       "gray63"                        => array(161, 161, 161),
-       "grey63"                        => array(161, 161, 161),
-       "gray64"                        => array(163, 163, 163),
-       "grey64"                        => array(163, 163, 163),
-       "gray65"                        => array(166, 166, 166),
-       "grey65"                        => array(166, 166, 166),
-       "gray66"                        => array(168, 168, 168),
-       "grey66"                        => array(168, 168, 168),
-       "gray67"                        => array(171, 171, 171),
-       "grey67"                        => array(171, 171, 171),
-       "gray68"                        => array(173, 173, 173),
-       "grey68"                        => array(173, 173, 173),
-       "gray69"                        => array(176, 176, 176),
-       "grey69"                        => array(176, 176, 176),
-       "gray70"                        => array(179, 179, 179),
-       "grey70"                        => array(179, 179, 179),
-       "gray71"                        => array(181, 181, 181),
-       "grey71"                        => array(181, 181, 181),
-       "gray72"                        => array(184, 184, 184),
-       "grey72"                        => array(184, 184, 184),
-       "gray73"                        => array(186, 186, 186),
-       "grey73"                        => array(186, 186, 186),
-       "gray74"                        => array(189, 189, 189),
-       "grey74"                        => array(189, 189, 189),
-       "gray75"                        => array(191, 191, 191),
-       "grey75"                        => array(191, 191, 191),
-       "gray76"                        => array(194, 194, 194),
-       "grey76"                        => array(194, 194, 194),
-       "gray77"                        => array(196, 196, 196),
-       "grey77"                        => array(196, 196, 196),
-       "gray78"                        => array(199, 199, 199),
-       "grey78"                        => array(199, 199, 199),
-       "gray79"                        => array(201, 201, 201),
-       "grey79"                        => array(201, 201, 201),
-       "gray80"                        => array(204, 204, 204),
-       "grey80"                        => array(204, 204, 204),
-       "gray81"                        => array(207, 207, 207),
-       "grey81"                        => array(207, 207, 207),
-       "gray82"                        => array(209, 209, 209),
-       "grey82"                        => array(209, 209, 209),
-       "gray83"                        => array(212, 212, 212),
-       "grey83"                        => array(212, 212, 212),
-       "gray84"                        => array(214, 214, 214),
-       "grey84"                        => array(214, 214, 214),
-       "gray85"                        => array(217, 217, 217),
-       "grey85"                        => array(217, 217, 217),
-       "gray86"                        => array(219, 219, 219),
-       "grey86"                        => array(219, 219, 219),
-       "gray87"                        => array(222, 222, 222),
-       "grey87"                        => array(222, 222, 222),
-       "gray88"                        => array(224, 224, 224),
-       "grey88"                        => array(224, 224, 224),
-       "gray89"                        => array(227, 227, 227),
-       "grey89"                        => array(227, 227, 227),
-       "gray90"                        => array(229, 229, 229),
-       "grey90"                        => array(229, 229, 229),
-       "gray91"                        => array(232, 232, 232),
-       "grey91"                        => array(232, 232, 232),
-       "gray92"                        => array(235, 235, 235),
-       "grey92"                        => array(235, 235, 235),
-       "gray93"                        => array(237, 237, 237),
-       "grey93"                        => array(237, 237, 237),
-       "gray94"                        => array(240, 240, 240),
-       "grey94"                        => array(240, 240, 240),
-       "gray95"                        => array(242, 242, 242),
-       "grey95"                        => array(242, 242, 242),
-       "gray96"                        => array(245, 245, 245),
-       "grey96"                        => array(245, 245, 245),
-       "gray97"                        => array(247, 247, 247),
-       "grey97"                        => array(247, 247, 247),
-       "gray98"                        => array(250, 250, 250),
-       "grey98"                        => array(250, 250, 250),
-       "gray99"                        => array(252, 252, 252),
-       "grey99"                        => array(252, 252, 252),
-       "gray100"                       => array(255, 255, 255)
-);