diff options
author | Benjamin Otte <otte@redhat.com> | 2010-10-17 21:58:33 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2010-10-30 01:50:02 +0800 |
commit | 67420580070ea143a4c8c4eb07d51ea800928d3f (patch) | |
tree | 2c5e5c1f4b0876ff47d49c13b5752c3e66579c4a /libart_lgpl | |
parent | 3e97227202f38a8cf44732abbb5bf708c12072ef (diff) | |
download | gsoc2013-evolution-67420580070ea143a4c8c4eb07d51ea800928d3f.tar gsoc2013-evolution-67420580070ea143a4c8c4eb07d51ea800928d3f.tar.gz gsoc2013-evolution-67420580070ea143a4c8c4eb07d51ea800928d3f.tar.bz2 gsoc2013-evolution-67420580070ea143a4c8c4eb07d51ea800928d3f.tar.lz gsoc2013-evolution-67420580070ea143a4c8c4eb07d51ea800928d3f.tar.xz gsoc2013-evolution-67420580070ea143a4c8c4eb07d51ea800928d3f.tar.zst gsoc2013-evolution-67420580070ea143a4c8c4eb07d51ea800928d3f.zip |
Remove libart
It's not used by the gnome-canvas anymore.
Diffstat (limited to 'libart_lgpl')
69 files changed, 0 insertions, 9937 deletions
diff --git a/libart_lgpl/AUTHORS b/libart_lgpl/AUTHORS deleted file mode 100644 index fbb51b36a4..0000000000 --- a/libart_lgpl/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Raph Levien <raph@acm.org> diff --git a/libart_lgpl/COPYING b/libart_lgpl/COPYING deleted file mode 100644 index bf50f20de6..0000000000 --- a/libart_lgpl/COPYING +++ /dev/null @@ -1,482 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - 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 Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, 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 or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the 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 a program 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. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - 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, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile 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) 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. - - c) 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. - - d) 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 source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307 USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/libart_lgpl/MAINTAINERS b/libart_lgpl/MAINTAINERS deleted file mode 100644 index dfeac41c66..0000000000 --- a/libart_lgpl/MAINTAINERS +++ /dev/null @@ -1,7 +0,0 @@ -Alex Larsson -E-mail: alexl@redhat.com -Userid: alexl - -Kjartan Maraas -E-mail: kmaraas@gnome.org -Userid: kmaraas diff --git a/libart_lgpl/Makefile.am b/libart_lgpl/Makefile.am deleted file mode 100644 index 1291a7bfd4..0000000000 --- a/libart_lgpl/Makefile.am +++ /dev/null @@ -1,82 +0,0 @@ -libart_lgplincludedir = $(privincludedir)/libart_lgpl - -privsolib_LTLIBRARIES = libart_lgpl.la - -libart_lgpl_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - $(GNOME_PLATFORM_CFLAGS) - -libart_lgplinclude_HEADERS = \ - art_affine.h \ - art_alphagamma.h \ - art_bpath.h \ - art_filterlevel.h \ - art_gray_svp.h \ - art_misc.h \ - art_pathcode.h \ - art_point.h \ - art_rect.h \ - art_rect_svp.h \ - art_rect_uta.h \ - art_render.h \ - art_rgb.h \ - art_rgb_affine.h \ - art_rgb_affine_private.h \ - art_rgb_rgba_affine.h \ - art_rgb_svp.h \ - art_svp.h \ - art_svp_intersect.h \ - art_svp_ops.h \ - art_svp_point.h \ - art_svp_render_aa.h \ - art_svp_vpath.h \ - art_svp_vpath_stroke.h \ - art_svp_wind.h \ - art_uta.h \ - art_uta_rect.h \ - art_uta_svp.h \ - art_uta_vpath.h \ - art_vpath.h \ - art_vpath_bpath.h \ - art_vpath_dash.h \ - art_vpath_svp.h \ - libart.h - -libart_lgpl_la_SOURCES = \ - art_affine.c \ - art_bpath.c \ - art_gray_svp.c \ - art_misc.c \ - art_rect.c \ - art_rect_svp.c \ - art_rect_uta.c \ - art_render.c \ - art_rgb.c \ - art_rgb_affine.c \ - art_rgb_affine_private.c \ - art_rgb_rgba_affine.c \ - art_rgb_svp.c \ - art_svp.c \ - art_svp_intersect.c \ - art_svp_ops.c \ - art_svp_point.c \ - art_svp_render_aa.c \ - art_svp_vpath.c \ - art_svp_vpath_stroke.c \ - art_uta.c \ - art_uta_rect.c \ - art_uta_svp.c \ - art_uta_vpath.c \ - art_vpath.c \ - art_vpath_bpath.c \ - art_vpath_dash.c \ - art_vpath_svp.c - -libart_lgpl_la_LIBADD = \ - $(GNOME_PLATFORM_LIBS) \ - $(MATH_LIB) - -libart_lgpl_la_LDFLAGS = $(NO_UNDEFINED) - --include $(top_srcdir)/git.mk diff --git a/libart_lgpl/README b/libart_lgpl/README deleted file mode 100644 index 882527e53f..0000000000 --- a/libart_lgpl/README +++ /dev/null @@ -1,19 +0,0 @@ -This is the LGPL'd component of libart. All functions needed for -running the Gnome canvas, and for printing support, will be going in -here. The GPL'd component will be getting various enhanced functions -for specific applications. - -Libart is free software. It is also for sale. For information about -licensing libart, please contact Raph Levien -<raph@acm.org>. Contributions to the codebase are also very welcome, -but the copyright must be assigned in writing to preserve the -licensing flexibility. - - -For more information about libart, see the web page: - - http://www.levien.com/libart/ - -There's also a libart tutorial available at -http://www.gnome.org/~mathieu/libart/libart.html - diff --git a/libart_lgpl/README.CVS b/libart_lgpl/README.CVS deleted file mode 100644 index 7ba42f7e70..0000000000 --- a/libart_lgpl/README.CVS +++ /dev/null @@ -1,14 +0,0 @@ -Welcome to the libart source tree! - -This code is being developed in a "free software for sale" -model. Thus, it's available under a free software license (LGPL for -this module), but I'm also requesting that for all changes to the code -the copyright gets assigned back to me. - -So if you want to contribute, please do, but contact me about getting -the copyright assigned. Otherwise, I will have to back your changes -out. - -Thanks! - -Raph Levien <raph@acm.org> diff --git a/libart_lgpl/art_affine.c b/libart_lgpl/art_affine.c deleted file mode 100644 index dd6866ca86..0000000000 --- a/libart_lgpl/art_affine.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Simple manipulations with affine transformations */ - -#include "config.h" -#include "art_affine.h" -#include "art_misc.h" /* for M_PI */ - -#include <math.h> -#include <stdio.h> /* for sprintf */ -#include <string.h> /* for strcpy */ - -/* According to a strict interpretation of the libart structure, this - routine should go into its own module, art_point_affine. However, - it's only two lines of code, and it can be argued that it is one of - the natural basic functions of an affine transformation. -*/ - -/** - * art_affine_point: Do an affine transformation of a point. - * @dst: Where the result point is stored. - * @src: The original point. - @ @affine: The affine transformation. - **/ -void -art_affine_point (ArtPoint *dst, const ArtPoint *src, - const gdouble affine[6]) -{ - gdouble x, y; - - x = src->x; - y = src->y; - dst->x = x * affine[0] + y * affine[2] + affine[4]; - dst->y = x * affine[1] + y * affine[3] + affine[5]; -} - -/** - * art_affine_invert: Find the inverse of an affine transformation. - * @dst: Where the resulting affine is stored. - * @src: The original affine transformation. - * - * All non-degenerate affine transforms are invertible. If the original - * affine is degenerate or nearly so, expect numerical instability and - * very likely core dumps on Alpha and other fp-picky architectures. - * Otherwise, @dst multiplied with @src, or @src multiplied with @dst - * will be (to within roundoff error) the identity affine. - **/ -void -art_affine_invert (gdouble dst[6], const gdouble src[6]) -{ - gdouble r_det; - - r_det = 1.0 / (src[0] * src[3] - src[1] * src[2]); - dst[0] = src[3] * r_det; - dst[1] = -src[1] * r_det; - dst[2] = -src[2] * r_det; - dst[3] = src[0] * r_det; - dst[4] = -src[4] * dst[0] - src[5] * dst[2]; - dst[5] = -src[4] * dst[1] - src[5] * dst[3]; -} - -/** - * art_affine_multiply: Multiply two affine transformation matrices. - * @dst: Where to store the result. - * @src1: The first affine transform to multiply. - * @src2: The second affine transform to multiply. - * - * Multiplies two affine transforms together, i.e. the resulting @dst - * is equivalent to doing first @src1 then @src2. Note that the - * PostScript concat operator multiplies on the left, i.e. "M concat" - * is equivalent to "CTM = multiply (M, CTM)"; - * - * It is safe to call this function with @dst equal to @src1 or @src2. - **/ -void -art_affine_multiply (gdouble dst[6], const gdouble src1[6], const gdouble src2[6]) -{ - gdouble d0, d1, d2, d3, d4, d5; - - d0 = src1[0] * src2[0] + src1[1] * src2[2]; - d1 = src1[0] * src2[1] + src1[1] * src2[3]; - d2 = src1[2] * src2[0] + src1[3] * src2[2]; - d3 = src1[2] * src2[1] + src1[3] * src2[3]; - d4 = src1[4] * src2[0] + src1[5] * src2[2] + src2[4]; - d5 = src1[4] * src2[1] + src1[5] * src2[3] + src2[5]; - dst[0] = d0; - dst[1] = d1; - dst[2] = d2; - dst[3] = d3; - dst[4] = d4; - dst[5] = d5; -} - -/** - * art_affine_identity: Set up the identity matrix. - * @dst: Where to store the resulting affine transform. - * - * Sets up an identity matrix. - **/ -void -art_affine_identity (gdouble dst[6]) -{ - dst[0] = 1; - dst[1] = 0; - dst[2] = 0; - dst[3] = 1; - dst[4] = 0; - dst[5] = 0; -} - -/** - * art_affine_scale: Set up a scaling matrix. - * @dst: Where to store the resulting affine transform. - * @sx: X scale factor. - * @sy: Y scale factor. - * - * Sets up a scaling matrix. - **/ -void -art_affine_scale (gdouble dst[6], gdouble sx, gdouble sy) -{ - dst[0] = sx; - dst[1] = 0; - dst[2] = 0; - dst[3] = sy; - dst[4] = 0; - dst[5] = 0; -} - -/** - * art_affine_translate: Set up a translation matrix. - * @dst: Where to store the resulting affine transform. - * @tx: X translation amount. - * @tx: Y translation amount. - * - * Sets up a translation matrix. - **/ -void -art_affine_translate (gdouble dst[6], gdouble tx, gdouble ty) -{ - dst[0] = 1; - dst[1] = 0; - dst[2] = 0; - dst[3] = 1; - dst[4] = tx; - dst[5] = ty; -} - -/** - * art_affine_expansion: Find the affine's expansion factor. - * @src: The affine transformation. - * - * Finds the expansion factor, i.e. the square root of the factor - * by which the affine transform affects area. In an affine transform - * composed of scaling, rotation, shearing, and translation, returns - * the amount of scaling. - * - * Return value: the expansion factor. - **/ -gdouble -art_affine_expansion (const gdouble src[6]) -{ - return sqrt (fabs (src[0] * src[3] - src[1] * src[2])); -} - diff --git a/libart_lgpl/art_affine.h b/libart_lgpl/art_affine.h deleted file mode 100644 index 2c50df1382..0000000000 --- a/libart_lgpl/art_affine.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_AFFINE_H__ -#define __ART_AFFINE_H__ - -#include <libart_lgpl/art_point.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -void -art_affine_point (ArtPoint *dst, const ArtPoint *src, - const gdouble affine[6]); - -void -art_affine_invert (gdouble dst_affine[6], const gdouble src_affine[6]); - -void -art_affine_multiply (gdouble dst[6], - const gdouble src1[6], const gdouble src2[6]); - -/* set up the identity matrix */ -void -art_affine_identity (gdouble dst[6]); - -/* set up a scaling matrix */ -void -art_affine_scale (gdouble dst[6], gdouble sx, gdouble sy); - -/* set up a translation matrix */ -void -art_affine_translate (gdouble dst[6], gdouble tx, gdouble ty); - -/* find the affine's "expansion factor", i.e. the scale amount */ -gdouble -art_affine_expansion (const gdouble src[6]); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_AFFINE_H__ */ diff --git a/libart_lgpl/art_alphagamma.h b/libart_lgpl/art_alphagamma.h deleted file mode 100644 index a779ae86a8..0000000000 --- a/libart_lgpl/art_alphagamma.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_ALPHAGAMMA_H__ -#define __ART_ALPHAGAMMA_H__ - -/* Alphagamma tables */ - -#include <libart_lgpl/art_misc.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct _ArtAlphaGamma ArtAlphaGamma; - -struct _ArtAlphaGamma { - /*< private >*/ - gdouble gamma; - gint invtable_size; - gint table[256]; - art_u8 invtable[1]; -}; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_H__ */ diff --git a/libart_lgpl/art_bpath.c b/libart_lgpl/art_bpath.c deleted file mode 100644 index 8c8dad0480..0000000000 --- a/libart_lgpl/art_bpath.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Basic constructors and operations for bezier paths */ - -#include "config.h" -#include "art_bpath.h" - -#include <math.h> - -/** - * art_bpath_affine_transform: Affine transform an #ArtBpath. - * @src: The source #ArtBpath. - * @matrix: The affine transform. - * - * Affine transform the bezpath, returning a newly allocated #ArtBpath - * (allocated using art_alloc()). - * - * Result (x', y') = (matrix[0] * x + matrix[2] * y + matrix[4], - * matrix[1] * x + matrix[3] * y + matrix[5]) - * - * Return value: the transformed #ArtBpath. - **/ -ArtBpath * -art_bpath_affine_transform (const ArtBpath *src, const gdouble matrix[6]) -{ - gint i; - gint size; - ArtBpath *new; - ArtPathcode code; - gdouble x, y; - - for (i = 0; src[i].code != ART_END; i++); - size = i; - - new = art_new (ArtBpath, size + 1); - - for (i = 0; i < size; i++) - { - code = src[i].code; - new[i].code = code; - if (code == ART_CURVETO) - { - x = src[i].x1; - y = src[i].y1; - new[i].x1 = matrix[0] * x + matrix[2] * y + matrix[4]; - new[i].y1 = matrix[1] * x + matrix[3] * y + matrix[5]; - x = src[i].x2; - y = src[i].y2; - new[i].x2 = matrix[0] * x + matrix[2] * y + matrix[4]; - new[i].y2 = matrix[1] * x + matrix[3] * y + matrix[5]; - } - else - { - new[i].x1 = 0; - new[i].y1 = 0; - new[i].x2 = 0; - new[i].y2 = 0; - } - x = src[i].x3; - y = src[i].y3; - new[i].x3 = matrix[0] * x + matrix[2] * y + matrix[4]; - new[i].y3 = matrix[1] * x + matrix[3] * y + matrix[5]; - } - new[i].code = ART_END; - new[i].x1 = 0; - new[i].y1 = 0; - new[i].x2 = 0; - new[i].y2 = 0; - new[i].x3 = 0; - new[i].y3 = 0; - - return new; -} - diff --git a/libart_lgpl/art_bpath.h b/libart_lgpl/art_bpath.h deleted file mode 100644 index e6362d41de..0000000000 --- a/libart_lgpl/art_bpath.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_BPATH_H__ -#define __ART_BPATH_H__ - -#include <libart_lgpl/art_misc.h> -#include <libart_lgpl/art_point.h> -#include <libart_lgpl/art_pathcode.h> - -/* Basic data structures and constructors for bezier paths */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct _ArtBpath ArtBpath; - -struct _ArtBpath { - /*< public >*/ - ArtPathcode code; - gdouble x1; - gdouble y1; - gdouble x2; - gdouble y2; - gdouble x3; - gdouble y3; -}; - -ArtBpath * -art_bpath_affine_transform (const ArtBpath *src, const gdouble matrix[6]); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_BPATH_H__ */ diff --git a/libart_lgpl/art_filterlevel.h b/libart_lgpl/art_filterlevel.h deleted file mode 100644 index 97d9abb400..0000000000 --- a/libart_lgpl/art_filterlevel.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_FILTERLEVEL_H__ -#define __ART_FILTERLEVEL_H__ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef enum { - ART_FILTER_NEAREST, - ART_FILTER_TILES, - ART_FILTER_BILINEAR, - ART_FILTER_HYPER -} ArtFilterLevel; - -/* NEAREST is nearest neighbor. It is the fastest and lowest quality. - - TILES is an accurate simulation of the PostScript image operator - without any interpolation enabled; each pixel is rendered as a tiny - parallelogram of solid color, the edges of which are implemented - with antialiasing. It resembles nearest neighbor for enlargement, - and bilinear for reduction. - - BILINEAR is bilinear interpolation. For enlargement, it is - equivalent to point-sampling the ideal bilinear-interpolated - image. For reduction, it is equivalent to laying down small tiles - and integrating over the coverage area. - - HYPER is the highest quality reconstruction function. It is derived - from the hyperbolic filters in Wolberg's "Digital Image Warping," - and is formally defined as the hyperbolic-filter sampling the ideal - hyperbolic-filter interpolated image (the filter is designed to be - idempotent for 1:1 pixel mapping). It is the slowest and highest - quality. - - Note: at this stage of implementation, most filter modes are likely - not to be implemented. - - Note: cubic filtering is missing from this list, because there isn't - much point - hyper is just as fast to implement and slightly better - in quality. - -*/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_PATHCODE_H__ */ diff --git a/libart_lgpl/art_gray_svp.c b/libart_lgpl/art_gray_svp.c deleted file mode 100644 index f076a69f99..0000000000 --- a/libart_lgpl/art_gray_svp.c +++ /dev/null @@ -1,123 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Render a sorted vector path into a graymap. */ - -#include "config.h" -#include "art_gray_svp.h" - -#include <string.h> /* for memset */ -#include "art_misc.h" - -#include "art_svp.h" -#include "art_svp_render_aa.h" - -typedef struct _ArtGraySVPData ArtGraySVPData; - -struct _ArtGraySVPData { - art_u8 *buf; - gint rowstride; - gint x0, x1; -}; - -static void -art_gray_svp_callback (gpointer callback_data, gint y, - gint start, ArtSVPRenderAAStep *steps, gint n_steps) -{ - ArtGraySVPData *data = (ArtGraySVPData *)callback_data; - art_u8 *linebuf; - gint run_x0, run_x1; - gint running_sum = start; - gint x0, x1; - gint k; - -#if 0 - printf ("start = %d", start); - running_sum = start; - for (k = 0; k < n_steps; k++) - { - running_sum += steps[k].delta; - printf (" %d:%d", steps[k].x, running_sum >> 16); - } - printf ("\n"); -#endif - - linebuf = data->buf; - x0 = data->x0; - x1 = data->x1; - - if (n_steps > 0) - { - run_x1 = steps[0].x; - if (run_x1 > x0) - memset (linebuf, running_sum >> 16, run_x1 - x0); - - for (k = 0; k < n_steps - 1; k++) - { - running_sum += steps[k].delta; - run_x0 = run_x1; - run_x1 = steps[k + 1].x; - if (run_x1 > run_x0) - memset (linebuf + run_x0 - x0, running_sum >> 16, run_x1 - run_x0); - } - running_sum += steps[k].delta; - if (x1 > run_x1) - memset (linebuf + run_x1 - x0, running_sum >> 16, x1 - run_x1); - } - else - { - memset (linebuf, running_sum >> 16, x1 - x0); - } - - data->buf += data->rowstride; -} - -/** - * art_gray_svp_aa: Render the vector path into the bytemap. - * @svp: The SVP to render. - * @x0: The view window's left coord. - * @y0: The view window's top coord. - * @x1: The view window's right coord. - * @y1: The view window's bottom coord. - * @buf: The buffer where the bytemap is stored. - * @rowstride: the rowstride for @buf. - * - * Each pixel gets a value proportional to the area within the pixel - * overlapping the (filled) SVP. Pixel (x, y) is stored at: - * - * @buf[(y - * @y0) * @rowstride + (x - @x0)] - * - * All pixels @x0 <= x < @x1, @y0 <= y < @y1 are generated. A - * stored value of zero is no coverage, and a value of 255 is full - * coverage. The area within the pixel (x, y) is the region covered - * by [x..x+1] and [y..y+1]. - **/ -void -art_gray_svp_aa (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - art_u8 *buf, gint rowstride) -{ - ArtGraySVPData data; - - data.buf = buf; - data.rowstride = rowstride; - data.x0 = x0; - data.x1 = x1; - art_svp_render_aa (svp, x0, y0, x1, y1, art_gray_svp_callback, &data); -} diff --git a/libart_lgpl/art_gray_svp.h b/libart_lgpl/art_gray_svp.h deleted file mode 100644 index 1a3c5d9c9a..0000000000 --- a/libart_lgpl/art_gray_svp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Render a sorted vector path into a graymap. */ - -#ifndef __ART_GRAY_SVP_H__ -#define __ART_GRAY_SVP_H__ - -#include <libart_lgpl/art_misc.h> -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -void -art_gray_svp_aa (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - art_u8 *buf, gint rowstride); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_GRAY_SVP_H__ */ diff --git a/libart_lgpl/art_misc.c b/libart_lgpl/art_misc.c deleted file mode 100644 index 08ddcd184c..0000000000 --- a/libart_lgpl/art_misc.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Various utility functions RLL finds useful. */ - -#include "config.h" -#include "art_misc.h" - -#ifdef HAVE_UINSTD_H -#include <unistd.h> -#endif -#include <stdio.h> -#include <stdarg.h> - -/** - * art_die: Print the error message to stderr and exit with a return code of 1. - * @fmt: The printf-style format for the error message. - * - * Used for dealing with severe errors. - **/ -void -art_die (const gchar *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - exit (1); -} - -/** - * art_warn: Print the warning message to stderr. - * @fmt: The printf-style format for the warning message. - * - * Used for generating warnings. - **/ -void -art_warn (const gchar *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); -} - -gpointer art_alloc (gsize size) -{ - return malloc (size); -} - -void art_free (gpointer ptr) -{ - free (ptr); -} - -gpointer art_realloc (gpointer ptr, gsize size) -{ - return realloc (ptr, size); -} diff --git a/libart_lgpl/art_misc.h b/libart_lgpl/art_misc.h deleted file mode 100644 index a124413e70..0000000000 --- a/libart_lgpl/art_misc.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Simple macros to set up storage allocation and basic types for libart - functions. */ - -#ifndef __ART_MISC_H__ -#define __ART_MISC_H__ - -#include <glib.h> -#include <stdlib.h> /* for malloc, etc. */ - -#ifdef __cplusplus -extern "C" { -#endif -gpointer art_alloc (gsize size); -void art_free (gpointer ptr); -gpointer art_realloc (gpointer ptr, gsize size); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -/* These aren't, strictly speaking, configuration macros, but they're - damn handy to have around, and may be worth playing with for - debugging. */ -#define art_new(type, n) ((type *)art_alloc ((n) * sizeof(type))) - -#define art_renew(p, type, n) ((type *)art_realloc (p, (n) * sizeof(type))) - -/* This one must be used carefully - in particular, p and max should - be variables. They can also be pstruct->el lvalues. */ -#define art_expand(p, type, max) \ - do { if (max) { p = art_renew (p, type, max <<= 1); } \ - else { max = 1; p = art_new (type, 1); } } while (0) - -typedef gint art_boolean; -#define ART_FALSE 0 -#define ART_TRUE 1 - -/* define pi */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif /* M_PI */ - -#ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#endif /* M_SQRT2 */ - -/* Provide macros to feature the GCC function attribute. - */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) -#define ART_GNUC_PRINTF( format_idx, arg_idx ) \ - __attribute__((__format__ (__printf__, format_idx, arg_idx))) -#define ART_GNUC_NORETURN \ - __attribute__((__noreturn__)) -#else /* !__GNUC__ */ -#define ART_GNUC_PRINTF( format_idx, arg_idx ) -#define ART_GNUC_NORETURN -#endif /* !__GNUC__ */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef guint8 art_u8; -typedef guint16 art_u16; -typedef guint32 art_u32; - -void ART_GNUC_NORETURN -art_die (const gchar *fmt, ...) ART_GNUC_PRINTF (1, 2); - -void -art_warn (const gchar *fmt, ...) ART_GNUC_PRINTF (1, 2); - -#ifdef __cplusplus -} -#endif - -#define ART_USE_NEW_INTERSECTOR - -#endif /* __ART_MISC_H__ */ diff --git a/libart_lgpl/art_pathcode.h b/libart_lgpl/art_pathcode.h deleted file mode 100644 index 87979ceb8f..0000000000 --- a/libart_lgpl/art_pathcode.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_PATHCODE_H__ -#define __ART_PATHCODE_H__ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef enum { - ART_MOVETO, - ART_MOVETO_OPEN, - ART_CURVETO, - ART_LINETO, - ART_END -} ArtPathcode; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_PATHCODE_H__ */ diff --git a/libart_lgpl/art_point.h b/libart_lgpl/art_point.h deleted file mode 100644 index a5486d22c6..0000000000 --- a/libart_lgpl/art_point.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_POINT_H__ -#define __ART_POINT_H__ - -#include <glib.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct _ArtPoint ArtPoint; - -struct _ArtPoint { - /*< public >*/ - gdouble x, y; -}; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_POINT_H__ */ diff --git a/libart_lgpl/art_rect.c b/libart_lgpl/art_rect.c deleted file mode 100644 index ec53d2d70f..0000000000 --- a/libart_lgpl/art_rect.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_rect.h" - -#include <math.h> - -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif /* MAX */ - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif /* MIN */ - -/* rectangle primitives stolen from gzilla */ - -/** - * art_irect_intersection: Find intersection of two integer rectangles. - * @dest: Where the result is stored. - * @src1: A source rectangle. - * @src2: Another source rectangle. - * - * Finds the intersection of @src1 and @src2. - **/ -void -art_irect_intersect (ArtIRect *dest, const ArtIRect *src1, const ArtIRect *src2) { - dest->x0 = MAX (src1->x0, src2->x0); - dest->y0 = MAX (src1->y0, src2->y0); - dest->x1 = MIN (src1->x1, src2->x1); - dest->y1 = MIN (src1->y1, src2->y1); -} - -/** - * art_irect_empty: Determine whether integer rectangle is empty. - * @src: The source rectangle. - * - * Return value: TRUE if @src is an empty rectangle, FALSE otherwise. - **/ -gint -art_irect_empty (const ArtIRect *src) { - return (src->x1 <= src->x0 || src->y1 <= src->y0); -} - -/** - * art_drect_copy: Make a copy of a rectangle. - * @dest: Where the copy is stored. - * @src: The source rectangle. - * - * Copies the rectangle. - **/ -void -art_drect_copy (ArtDRect *dest, const ArtDRect *src) { - dest->x0 = src->x0; - dest->y0 = src->y0; - dest->x1 = src->x1; - dest->y1 = src->y1; -} - -/** - * art_drect_union: Find union of two rectangles. - * @dest: Where the result is stored. - * @src1: A source rectangle. - * @src2: Another source rectangle. - * - * Finds the smallest rectangle that includes @src1 and @src2. - **/ -void -art_drect_union (ArtDRect *dest, const ArtDRect *src1, const ArtDRect *src2) { - if (art_drect_empty (src1)) { - art_drect_copy (dest, src2); - } else if (art_drect_empty (src2)) { - art_drect_copy (dest, src1); - } else { - dest->x0 = MIN (src1->x0, src2->x0); - dest->y0 = MIN (src1->y0, src2->y0); - dest->x1 = MAX (src1->x1, src2->x1); - dest->y1 = MAX (src1->y1, src2->y1); - } -} - -/** - * art_irect_empty: Determine whether rectangle is empty. - * @src: The source rectangle. - * - * Return value: TRUE if @src is an empty rectangle, FALSE otherwise. - **/ -gint -art_drect_empty (const ArtDRect *src) { - return (src->x1 <= src->x0 || src->y1 <= src->y0); -} - -/** - * art_drect_affine_transform: Affine transform rectangle. - * @dst: Where to store the result. - * @src: The source rectangle. - * @matrix: The affine transformation. - * - * Find the smallest rectangle enclosing the affine transformed @src. - * The result is exactly the affine transformation of @src when - * @matrix specifies a rectilinear affine transformation, otherwise it - * is a conservative approximation. - **/ -void -art_drect_affine_transform (ArtDRect *dst, - const ArtDRect *src, - const gdouble matrix[6]) -{ - gdouble x00, y00, x10, y10; - gdouble x01, y01, x11, y11; - - x00 = src->x0 * matrix[0] + src->y0 * matrix[2] + matrix[4]; - y00 = src->x0 * matrix[1] + src->y0 * matrix[3] + matrix[5]; - x10 = src->x1 * matrix[0] + src->y0 * matrix[2] + matrix[4]; - y10 = src->x1 * matrix[1] + src->y0 * matrix[3] + matrix[5]; - x01 = src->x0 * matrix[0] + src->y1 * matrix[2] + matrix[4]; - y01 = src->x0 * matrix[1] + src->y1 * matrix[3] + matrix[5]; - x11 = src->x1 * matrix[0] + src->y1 * matrix[2] + matrix[4]; - y11 = src->x1 * matrix[1] + src->y1 * matrix[3] + matrix[5]; - dst->x0 = MIN (MIN (x00, x10), MIN (x01, x11)); - dst->y0 = MIN (MIN (y00, y10), MIN (y01, y11)); - dst->x1 = MAX (MAX (x00, x10), MAX (x01, x11)); - dst->y1 = MAX (MAX (y00, y10), MAX (y01, y11)); -} - -/** - * art_drect_to_irect: Convert rectangle to integer rectangle. - * @dst: Where to store resulting integer rectangle. - * @src: The source rectangle. - * - * Find the smallest integer rectangle that encloses @src. - **/ -void -art_drect_to_irect (ArtIRect *dst, ArtDRect *src) -{ - dst->x0 = floor (src->x0); - dst->y0 = floor (src->y0); - dst->x1 = ceil (src->x1); - dst->y1 = ceil (src->y1); -} diff --git a/libart_lgpl/art_rect.h b/libart_lgpl/art_rect.h deleted file mode 100644 index fb3ebb762b..0000000000 --- a/libart_lgpl/art_rect.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RECT_H__ -#define __ART_RECT_H__ - -#include <glib.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _ArtDRect ArtDRect; -typedef struct _ArtIRect ArtIRect; - -struct _ArtDRect { - /*< public >*/ - gdouble x0, y0, x1, y1; -}; - -struct _ArtIRect { - /*< public >*/ - gint x0, y0, x1, y1; -}; - -/* Make a copy of the rectangle. */ -void art_irect_copy (ArtIRect *dest, const ArtIRect *src); - -/* Return the intersection of the two rectangles */ -void art_irect_intersect (ArtIRect *dest, - const ArtIRect *src1, const ArtIRect *src2); - -/* Return true if the rectangle is empty. */ -gint art_irect_empty (const ArtIRect *src); - -/* Make a copy of the rectangle. */ -void art_drect_copy (ArtDRect *dest, const ArtDRect *src); - -/* Find the smallest rectangle that includes both source rectangles. */ -void art_drect_union (ArtDRect *dest, - const ArtDRect *src1, const ArtDRect *src2); - -/* Return true if the rectangle is empty. */ -gint art_drect_empty (const ArtDRect *src); - -void -art_drect_affine_transform (ArtDRect *dst, const ArtDRect *src, - const gdouble matrix[6]); - -void art_drect_to_irect (ArtIRect *dst, ArtDRect *src); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libart_lgpl/art_rect_svp.c b/libart_lgpl/art_rect_svp.c deleted file mode 100644 index 0c4d39643e..0000000000 --- a/libart_lgpl/art_rect_svp.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_rect_svp.h" - -#include "art_misc.h" -#include "art_svp.h" -#include "art_rect.h" - -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif /* MAX */ - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif /* MIN */ - -/** - * art_drect_svp: Find the bounding box of a sorted vector path. - * @bbox: Where to store the bounding box. - * @svp: The SVP. - * - * Finds the bounding box of the SVP. - **/ -void -art_drect_svp (ArtDRect *bbox, const ArtSVP *svp) -{ - gint i; - - if (svp->n_segs == 0) - { - bbox->x0 = 0; - bbox->y0 = 0; - bbox->x1 = 0; - bbox->y1 = 0; - return; - } - - art_drect_copy (bbox, &svp->segs[0].bbox); - - for (i = 1; i < svp->n_segs; i++) - { - bbox->x0 = MIN (bbox->x0, svp->segs[i].bbox.x0); - bbox->y0 = MIN (bbox->y0, svp->segs[i].bbox.y0); - bbox->x1 = MAX (bbox->x1, svp->segs[i].bbox.x1); - bbox->y1 = MAX (bbox->y1, svp->segs[i].bbox.y1); - } -} - -/** - * art_drect_svp_union: - * @bbox: Initial boundin box and where to store the bounding box. - * @svp: The SVP. - * - * Finds the bounding box of the SVP, computing its union with an - * existing bbox. - **/ -void -art_drect_svp_union (ArtDRect *bbox, const ArtSVP *svp) -{ - ArtDRect svp_bbox; - - art_drect_svp (&svp_bbox, svp); - art_drect_union (bbox, bbox, &svp_bbox); -} diff --git a/libart_lgpl/art_rect_svp.h b/libart_lgpl/art_rect_svp.h deleted file mode 100644 index 496826decf..0000000000 --- a/libart_lgpl/art_rect_svp.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RECT_SVP_H__ -#define __ART_RECT_SVP_H__ - -/* Find the bounding box of a sorted vector path. */ - -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -void -art_drect_svp (ArtDRect *bbox, const ArtSVP *svp); - -/* Compute the bounding box of the svp and union it in to the - existing bounding box. */ -void -art_drect_svp_union (ArtDRect *bbox, const ArtSVP *svp); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_RECT_SVP_H__ */ diff --git a/libart_lgpl/art_rect_uta.c b/libart_lgpl/art_rect_uta.c deleted file mode 100644 index 9a2f0c8ce9..0000000000 --- a/libart_lgpl/art_rect_uta.c +++ /dev/null @@ -1,133 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_rect_uta.h" - -/* Functions to decompose a microtile array into a list of rectangles. */ - -/** - * art_rect_list_from_uta: Decompose uta into list of rectangles. - * @uta: The source uta. - * @max_width: The maximum width of the resulting rectangles. - * @max_height: The maximum height of the resulting rectangles. - * @p_nrects: Where to store the number of returned rectangles. - * - * Allocates a new list of rectangles, sets *@p_nrects to the number - * in the list. This list should be freed with art_free(). - * - * Each rectangle bounded in size by (@max_width, @max_height). - * However, these bounds must be at least the size of one tile. - * - * This routine provides a precise implementation, i.e. the rectangles - * cover exactly the same area as the uta. It is thus appropriate in - * cases where the overhead per rectangle is small compared with the - * cost of filling in extra pixels. - * - * Return value: An array containing the resulting rectangles. - **/ -ArtIRect * -art_rect_list_from_uta (ArtUta *uta, gint max_width, gint max_height, - gint *p_nrects) -{ - ArtIRect *rects; - gint n_rects, n_rects_max; - gint x, y; - gint width, height; - gint ix; - gint left_ix; - ArtUtaBbox *utiles; - ArtUtaBbox bb; - gint x0, y0, x1, y1; - gint *glom; - gint glom_rect; - - n_rects = 0; - n_rects_max = 1; - rects = art_new (ArtIRect, n_rects_max); - - width = uta->width; - height = uta->height; - utiles = uta->utiles; - - glom = art_new (int, width * height); - for (ix = 0; ix < width * height; ix++) - glom[ix] = -1; - - ix = 0; - for (y = 0; y < height; y++) - for (x = 0; x < width; x++) - { - bb = utiles[ix]; - if (bb) - { - x0 = ((uta->x0 + x) << ART_UTILE_SHIFT) + ART_UTA_BBOX_X0 (bb); - y0 = ((uta->y0 + y) << ART_UTILE_SHIFT) + ART_UTA_BBOX_Y0 (bb); - y1 = ((uta->y0 + y) << ART_UTILE_SHIFT) + ART_UTA_BBOX_Y1 (bb); - - left_ix = ix; - /* now try to extend to the right */ - while (x != width - 1 && - ART_UTA_BBOX_X1 (bb) == ART_UTILE_SIZE && - (((bb & 0xffffff) ^ utiles[ix + 1]) & 0xffff00ff) == 0 && - (((uta->x0 + x + 1) << ART_UTILE_SHIFT) + - ART_UTA_BBOX_X1 (utiles[ix + 1]) - - x0) <= max_width) - { - bb = utiles[ix + 1]; - ix++; - x++; - } - x1 = ((uta->x0 + x) << ART_UTILE_SHIFT) + ART_UTA_BBOX_X1 (bb); - - /* if rectangle nonempty */ - if ((x1 ^ x0) | (y1 ^ y0)) - { - /* try to glom onto an existing rectangle */ - glom_rect = glom[left_ix]; - if (glom_rect != -1 && - x0 == rects[glom_rect].x0 && - x1 == rects[glom_rect].x1 && - y0 == rects[glom_rect].y1 && - y1 - rects[glom_rect].y0 <= max_height) - { - rects[glom_rect].y1 = y1; - } - else - { - if (n_rects == n_rects_max) - art_expand (rects, ArtIRect, n_rects_max); - rects[n_rects].x0 = x0; - rects[n_rects].y0 = y0; - rects[n_rects].x1 = x1; - rects[n_rects].y1 = y1; - glom_rect = n_rects; - n_rects++; - } - if (y != height - 1) - glom[left_ix + width] = glom_rect; - } - } - ix++; - } - - art_free (glom); - *p_nrects = n_rects; - return rects; -} diff --git a/libart_lgpl/art_rect_uta.h b/libart_lgpl/art_rect_uta.h deleted file mode 100644 index 7b07d89ad9..0000000000 --- a/libart_lgpl/art_rect_uta.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RECT_UTA_H__ -#define __ART_RECT_UTA_H__ - -#include <libart_lgpl/art_rect.h> -#include <libart_lgpl/art_uta.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -ArtIRect * -art_rect_list_from_uta (ArtUta *uta, gint max_width, gint max_height, - gint *p_nrects); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_RECT_UTA_H__ */ diff --git a/libart_lgpl/art_render.c b/libart_lgpl/art_render.c deleted file mode 100644 index 6c71e4a260..0000000000 --- a/libart_lgpl/art_render.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * art_render.c: Modular rendering architecture. - * - * Libart_LGPL - library of basic graphic primitives - * Copyright (C) 2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_render.h" - -#include "art_rgb.h" - -typedef struct _ArtRenderPriv ArtRenderPriv; - -struct _ArtRenderPriv { - ArtRender super; - - ArtImageSource *image_source; - - gint n_mask_source; - ArtMaskSource **mask_source; - - gint n_callbacks; - ArtRenderCallback **callbacks; -}; - -static void -art_render_nop_done (ArtRenderCallback *self, ArtRender *render) -{ -} - -static void -art_render_clear_render_rgb8 (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y) -{ - gint width = render->x1 - render->x0; - art_u8 r, g, b; - ArtPixMaxDepth color_max; - - color_max = render->clear_color[0]; - r = ART_PIX_8_FROM_MAX (color_max); - color_max = render->clear_color[1]; - g = ART_PIX_8_FROM_MAX (color_max); - color_max = render->clear_color[2]; - b = ART_PIX_8_FROM_MAX (color_max); - - art_rgb_fill_run (dest, r, g, b, width); -} - -static void -art_render_clear_render_8 (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y) -{ - gint width = render->x1 - render->x0; - gint i, j; - gint n_ch = render->n_chan + (render->alpha_type != ART_ALPHA_NONE); - gint ix; - art_u8 color[ART_MAX_CHAN + 1]; - - for (j = 0; j < n_ch; j++) - { - ArtPixMaxDepth color_max = render->clear_color[j]; - color[j] = ART_PIX_8_FROM_MAX (color_max); - } - - ix = 0; - for (i = 0; i < width; i++) - for (j = 0; j < n_ch; j++) - dest[ix++] = color[j]; -} - -const ArtRenderCallback art_render_clear_rgb8_obj = -{ - art_render_clear_render_rgb8, - art_render_nop_done -}; - -const ArtRenderCallback art_render_clear_8_obj = -{ - art_render_clear_render_8, - art_render_nop_done -}; - -#if ART_MAX_DEPTH >= 16 - -static void -art_render_clear_render_16 (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y) -{ - gint width = render->x1 - render->x0; - gint i, j; - gint n_ch = render->n_chan + (render->alpha_type != ART_ALPHA_NONE); - gint ix; - art_u16 *dest_16 = (art_u16 *)dest; - art_u8 color[ART_MAX_CHAN + 1]; - - for (j = 0; j < n_ch; j++) - { - gint color_16 = render->clear_color[j]; - color[j] = color_16; - } - - ix = 0; - for (i = 0; i < width; i++) - for (j = 0; j < n_ch; j++) - dest_16[ix++] = color[j]; -} - -const ArtRenderCallback art_render_clear_16_obj = -{ - art_render_clear_render_16, - art_render_nop_done -}; - -#endif /* ART_MAX_DEPTH >= 16 */ - -/* This is the most general form of the function. It is slow but - (hopefully) correct. Actually, I'm still worried about roundoff - errors in the premul case - it seems to me that an off-by-one could - lead to overflow. */ -static void -art_render_composite (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y) -{ - ArtRenderMaskRun *run = render->run; - art_u32 depth = render->depth; - gint n_run = render->n_run; - gint x0 = render->x0; - gint x; - gint run_x0, run_x1; - art_u8 *alpha_buf = render->alpha_buf; - art_u8 *image_buf = render->image_buf; - gint i, j; - art_u32 tmp; - art_u32 run_alpha; - art_u32 alpha; - gint image_ix; - art_u16 src[ART_MAX_CHAN + 1]; - art_u16 dst[ART_MAX_CHAN + 1]; - gint n_chan = render->n_chan; - ArtAlphaType alpha_type = render->alpha_type; - gint n_ch = n_chan + (alpha_type != ART_ALPHA_NONE); - gint dst_pixstride = n_ch * (depth >> 3); - gint buf_depth = render->buf_depth; - ArtAlphaType buf_alpha = render->buf_alpha; - gint buf_n_ch = n_chan + (buf_alpha != ART_ALPHA_NONE); - gint buf_pixstride = buf_n_ch * (buf_depth >> 3); - art_u8 *bufptr; - art_u32 src_alpha; - art_u32 src_mul; - art_u8 *dstptr; - art_u32 dst_alpha; - art_u32 dst_mul; - - image_ix = 0; - for (i = 0; i < n_run - 1; i++) - { - run_x0 = run[i].x; - run_x1 = run[i + 1].x; - tmp = run[i].alpha; - if (tmp < 0x8100) - continue; - - run_alpha = (tmp + (tmp >> 8) + (tmp >> 16) - 0x8000) >> 8; - bufptr = image_buf + (run_x0 - x0) * buf_pixstride; - dstptr = dest + (run_x0 - x0) * dst_pixstride; - for (x = run_x0; x < run_x1; x++) - { - if (alpha_buf) - { - if (depth == 8) - { - tmp = run_alpha * alpha_buf[x - x0] + 0x80; - /* range 0x80 .. 0xff0080 */ - alpha = (tmp + (tmp >> 8) + (tmp >> 16)) >> 8; - } - else /* (depth == 16) */ - { - tmp = ((art_u16 *)alpha_buf)[x - x0]; - tmp = (run_alpha * tmp + 0x8000) >> 8; - /* range 0x80 .. 0xffff80 */ - alpha = (tmp + (tmp >> 16)) >> 8; - } - } - else - alpha = run_alpha; - /* alpha is run_alpha * alpha_buf[x], range 0 .. 0x10000 */ - - /* convert (src pixel * alpha) to premul alpha form, - store in src as 0..0xffff range */ - if (buf_alpha == ART_ALPHA_NONE) - { - src_alpha = alpha; - src_mul = src_alpha; - } - else - { - if (buf_depth == 8) - { - tmp = alpha * bufptr[n_chan] + 0x80; - /* range 0x80 .. 0xff0080 */ - src_alpha = (tmp + (tmp >> 8) + (tmp >> 16)) >> 8; - } - else /* (depth == 16) */ - { - tmp = ((art_u16 *)bufptr)[n_chan]; - tmp = (alpha * tmp + 0x8000) >> 8; - /* range 0x80 .. 0xffff80 */ - src_alpha = (tmp + (tmp >> 16)) >> 8; - } - if (buf_alpha == ART_ALPHA_SEPARATE) - src_mul = src_alpha; - else /* buf_alpha == (ART_ALPHA_PREMUL) */ - src_mul = alpha; - } - /* src_alpha is the (alpha of the source pixel * alpha), - range 0..0x10000 */ - - if (buf_depth == 8) - { - src_mul *= 0x101; - for (j = 0; j < n_chan; j++) - src[j] = (bufptr[j] * src_mul + 0x8000) >> 16; - } - else if (buf_depth == 16) - { - for (j = 0; j < n_chan; j++) - src[j] = (((art_u16 *)bufptr)[j] * src_mul + 0x8000) >> 16; - } - bufptr += buf_pixstride; - - /* src[0..n_chan - 1] (range 0..0xffff) and src_alpha (range - 0..0x10000) now contain the source pixel with - premultiplied alpha */ - - /* convert dst pixel to premul alpha form, - store in dst as 0..0xffff range */ - if (alpha_type == ART_ALPHA_NONE) - { - dst_alpha = 0x10000; - dst_mul = dst_alpha; - } - else - { - if (depth == 8) - { - tmp = dstptr[n_chan]; - /* range 0..0xff */ - dst_alpha = (tmp << 8) + tmp + (tmp >> 7); - } - else /* (depth == 16) */ - { - tmp = ((art_u16 *)dstptr)[n_chan]; - dst_alpha = (tmp + (tmp >> 15)); - } - if (alpha_type == ART_ALPHA_SEPARATE) - dst_mul = dst_alpha; - else /* (alpha_type == ART_ALPHA_PREMUL) */ - dst_mul = 0x10000; - } - /* dst_alpha is the alpha of the dest pixel, - range 0..0x10000 */ - - if (depth == 8) - { - dst_mul *= 0x101; - for (j = 0; j < n_chan; j++) - dst[j] = (dstptr[j] * dst_mul + 0x8000) >> 16; - } - else if (buf_depth == 16) - { - for (j = 0; j < n_chan; j++) - dst[j] = (((art_u16 *)dstptr)[j] * dst_mul + 0x8000) >> 16; - } - - /* do the compositing, dst = (src over dst) */ - for (j = 0; j < n_chan; j++) - { - art_u32 srcv, dstv; - art_u32 tmp; - - srcv = src[j]; - dstv = dst[j]; - tmp = ((dstv * (0x10000 - src_alpha) + 0x8000) >> 16) + srcv; - tmp -= tmp >> 16; - dst[j] = tmp; - } - - if (alpha_type == ART_ALPHA_NONE) - { - if (depth == 8) - dst_mul = 0xff; - else /* (depth == 16) */ - dst_mul = 0xffff; - } - else - { - if (src_alpha >= 0x10000) - dst_alpha = 0x10000; - else - dst_alpha += ((((0x10000 - dst_alpha) * src_alpha) >> 8) + 0x80) >> 8; - if (alpha_type == ART_ALPHA_PREMUL || dst_alpha == 0) - { - if (depth == 8) - dst_mul = 0xff; - else /* (depth == 16) */ - dst_mul = 0xffff; - } - else /* (ALPHA_TYPE == ART_ALPHA_SEPARATE && dst_alpha != 0) */ - { - if (depth == 8) - dst_mul = 0xff0000 / dst_alpha; - else /* (depth == 16) */ - dst_mul = 0xffff0000 / dst_alpha; - } - } - if (depth == 8) - { - for (j = 0; j < n_chan; j++) - dstptr[j] = (dst[j] * dst_mul + 0x8000) >> 16; - if (alpha_type != ART_ALPHA_NONE) - dstptr[n_chan] = (dst_alpha * 0xff + 0x8000) >> 16; - } - else if (depth == 16) - { - for (j = 0; j < n_chan; j++) - ((art_u16 *)dstptr)[j] = (dst[j] * dst_mul + 0x8000) >> 16; - if (alpha_type != ART_ALPHA_NONE) - ((art_u16 *)dstptr)[n_chan] = (dst_alpha * 0xffff + 0x8000) >> 16; - } - dstptr += dst_pixstride; - } - } -} - -const ArtRenderCallback art_render_composite_obj = -{ - art_render_composite, - art_render_nop_done -}; - -static void -art_render_composite_8 (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y) -{ - ArtRenderMaskRun *run = render->run; - gint n_run = render->n_run; - gint x0 = render->x0; - gint x; - gint run_x0, run_x1; - art_u8 *alpha_buf = render->alpha_buf; - art_u8 *image_buf = render->image_buf; - gint i, j; - art_u32 tmp; - art_u32 run_alpha; - art_u32 alpha; - gint image_ix; - gint n_chan = render->n_chan; - ArtAlphaType alpha_type = render->alpha_type; - gint n_ch = n_chan + (alpha_type != ART_ALPHA_NONE); - gint dst_pixstride = n_ch; - ArtAlphaType buf_alpha = render->buf_alpha; - gint buf_n_ch = n_chan + (buf_alpha != ART_ALPHA_NONE); - gint buf_pixstride = buf_n_ch; - art_u8 *bufptr; - art_u32 src_alpha; - art_u32 src_mul; - art_u8 *dstptr; - art_u32 dst_alpha; - art_u32 dst_mul, dst_save_mul; - - image_ix = 0; - for (i = 0; i < n_run - 1; i++) - { - run_x0 = run[i].x; - run_x1 = run[i + 1].x; - tmp = run[i].alpha; - if (tmp < 0x10000) - continue; - - run_alpha = (tmp + (tmp >> 8) + (tmp >> 16) - 0x8000) >> 8; - bufptr = image_buf + (run_x0 - x0) * buf_pixstride; - dstptr = dest + (run_x0 - x0) * dst_pixstride; - for (x = run_x0; x < run_x1; x++) - { - if (alpha_buf) - { - tmp = run_alpha * alpha_buf[x - x0] + 0x80; - /* range 0x80 .. 0xff0080 */ - alpha = (tmp + (tmp >> 8) + (tmp >> 16)) >> 8; - } - else - alpha = run_alpha; - /* alpha is run_alpha * alpha_buf[x], range 0 .. 0x10000 */ - - /* convert (src pixel * alpha) to premul alpha form, - store in src as 0..0xffff range */ - if (buf_alpha == ART_ALPHA_NONE) - { - src_alpha = alpha; - src_mul = src_alpha; - } - else - { - tmp = alpha * bufptr[n_chan] + 0x80; - /* range 0x80 .. 0xff0080 */ - src_alpha = (tmp + (tmp >> 8) + (tmp >> 16)) >> 8; - - if (buf_alpha == ART_ALPHA_SEPARATE) - src_mul = src_alpha; - else /* buf_alpha == (ART_ALPHA_PREMUL) */ - src_mul = alpha; - } - /* src_alpha is the (alpha of the source pixel * alpha), - range 0..0x10000 */ - - src_mul *= 0x101; - - if (alpha_type == ART_ALPHA_NONE) - { - dst_alpha = 0x10000; - dst_mul = dst_alpha; - } - else - { - tmp = dstptr[n_chan]; - /* range 0..0xff */ - dst_alpha = (tmp << 8) + tmp + (tmp >> 7); - if (alpha_type == ART_ALPHA_SEPARATE) - dst_mul = dst_alpha; - else /* (alpha_type == ART_ALPHA_PREMUL) */ - dst_mul = 0x10000; - } - /* dst_alpha is the alpha of the dest pixel, - range 0..0x10000 */ - - dst_mul *= 0x101; - - if (alpha_type == ART_ALPHA_NONE) - { - dst_save_mul = 0xff; - } - else - { - if (src_alpha >= 0x10000) - dst_alpha = 0x10000; - else - dst_alpha += ((((0x10000 - dst_alpha) * src_alpha) >> 8) + 0x80) >> 8; - if (alpha_type == ART_ALPHA_PREMUL || dst_alpha == 0) - { - dst_save_mul = 0xff; - } - else /* (ALPHA_TYPE == ART_ALPHA_SEPARATE && dst_alpha != 0) */ - { - dst_save_mul = 0xff0000 / dst_alpha; - } - } - - for (j = 0; j < n_chan; j++) - { - art_u32 src, dst; - art_u32 tmp; - - src = (bufptr[j] * src_mul + 0x8000) >> 16; - dst = (dstptr[j] * dst_mul + 0x8000) >> 16; - tmp = ((dst * (0x10000 - src_alpha) + 0x8000) >> 16) + src; - tmp -= tmp >> 16; - dstptr[j] = (tmp * dst_save_mul + 0x8000) >> 16; - } - if (alpha_type != ART_ALPHA_NONE) - dstptr[n_chan] = (dst_alpha * 0xff + 0x8000) >> 16; - - bufptr += buf_pixstride; - dstptr += dst_pixstride; - } - } -} - -const ArtRenderCallback art_render_composite_8_obj = -{ - art_render_composite_8, - art_render_nop_done -}; - -/* Assumes: - * alpha_buf is NULL - * buf_alpha = ART_ALPHA_NONE (source) - * alpha_type = ART_ALPHA_SEPARATE (dest) - * n_chan = 3; - */ -static void -art_render_composite_8_opt1 (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y) -{ - ArtRenderMaskRun *run = render->run; - gint n_run = render->n_run; - gint x0 = render->x0; - gint x; - gint run_x0, run_x1; - art_u8 *image_buf = render->image_buf; - gint i, j; - art_u32 tmp; - art_u32 run_alpha; - gint image_ix; - art_u8 *bufptr; - art_u32 src_mul; - art_u8 *dstptr; - art_u32 dst_alpha; - art_u32 dst_mul, dst_save_mul; - - image_ix = 0; - for (i = 0; i < n_run - 1; i++) - { - run_x0 = run[i].x; - run_x1 = run[i + 1].x; - tmp = run[i].alpha; - if (tmp < 0x10000) - continue; - - run_alpha = (tmp + (tmp >> 8) + (tmp >> 16) - 0x8000) >> 8; - bufptr = image_buf + (run_x0 - x0) * 3; - dstptr = dest + (run_x0 - x0) * 4; - if (run_alpha == 0x10000) - { - for (x = run_x0; x < run_x1; x++) - { - *dstptr++ = *bufptr++; - *dstptr++ = *bufptr++; - *dstptr++ = *bufptr++; - *dstptr++ = 0xff; - } - } - else - { - for (x = run_x0; x < run_x1; x++) - { - src_mul = run_alpha * 0x101; - - tmp = dstptr[3]; - /* range 0..0xff */ - dst_alpha = (tmp << 8) + tmp + (tmp >> 7); - dst_mul = dst_alpha; - /* dst_alpha is the alpha of the dest pixel, - range 0..0x10000 */ - - dst_mul *= 0x101; - - dst_alpha += ((((0x10000 - dst_alpha) * run_alpha) >> 8) + 0x80) >> 8; - if (dst_alpha == 0) - dst_save_mul = 0xff; - else /* (dst_alpha != 0) */ - dst_save_mul = 0xff0000 / dst_alpha; - - for (j = 0; j < 3; j++) - { - art_u32 src, dst; - art_u32 tmp; - - src = (bufptr[j] * src_mul + 0x8000) >> 16; - dst = (dstptr[j] * dst_mul + 0x8000) >> 16; - tmp = ((dst * (0x10000 - run_alpha) + 0x8000) >> 16) + src; - tmp -= tmp >> 16; - dstptr[j] = (tmp * dst_save_mul + 0x8000) >> 16; - } - dstptr[3] = (dst_alpha * 0xff + 0x8000) >> 16; - - bufptr += 3; - dstptr += 4; - } - } - } -} - -const ArtRenderCallback art_render_composite_8_opt1_obj = -{ - art_render_composite_8_opt1, - art_render_nop_done -}; - -/* Assumes: - * alpha_buf is NULL - * buf_alpha = ART_ALPHA_PREMUL (source) - * alpha_type = ART_ALPHA_SEPARATE (dest) - * n_chan = 3; - */ -static void -art_render_composite_8_opt2 (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y) -{ - ArtRenderMaskRun *run = render->run; - gint n_run = render->n_run; - gint x0 = render->x0; - gint x; - gint run_x0, run_x1; - art_u8 *image_buf = render->image_buf; - gint i, j; - art_u32 tmp; - art_u32 run_alpha; - gint image_ix; - art_u8 *bufptr; - art_u32 src_alpha; - art_u32 src_mul; - art_u8 *dstptr; - art_u32 dst_alpha; - art_u32 dst_mul, dst_save_mul; - - image_ix = 0; - for (i = 0; i < n_run - 1; i++) - { - run_x0 = run[i].x; - run_x1 = run[i + 1].x; - tmp = run[i].alpha; - if (tmp < 0x10000) - continue; - - run_alpha = (tmp + (tmp >> 8) + (tmp >> 16) - 0x8000) >> 8; - bufptr = image_buf + (run_x0 - x0) * 4; - dstptr = dest + (run_x0 - x0) * 4; - if (run_alpha == 0x10000) - { - for (x = run_x0; x < run_x1; x++) - { - src_alpha = (bufptr[3] << 8) + bufptr[3] + (bufptr[3] >> 7); - /* src_alpha is the (alpha of the source pixel), - range 0..0x10000 */ - - dst_alpha = (dstptr[3] << 8) + dstptr[3] + (dstptr[3] >> 7); - /* dst_alpha is the alpha of the dest pixel, - range 0..0x10000 */ - - dst_mul = dst_alpha*0x101; - - if (src_alpha >= 0x10000) - dst_alpha = 0x10000; - else - dst_alpha += ((((0x10000 - dst_alpha) * src_alpha) >> 8) + 0x80) >> 8; - - if (dst_alpha == 0) - dst_save_mul = 0xff; - else /* dst_alpha != 0) */ - dst_save_mul = 0xff0000 / dst_alpha; - - for (j = 0; j < 3; j++) - { - art_u32 src, dst; - art_u32 tmp; - - src = (bufptr[j] << 8) | bufptr[j]; - dst = (dstptr[j] * dst_mul + 0x8000) >> 16; - tmp = ((dst * (0x10000 - src_alpha) + 0x8000) >> 16) + src; - tmp -= tmp >> 16; - dstptr[j] = (tmp * dst_save_mul + 0x8000) >> 16; - } - dstptr[3] = (dst_alpha * 0xff + 0x8000) >> 16; - - bufptr += 4; - dstptr += 4; - } - } - else - { - for (x = run_x0; x < run_x1; x++) - { - tmp = run_alpha * bufptr[3] + 0x80; - /* range 0x80 .. 0xff0080 */ - src_alpha = (tmp + (tmp >> 8) + (tmp >> 16)) >> 8; - /* src_alpha is the (alpha of the source pixel * alpha), - range 0..0x10000 */ - - src_mul = run_alpha * 0x101; - - tmp = dstptr[3]; - /* range 0..0xff */ - dst_alpha = (tmp << 8) + tmp + (tmp >> 7); - dst_mul = dst_alpha; - /* dst_alpha is the alpha of the dest pixel, - range 0..0x10000 */ - - dst_mul *= 0x101; - - if (src_alpha >= 0x10000) - dst_alpha = 0x10000; - else - dst_alpha += ((((0x10000 - dst_alpha) * src_alpha) >> 8) + 0x80) >> 8; - - if (dst_alpha == 0) - { - dst_save_mul = 0xff; - } - else /* dst_alpha != 0) */ - { - dst_save_mul = 0xff0000 / dst_alpha; - } - - for (j = 0; j < 3; j++) - { - art_u32 src, dst; - art_u32 tmp; - - src = (bufptr[j] * src_mul + 0x8000) >> 16; - dst = (dstptr[j] * dst_mul + 0x8000) >> 16; - tmp = ((dst * (0x10000 - src_alpha) + 0x8000) >> 16) + src; - tmp -= tmp >> 16; - dstptr[j] = (tmp * dst_save_mul + 0x8000) >> 16; - } - dstptr[3] = (dst_alpha * 0xff + 0x8000) >> 16; - - bufptr += 4; - dstptr += 4; - } - } - } -} - -const ArtRenderCallback art_render_composite_8_opt2_obj = -{ - art_render_composite_8_opt2, - art_render_nop_done -}; - diff --git a/libart_lgpl/art_render.h b/libart_lgpl/art_render.h deleted file mode 100644 index 0675722add..0000000000 --- a/libart_lgpl/art_render.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * art_render.h: Modular rendering architecture. - * - * Libart_LGPL - library of basic graphic primitives - * Copyright (C) 2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RENDER_H__ -#define __ART_RENDER_H__ - -#include <libart_lgpl/art_alphagamma.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Render object */ - -#ifndef ART_MAX_DEPTH -#define ART_MAX_DEPTH 16 -#endif - -#if ART_MAX_DEPTH == 16 -typedef art_u16 ArtPixMaxDepth; -#define ART_PIX_MAX_FROM_8(x) ((x) | ((x) << 8)) -#define ART_PIX_8_FROM_MAX(x) (((x) + 0x80 - (((x) + 0x80) >> 8)) >> 8) -#else -#if ART_MAX_DEPTH == 8 -typedef art_u8 ArtPixMaxDepth; -#define ART_PIX_MAX_FROM_8(x) (x) -#define ART_PIX_8_FROM_MAX(x) (x) -#else -#error ART_MAX_DEPTH must be either 8 or 16 -#endif -#endif - -#define ART_MAX_CHAN 16 - -typedef struct _ArtRender ArtRender; -typedef struct _ArtRenderCallback ArtRenderCallback; -typedef struct _ArtRenderMaskRun ArtRenderMaskRun; -typedef struct _ArtImageSource ArtImageSource; -typedef struct _ArtMaskSource ArtMaskSource; - -typedef enum { - ART_ALPHA_NONE = 0, - ART_ALPHA_SEPARATE = 1, - ART_ALPHA_PREMUL = 2 -} ArtAlphaType; - -typedef enum { - ART_COMPOSITE_NORMAL, - ART_COMPOSITE_MULTIPLY, - /* todo: more */ - ART_COMPOSITE_CUSTOM -} ArtCompositingMode; - -typedef enum { - ART_IMAGE_SOURCE_CAN_CLEAR = 1, - ART_IMAGE_SOURCE_CAN_COMPOSITE = 2 -} ArtImageSourceFlags; - -struct _ArtRenderMaskRun { - gint x; - gint alpha; -}; - -struct _ArtRenderCallback { - void (*render) (ArtRenderCallback *self, ArtRender *render, - art_u8 *dest, gint y); - void (*done) (ArtRenderCallback *self, ArtRender *render); -}; - -struct _ArtImageSource { - ArtRenderCallback super; - void (*negotiate) (ArtImageSource *self, ArtRender *render, - ArtImageSourceFlags *p_flags, - gint *p_buf_depth, ArtAlphaType *p_alpha_type); -}; - -struct _ArtMaskSource { - ArtRenderCallback super; - gint (*can_drive) (ArtMaskSource *self, ArtRender *render); - /* For each mask source, ::prepare() is invoked if it is not - a driver, or ::invoke_driver () if it is. */ - void (*invoke_driver) (ArtMaskSource *self, ArtRender *render); - void (*prepare) (ArtMaskSource *self, ArtRender *render, art_boolean first); -}; - -struct _ArtRender { - /* parameters of destination image */ - gint x0, y0; - gint x1, y1; - art_u8 *pixels; - gint rowstride; - gint n_chan; - gint depth; - ArtAlphaType alpha_type; - - art_boolean clear; - ArtPixMaxDepth clear_color[ART_MAX_CHAN + 1]; - art_u32 opacity; /*[0..0x10000] */ - - ArtCompositingMode compositing_mode; - - ArtAlphaGamma *alphagamma; - - art_u8 *alpha_buf; - - /* parameters of intermediate buffer */ - gint buf_depth; - ArtAlphaType buf_alpha; - art_u8 *image_buf; - - /* driving alpha scanline data */ - /* A "run" is a contiguous sequence of x values with the same alpha value. */ - gint n_run; - ArtRenderMaskRun *run; - - /* A "span" is a contiguous sequence of x values with non-zero alpha. */ - gint n_span; - gint *span_x; - - art_boolean need_span; -}; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_RENDER_H__ */ - diff --git a/libart_lgpl/art_rgb.c b/libart_lgpl/art_rgb.c deleted file mode 100644 index 34e6d237f9..0000000000 --- a/libart_lgpl/art_rgb.c +++ /dev/null @@ -1,175 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_rgb.h" - -#include <string.h> /* for memset */ - -/* Basic operators for manipulating 24-bit packed RGB buffers. */ - -#define COLOR_RUN_COMPLEX - -#ifdef COLOR_RUN_SIMPLE -/* This is really slow. Is there any way we might speed it up? - Two ideas: - - First, maybe we should be working at 32-bit alignment. Then, - this can be a simple loop over word stores. - - Second, we can keep working at 24-bit alignment, but have some - intelligence about storing. For example, we can iterate over - 4-pixel chunks (aligned at 4 pixels), with an inner loop - something like: - - *buf++ = v1; - *buf++ = v2; - *buf++ = v3; - - One source of extra complexity is the need to make sure linebuf is - aligned to a 32-bit boundary. - - This second alternative has some complexity to it, but is - appealing because it really minimizes the memory bandwidth. */ -void -art_rgb_fill_run (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, gint n) -{ - gint i; - - if (r == g && g == b) - { - memset (buf, g, n + n + n); - } - else - { - for (i = 0; i < n; i++) - { - *buf++ = r; - *buf++ = g; - *buf++ = b; - } - } -} -#endif - -#ifdef COLOR_RUN_COMPLEX -/* This implements the second of the two ideas above. The test results - are _very_ encouraging - it seems the speed is within 10% of - memset, which is quite good! */ -/** - * art_rgb_fill_run: fill a buffer a solid RGB color. - * @buf: Buffer to fill. - * @r: Red, range 0..255. - * @g: Green, range 0..255. - * @b: Blue, range 0..255. - * @n: Number of RGB triples to fill. - * - * Fills a buffer with @n copies of the (@r, @g, @b) triple. Thus, - * locations @buf (inclusive) through @buf + 3 * @n (exclusive) are - * written. - * - * The implementation of this routine is very highly optimized. - **/ -void -art_rgb_fill_run (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, gint n) -{ - gint i; - guint v1, v2, v3; - - if (r == g && g == b) - { - memset (buf, g, n + n + n); - } - else - { - if (n < 8) - { - for (i = 0; i < n; i++) - { - *buf++ = r; - *buf++ = g; - *buf++ = b; - } - } else { - /* handle prefix up to byte alignment */ - /* I'm worried about this cast on sizeof(long) != sizeof(uchar *) - architectures, but it _should_ work. */ - for (i = 0; ((unsigned long)buf) & 3; i++) - { - *buf++ = r; - *buf++ = g; - *buf++ = b; - } -#ifndef WORDS_BIGENDIAN - v1 = r | (g << 8) | (b << 16) | (r << 24); - v3 = (v1 << 8) | b; - v2 = (v3 << 8) | g; -#else - v1 = (r << 24) | (g << 16) | (b << 8) | r; - v2 = (v1 << 8) | g; - v3 = (v2 << 8) | b; -#endif - for (; i < n - 3; i += 4) - { - ((art_u32 *)buf)[0] = v1; - ((art_u32 *)buf)[1] = v2; - ((art_u32 *)buf)[2] = v3; - buf += 12; - } - /* handle postfix */ - for (; i < n; i++) - { - *buf++ = r; - *buf++ = g; - *buf++ = b; - } - } - } -} -#endif - -/** - * art_rgb_run_alpha: Render semitransparent color over RGB buffer. - * @buf: Buffer for rendering. - * @r: Red, range 0..255. - * @g: Green, range 0..255. - * @b: Blue, range 0..255. - * @alpha: Alpha, range 0..256. - * @n: Number of RGB triples to render. - * - * Renders a sequential run of solid (@r, @g, @b) color over @buf with - * opacity @alpha. - **/ -void -art_rgb_run_alpha (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, gint alpha, gint n) -{ - gint i; - gint v; - - for (i = 0; i < n; i++) - { - v = *buf; - *buf++ = v + (((r - v) * alpha + 0x80) >> 8); - v = *buf; - *buf++ = v + (((g - v) * alpha + 0x80) >> 8); - v = *buf; - *buf++ = v + (((b - v) * alpha + 0x80) >> 8); - } -} - diff --git a/libart_lgpl/art_rgb.h b/libart_lgpl/art_rgb.h deleted file mode 100644 index d7581b4402..0000000000 --- a/libart_lgpl/art_rgb.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RGB_H__ -#define __ART_RGB_H__ - -#include <libart_lgpl/art_misc.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void -art_rgb_fill_run (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, gint n); - -void -art_rgb_run_alpha (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, gint alpha, - gint n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libart_lgpl/art_rgb_affine.c b/libart_lgpl/art_rgb_affine.c deleted file mode 100644 index 61cdb1e9a8..0000000000 --- a/libart_lgpl/art_rgb_affine.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_rgb_affine.h" - -#include <math.h> -#include "art_misc.h" -#include "art_point.h" -#include "art_affine.h" -#include "art_rgb_affine_private.h" - -/* This module handles compositing of affine-transformed rgb images - over rgb pixel buffers. */ - -/** - * art_rgb_affine: Affine transform source RGB image and composite. - * @dst: Destination image RGB buffer. - * @x0: Left coordinate of destination rectangle. - * @y0: Top coordinate of destination rectangle. - * @x1: Right coordinate of destination rectangle. - * @y1: Bottom coordinate of destination rectangle. - * @dst_rowstride: Rowstride of @dst buffer. - * @src: Source image RGB buffer. - * @src_width: Width of source image. - * @src_height: Height of source image. - * @src_rowstride: Rowstride of @src buffer. - * @affine: Affine transform. - * @level: Filter level. - * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing. - * - * Affine transform the source image stored in @src, compositing over - * the area of destination image @dst specified by the rectangle - * (@x0, @y0) - (@x1, @y1). As usual in libart, the left and top edges - * of this rectangle are included, and the right and bottom edges are - * excluded. - * - * The @alphagamma parameter specifies that the alpha compositing be done - * in a gamma-corrected color space. Since the source image is opaque RGB, - * this argument only affects the edges. In the current implementation, - * it is ignored. - * - * The @level parameter specifies the speed/quality tradeoff of the - * image interpolation. Currently, only ART_FILTER_NEAREST is - * implemented. - **/ -void -art_rgb_affine (art_u8 *dst, gint x0, gint y0, gint x1, gint y1, gint dst_rowstride, - const art_u8 *src, - gint src_width, gint src_height, gint src_rowstride, - const gdouble affine[6], - ArtFilterLevel level, - ArtAlphaGamma *alphagamma) -{ - /* Note: this is a slow implementation, and is missing all filter - levels other than NEAREST. It is here for clarity of presentation - and to establish the interface. */ - gint x, y; - gdouble inv[6]; - art_u8 *dst_p, *dst_linestart; - const art_u8 *src_p; - ArtPoint pt, src_pt; - gint src_x, src_y; - gint run_x0, run_x1; - - dst_linestart = dst; - art_affine_invert (inv, affine); - for (y = y0; y < y1; y++) - { - pt.y = y + 0.5; - run_x0 = x0; - run_x1 = x1; - art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height, - inv); - dst_p = dst_linestart + (run_x0 - x0) * 3; - for (x = run_x0; x < run_x1; x++) - { - pt.x = x + 0.5; - art_affine_point (&src_pt, &pt, inv); - src_x = floor (src_pt.x); - src_y = floor (src_pt.y); - src_p = src + (src_y * src_rowstride) + src_x * 3; - dst_p[0] = src_p[0]; - dst_p[1] = src_p[1]; - dst_p[2] = src_p[2]; - dst_p += 3; - } - dst_linestart += dst_rowstride; - } -} diff --git a/libart_lgpl/art_rgb_affine.h b/libart_lgpl/art_rgb_affine.h deleted file mode 100644 index 9f1414753a..0000000000 --- a/libart_lgpl/art_rgb_affine.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RGB_AFFINE_H__ -#define __ART_RGB_AFFINE_H__ - -/* This module handles compositing of affine-transformed rgb images - over rgb pixel buffers. */ - -#include <libart_lgpl/art_filterlevel.h> -#include <libart_lgpl/art_alphagamma.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void -art_rgb_affine (art_u8 *dst, gint x0, gint y0, gint x1, gint y1, gint dst_rowstride, - const art_u8 *src, - gint src_width, gint src_height, gint src_rowstride, - const gdouble affine[6], - ArtFilterLevel level, - ArtAlphaGamma *alphagamma); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libart_lgpl/art_rgb_affine_private.c b/libart_lgpl/art_rgb_affine_private.c deleted file mode 100644 index 9f2d12026f..0000000000 --- a/libart_lgpl/art_rgb_affine_private.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_rgb_affine_private.h" - -#include <math.h> -#include "art_misc.h" -#include "art_point.h" -#include "art_affine.h" - -/* Private functions for the rgb affine image compositors - primarily, - the determination of runs, eliminating the need for source image - bbox calculation in the inner loop. */ - -/* Determine a "run", such that the inverse affine of all pixels from - (x0, y) inclusive to (x1, y) exclusive fit within the bounds - of the source image. - - Initial values of x0, x1, and result values stored in first two - pointer arguments. -*/ - -#define EPSILON 1e-6 - -void -art_rgb_affine_run (gint *p_x0, gint *p_x1, gint y, - gint src_width, gint src_height, - const gdouble affine[6]) -{ - gint x0, x1; - gdouble z; - gdouble x_intercept; - gint xi; - - x0 = *p_x0; - x1 = *p_x1; - - /* do left and right edges */ - if (affine[0] > EPSILON) - { - z = affine[2] * (y + 0.5) + affine[4]; - x_intercept = -z / affine[0]; - xi = ceil (x_intercept + EPSILON - 0.5); - if (xi > x0) - x0 = xi; - x_intercept = (-z + src_width) / affine[0]; - xi = ceil (x_intercept - EPSILON - 0.5); - if (xi < x1) - x1 = xi; - } - else if (affine[0] < -EPSILON) - { - z = affine[2] * (y + 0.5) + affine[4]; - x_intercept = (-z + src_width) / affine[0]; - xi = ceil (x_intercept + EPSILON - 0.5); - if (xi > x0) - x0 = xi; - x_intercept = -z / affine[0]; - xi = ceil (x_intercept - EPSILON - 0.5); - if (xi < x1) - x1 = xi; - } - else - { - z = affine[2] * (y + 0.5) + affine[4]; - if (z < 0 || z >= src_width) - { - *p_x1 = *p_x0; - return; - } - } - - /* do top and bottom edges */ - if (affine[1] > EPSILON) - { - z = affine[3] * (y + 0.5) + affine[5]; - x_intercept = -z / affine[1]; - xi = ceil (x_intercept + EPSILON - 0.5); - if (xi > x0) - x0 = xi; - x_intercept = (-z + src_height) / affine[1]; - xi = ceil (x_intercept - EPSILON - 0.5); - if (xi < x1) - x1 = xi; - } - else if (affine[1] < -EPSILON) - { - z = affine[3] * (y + 0.5) + affine[5]; - x_intercept = (-z + src_height) / affine[1]; - xi = ceil (x_intercept + EPSILON - 0.5); - if (xi > x0) - x0 = xi; - x_intercept = -z / affine[1]; - xi = ceil (x_intercept - EPSILON - 0.5); - if (xi < x1) - x1 = xi; - } - else - { - z = affine[3] * (y + 0.5) + affine[5]; - if (z < 0 || z >= src_height) - { - *p_x1 = *p_x0; - return; - } - } - - *p_x0 = x0; - *p_x1 = x1; -} diff --git a/libart_lgpl/art_rgb_affine_private.h b/libart_lgpl/art_rgb_affine_private.h deleted file mode 100644 index a01ad770f1..0000000000 --- a/libart_lgpl/art_rgb_affine_private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RGB_AFFINE_PRIVATE_H__ -#define __ART_RGB_AFFINE_PRIVATE_H__ - -/* This module handles compositing of affine-transformed rgb images - over rgb pixel buffers. */ - -#include <glib.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void -art_rgb_affine_run (gint *p_x0, gint *p_x1, gint y, - gint src_width, gint src_height, - const gdouble affine[6]); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libart_lgpl/art_rgb_rgba_affine.c b/libart_lgpl/art_rgb_rgba_affine.c deleted file mode 100644 index a6da49ed91..0000000000 --- a/libart_lgpl/art_rgb_rgba_affine.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_rgb_rgba_affine.h" - -#include <math.h> -#include "art_misc.h" -#include "art_point.h" -#include "art_affine.h" -#include "art_rgb_affine_private.h" - -/* This module handles compositing of affine-transformed rgba images - over rgb pixel buffers. */ - -/* Composite the source image over the destination image, applying the - affine transform. */ - -/** - * art_rgb_rgba_affine: Affine transform source RGBA image and composite. - * @dst: Destination image RGB buffer. - * @x0: Left coordinate of destination rectangle. - * @y0: Top coordinate of destination rectangle. - * @x1: Right coordinate of destination rectangle. - * @y1: Bottom coordinate of destination rectangle. - * @dst_rowstride: Rowstride of @dst buffer. - * @src: Source image RGBA buffer. - * @src_width: Width of source image. - * @src_height: Height of source image. - * @src_rowstride: Rowstride of @src buffer. - * @affine: Affine transform. - * @level: Filter level. - * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing. - * - * Affine transform the source image stored in @src, compositing over - * the area of destination image @dst specified by the rectangle - * (@x0, @y0) - (@x1, @y1). As usual in libart, the left and top edges - * of this rectangle are included, and the right and bottom edges are - * excluded. - * - * The @alphagamma parameter specifies that the alpha compositing be - * done in a gamma-corrected color space. In the current - * implementation, it is ignored. - * - * The @level parameter specifies the speed/quality tradeoff of the - * image interpolation. Currently, only ART_FILTER_NEAREST is - * implemented. - **/ -void -art_rgb_rgba_affine (art_u8 *dst, - gint x0, gint y0, gint x1, gint y1, gint dst_rowstride, - const art_u8 *src, - gint src_width, gint src_height, gint src_rowstride, - const gdouble affine[6], - ArtFilterLevel level, - ArtAlphaGamma *alphagamma) -{ - /* Note: this is a slow implementation, and is missing all filter - levels other than NEAREST. It is here for clarity of presentation - and to establish the interface. */ - gint x, y; - gdouble inv[6]; - art_u8 *dst_p, *dst_linestart; - const art_u8 *src_p; - ArtPoint pt, src_pt; - gint src_x, src_y; - gint alpha; - art_u8 bg_r, bg_g, bg_b; - art_u8 fg_r, fg_g, fg_b; - gint tmp; - gint run_x0, run_x1; - - dst_linestart = dst; - art_affine_invert (inv, affine); - for (y = y0; y < y1; y++) - { - pt.y = y + 0.5; - run_x0 = x0; - run_x1 = x1; - art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height, - inv); - dst_p = dst_linestart + (run_x0 - x0) * 3; - for (x = run_x0; x < run_x1; x++) - { - pt.x = x + 0.5; - art_affine_point (&src_pt, &pt, inv); - src_x = floor (src_pt.x); - src_y = floor (src_pt.y); - src_p = src + (src_y * src_rowstride) + src_x * 4; - if (src_x >= 0 && src_x < src_width && - src_y >= 0 && src_y < src_height) - { - - alpha = src_p[3]; - if (alpha) - { - if (alpha == 255) - { - dst_p[0] = src_p[0]; - dst_p[1] = src_p[1]; - dst_p[2] = src_p[2]; - } - else - { - bg_r = dst_p[0]; - bg_g = dst_p[1]; - bg_b = dst_p[2]; - - tmp = (src_p[0] - bg_r) * alpha; - fg_r = bg_r + ((tmp + (tmp >> 8) + 0x80) >> 8); - tmp = (src_p[1] - bg_g) * alpha; - fg_g = bg_g + ((tmp + (tmp >> 8) + 0x80) >> 8); - tmp = (src_p[2] - bg_b) * alpha; - fg_b = bg_b + ((tmp + (tmp >> 8) + 0x80) >> 8); - - dst_p[0] = fg_r; - dst_p[1] = fg_g; - dst_p[2] = fg_b; - } - } - } else { dst_p[0] = 255; dst_p[1] = 0; dst_p[2] = 0; } - dst_p += 3; - } - dst_linestart += dst_rowstride; - } -} diff --git a/libart_lgpl/art_rgb_rgba_affine.h b/libart_lgpl/art_rgb_rgba_affine.h deleted file mode 100644 index 154084b670..0000000000 --- a/libart_lgpl/art_rgb_rgba_affine.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RGB_RGBA_AFFINE_H__ -#define __ART_RGB_RGBA_AFFINE_H__ - -/* This module handles compositing of affine-transformed rgba images - over rgb pixel buffers. */ - -#include <libart_lgpl/art_filterlevel.h> -#include <libart_lgpl/art_alphagamma.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void -art_rgb_rgba_affine (art_u8 *dst, - gint x0, gint y0, gint x1, gint y1, gint dst_rowstride, - const art_u8 *src, - gint src_width, gint src_height, gint src_rowstride, - const gdouble affine[6], - ArtFilterLevel level, - ArtAlphaGamma *alphagamma); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libart_lgpl/art_rgb_svp.c b/libart_lgpl/art_rgb_svp.c deleted file mode 100644 index afd57aeed6..0000000000 --- a/libart_lgpl/art_rgb_svp.c +++ /dev/null @@ -1,457 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Render a sorted vector path into an RGB buffer. */ - -#include "config.h" -#include "art_rgb_svp.h" - -#include "art_svp.h" -#include "art_svp_render_aa.h" -#include "art_rgb.h" - -typedef struct _ArtRgbSVPData ArtRgbSVPData; -typedef struct _ArtRgbSVPAlphaData ArtRgbSVPAlphaData; - -struct _ArtRgbSVPData { - art_u32 rgbtab[256]; - art_u8 *buf; - gint rowstride; - gint x0, x1; -}; - -struct _ArtRgbSVPAlphaData { - gint alphatab[256]; - art_u8 r, g, b, alpha; - art_u8 *buf; - gint rowstride; - gint x0, x1; -}; - -static void -art_rgb_svp_callback (gpointer callback_data, gint y, - gint start, ArtSVPRenderAAStep *steps, gint n_steps) -{ - ArtRgbSVPData *data = (ArtRgbSVPData *)callback_data; - art_u8 *linebuf; - gint run_x0, run_x1; - art_u32 running_sum = start; - art_u32 rgb; - gint x0, x1; - gint k; - - linebuf = data->buf; - x0 = data->x0; - x1 = data->x1; - - if (n_steps > 0) - { - run_x1 = steps[0].x; - if (run_x1 > x0) - { - rgb = data->rgbtab[(running_sum >> 16) & 0xff]; - art_rgb_fill_run (linebuf, - rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff, - run_x1 - x0); - } - - for (k = 0; k < n_steps - 1; k++) - { - running_sum += steps[k].delta; - run_x0 = run_x1; - run_x1 = steps[k + 1].x; - if (run_x1 > run_x0) - { - rgb = data->rgbtab[(running_sum >> 16) & 0xff]; - art_rgb_fill_run (linebuf + (run_x0 - x0) * 3, - rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff, - run_x1 - run_x0); - } - } - running_sum += steps[k].delta; - if (x1 > run_x1) - { - rgb = data->rgbtab[(running_sum >> 16) & 0xff]; - art_rgb_fill_run (linebuf + (run_x1 - x0) * 3, - rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff, - x1 - run_x1); - } - } - else - { - rgb = data->rgbtab[(running_sum >> 16) & 0xff]; - art_rgb_fill_run (linebuf, - rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff, - x1 - x0); - } - - data->buf += data->rowstride; -} - -/* Render the vector path into the RGB buffer. */ - -/** - * art_rgb_svp_aa: Render sorted vector path into RGB buffer. - * @svp: The source sorted vector path. - * @x0: Left coordinate of destination rectangle. - * @y0: Top coordinate of destination rectangle. - * @x1: Right coordinate of destination rectangle. - * @y1: Bottom coordinate of destination rectangle. - * @fg_color: Foreground color in 0xRRGGBB format. - * @bg_color: Background color in 0xRRGGBB format. - * @buf: Destination RGB buffer. - * @rowstride: Rowstride of @buf buffer. - * @alphagamma: #ArtAlphaGamma for gamma-correcting the rendering. - * - * Renders the shape specified with @svp into the @buf RGB buffer. - * @x1 - @x0 specifies the width, and @y1 - @y0 specifies the height, - * of the rectangle rendered. The new pixels are stored starting at - * the first byte of @buf. Thus, the @x0 and @y0 parameters specify - * an offset within @svp, and may be tweaked as a way of doing - * integer-pixel translations without fiddling with @svp itself. - * - * The @fg_color and @bg_color arguments specify the opaque colors to - * be used for rendering. For pixels of entirely 0 winding-number, - * @bg_color is used. For pixels of entirely 1 winding number, - * @fg_color is used. In between, the color is interpolated based on - * the fraction of the pixel with a winding number of 1. If - * @alphagamma is NULL, then linear interpolation (in pixel counts) is - * the default. Otherwise, the interpolation is as specified by - * @alphagamma. - **/ -void -art_rgb_svp_aa (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - art_u32 fg_color, art_u32 bg_color, - art_u8 *buf, gint rowstride, - ArtAlphaGamma *alphagamma) -{ - ArtRgbSVPData data; - - gint r_fg, g_fg, b_fg; - gint r_bg, g_bg, b_bg; - gint r, g, b; - gint dr, dg, db; - gint i; - - if (alphagamma == NULL) - { - r_fg = fg_color >> 16; - g_fg = (fg_color >> 8) & 0xff; - b_fg = fg_color & 0xff; - - r_bg = bg_color >> 16; - g_bg = (bg_color >> 8) & 0xff; - b_bg = bg_color & 0xff; - - r = (r_bg << 16) + 0x8000; - g = (g_bg << 16) + 0x8000; - b = (b_bg << 16) + 0x8000; - dr = ((r_fg - r_bg) << 16) / 255; - dg = ((g_fg - g_bg) << 16) / 255; - db = ((b_fg - b_bg) << 16) / 255; - - for (i = 0; i < 256; i++) - { - data.rgbtab[i] = (r & 0xff0000) | ((g & 0xff0000) >> 8) | (b >> 16); - r += dr; - g += dg; - b += db; - } - } - else - { - gint *table; - art_u8 *invtab; - - table = alphagamma->table; - - r_fg = table[fg_color >> 16]; - g_fg = table[(fg_color >> 8) & 0xff]; - b_fg = table[fg_color & 0xff]; - - r_bg = table[bg_color >> 16]; - g_bg = table[(bg_color >> 8) & 0xff]; - b_bg = table[bg_color & 0xff]; - - r = (r_bg << 16) + 0x8000; - g = (g_bg << 16) + 0x8000; - b = (b_bg << 16) + 0x8000; - dr = ((r_fg - r_bg) << 16) / 255; - dg = ((g_fg - g_bg) << 16) / 255; - db = ((b_fg - b_bg) << 16) / 255; - - invtab = alphagamma->invtable; - for (i = 0; i < 256; i++) - { - data.rgbtab[i] = (invtab[r >> 16] << 16) | - (invtab[g >> 16] << 8) | - invtab[b >> 16]; - r += dr; - g += dg; - b += db; - } - } - data.buf = buf; - data.rowstride = rowstride; - data.x0 = x0; - data.x1 = x1; - art_svp_render_aa (svp, x0, y0, x1, y1, art_rgb_svp_callback, &data); -} - -static void -art_rgb_svp_alpha_callback (gpointer callback_data, gint y, - gint start, ArtSVPRenderAAStep *steps, gint n_steps) -{ - ArtRgbSVPAlphaData *data = (ArtRgbSVPAlphaData *)callback_data; - art_u8 *linebuf; - gint run_x0, run_x1; - art_u32 running_sum = start; - gint x0, x1; - gint k; - art_u8 r, g, b; - gint *alphatab; - gint alpha; - - linebuf = data->buf; - x0 = data->x0; - x1 = data->x1; - - r = data->r; - g = data->g; - b = data->b; - alphatab = data->alphatab; - - if (n_steps > 0) - { - run_x1 = steps[0].x; - if (run_x1 > x0) - { - alpha = (running_sum >> 16) & 0xff; - if (alpha) - art_rgb_run_alpha (linebuf, - r, g, b, alphatab[alpha], - run_x1 - x0); - } - - for (k = 0; k < n_steps - 1; k++) - { - running_sum += steps[k].delta; - run_x0 = run_x1; - run_x1 = steps[k + 1].x; - if (run_x1 > run_x0) - { - alpha = (running_sum >> 16) & 0xff; - if (alpha) - art_rgb_run_alpha (linebuf + (run_x0 - x0) * 3, - r, g, b, alphatab[alpha], - run_x1 - run_x0); - } - } - running_sum += steps[k].delta; - if (x1 > run_x1) - { - alpha = (running_sum >> 16) & 0xff; - if (alpha) - art_rgb_run_alpha (linebuf + (run_x1 - x0) * 3, - r, g, b, alphatab[alpha], - x1 - run_x1); - } - } - else - { - alpha = (running_sum >> 16) & 0xff; - if (alpha) - art_rgb_run_alpha (linebuf, - r, g, b, alphatab[alpha], - x1 - x0); - } - - data->buf += data->rowstride; -} - -static void -art_rgb_svp_alpha_opaque_callback (gpointer callback_data, gint y, - gint start, - ArtSVPRenderAAStep *steps, gint n_steps) -{ - ArtRgbSVPAlphaData *data = (ArtRgbSVPAlphaData *)callback_data; - art_u8 *linebuf; - gint run_x0, run_x1; - art_u32 running_sum = start; - gint x0, x1; - gint k; - art_u8 r, g, b; - gint *alphatab; - gint alpha; - - linebuf = data->buf; - x0 = data->x0; - x1 = data->x1; - - r = data->r; - g = data->g; - b = data->b; - alphatab = data->alphatab; - - if (n_steps > 0) - { - run_x1 = steps[0].x; - if (run_x1 > x0) - { - alpha = running_sum >> 16; - if (alpha) - { - if (alpha >= 255) - art_rgb_fill_run (linebuf, - r, g, b, - run_x1 - x0); - else - art_rgb_run_alpha (linebuf, - r, g, b, alphatab[alpha], - run_x1 - x0); - } - } - - for (k = 0; k < n_steps - 1; k++) - { - running_sum += steps[k].delta; - run_x0 = run_x1; - run_x1 = steps[k + 1].x; - if (run_x1 > run_x0) - { - alpha = running_sum >> 16; - if (alpha) - { - if (alpha >= 255) - art_rgb_fill_run (linebuf + (run_x0 - x0) * 3, - r, g, b, - run_x1 - run_x0); - else - art_rgb_run_alpha (linebuf + (run_x0 - x0) * 3, - r, g, b, alphatab[alpha], - run_x1 - run_x0); - } - } - } - running_sum += steps[k].delta; - if (x1 > run_x1) - { - alpha = running_sum >> 16; - if (alpha) - { - if (alpha >= 255) - art_rgb_fill_run (linebuf + (run_x1 - x0) * 3, - r, g, b, - x1 - run_x1); - else - art_rgb_run_alpha (linebuf + (run_x1 - x0) * 3, - r, g, b, alphatab[alpha], - x1 - run_x1); - } - } - } - else - { - alpha = running_sum >> 16; - if (alpha) - { - if (alpha >= 255) - art_rgb_fill_run (linebuf, - r, g, b, - x1 - x0); - else - art_rgb_run_alpha (linebuf, - r, g, b, alphatab[alpha], - x1 - x0); - } - } - - data->buf += data->rowstride; -} - -/** - * art_rgb_svp_alpha: Alpha-composite sorted vector path over RGB buffer. - * @svp: The source sorted vector path. - * @x0: Left coordinate of destination rectangle. - * @y0: Top coordinate of destination rectangle. - * @x1: Right coordinate of destination rectangle. - * @y1: Bottom coordinate of destination rectangle. - * @rgba: Color in 0xRRGGBBAA format. - * @buf: Destination RGB buffer. - * @rowstride: Rowstride of @buf buffer. - * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing. - * - * Renders the shape specified with @svp over the @buf RGB buffer. - * @x1 - @x0 specifies the width, and @y1 - @y0 specifies the height, - * of the rectangle rendered. The new pixels are stored starting at - * the first byte of @buf. Thus, the @x0 and @y0 parameters specify - * an offset within @svp, and may be tweaked as a way of doing - * integer-pixel translations without fiddling with @svp itself. - * - * The @rgba argument specifies the color for the rendering. Pixels of - * entirely 0 winding number are left untouched. Pixels of entirely - * 1 winding number have the color @rgba composited over them (ie, - * are replaced by the red, green, blue components of @rgba if the alpha - * component is 0xff). Pixels of intermediate coverage are interpolated - * according to the rule in @alphagamma, or default to linear if - * @alphagamma is NULL. - **/ -void -art_rgb_svp_alpha (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - art_u32 rgba, - art_u8 *buf, gint rowstride, - ArtAlphaGamma *alphagamma) -{ - ArtRgbSVPAlphaData data; - gint r, g, b, alpha; - gint i; - gint a, da; - - r = rgba >> 24; - g = (rgba >> 16) & 0xff; - b = (rgba >> 8) & 0xff; - alpha = rgba & 0xff; - - data.r = r; - data.g = g; - data.b = b; - data.alpha = alpha; - - a = 0x8000; - da = (alpha * 66051 + 0x80) >> 8; /* 66051 equals 2 ^ 32 / (255 * 255) */ - - for (i = 0; i < 256; i++) - { - data.alphatab[i] = a >> 16; - a += da; - } - - data.buf = buf; - data.rowstride = rowstride; - data.x0 = x0; - data.x1 = x1; - if (alpha == 255) - art_svp_render_aa (svp, x0, y0, x1, y1, art_rgb_svp_alpha_opaque_callback, - &data); - else - art_svp_render_aa (svp, x0, y0, x1, y1, art_rgb_svp_alpha_callback, &data); -} - diff --git a/libart_lgpl/art_rgb_svp.h b/libart_lgpl/art_rgb_svp.h deleted file mode 100644 index 5d68616255..0000000000 --- a/libart_lgpl/art_rgb_svp.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_RGB_SVP_H__ -#define __ART_RGB_SVP_H__ - -/* Render a sorted vector path into an RGB buffer. */ - -#include <libart_lgpl/art_alphagamma.h> -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -void -art_rgb_svp_aa (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - art_u32 fg_color, art_u32 bg_color, - art_u8 *buf, gint rowstride, - ArtAlphaGamma *alphagamma); - -void -art_rgb_svp_alpha (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - art_u32 rgba, - art_u8 *buf, gint rowstride, - ArtAlphaGamma *alphagamma); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_RGB_SVP_H__ */ diff --git a/libart_lgpl/art_svp.c b/libart_lgpl/art_svp.c deleted file mode 100644 index 69814cca00..0000000000 --- a/libart_lgpl/art_svp.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Basic constructors and operations for sorted vector paths */ - -#include "config.h" -#include "art_svp.h" - -#include "art_misc.h" - -/** - * art_svp_free: Free an #ArtSVP structure. - * @svp: #ArtSVP to free. - * - * Frees an #ArtSVP structure and all the segments in it. - **/ -void -art_svp_free (ArtSVP *svp) -{ - gint n_segs = svp->n_segs; - gint i; - - for (i = 0; i < n_segs; i++) - art_free (svp->segs[i].points); - art_free (svp); -} - -#ifdef ART_USE_NEW_INTERSECTOR -#define EPSILON 0 -#else -#define EPSILON 1e-6 -#endif - -/** - * art_svp_seg_compare: Compare two segments of an svp. - * @seg1: First segment to compare. - * @seg2: Second segment to compare. - * - * Compares two segments of an svp. Return 1 if @seg2 is below or to the - * right of @seg1, -1 otherwise. - **/ -gint -art_svp_seg_compare (gconstpointer s1, gconstpointer s2) -{ - const ArtSVPSeg *seg1 = s1; - const ArtSVPSeg *seg2 = s2; - - if (seg1->points[0].y - EPSILON > seg2->points[0].y) return 1; - else if (seg1->points[0].y + EPSILON < seg2->points[0].y) return -1; - else if (seg1->points[0].x - EPSILON > seg2->points[0].x) return 1; - else if (seg1->points[0].x + EPSILON < seg2->points[0].x) return -1; - else if ((seg1->points[1].x - seg1->points[0].x) * - (seg2->points[1].y - seg2->points[0].y) - - (seg1->points[1].y - seg1->points[0].y) * - (seg2->points[1].x - seg2->points[0].x) > 0) return 1; - else return -1; -} - diff --git a/libart_lgpl/art_svp.h b/libart_lgpl/art_svp.h deleted file mode 100644 index f1627c70ef..0000000000 --- a/libart_lgpl/art_svp.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_H__ -#define __ART_SVP_H__ - -/* Basic data structures and constructors for sorted vector paths */ - -#include <libart_lgpl/art_rect.h> -#include <libart_lgpl/art_point.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct _ArtSVP ArtSVP; -typedef struct _ArtSVPSeg ArtSVPSeg; - -struct _ArtSVPSeg { - gint n_points; - gint dir; /* == 0 for "up", 1 for "down" */ - ArtDRect bbox; - ArtPoint *points; -}; - -struct _ArtSVP { - gint n_segs; - ArtSVPSeg segs[1]; -}; - -void -art_svp_free (ArtSVP *svp); - -gint -art_svp_seg_compare (gconstpointer s1, gconstpointer s2); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_H__ */ diff --git a/libart_lgpl/art_svp_intersect.c b/libart_lgpl/art_svp_intersect.c deleted file mode 100644 index 1074d084d7..0000000000 --- a/libart_lgpl/art_svp_intersect.c +++ /dev/null @@ -1,1675 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 2001 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* This file contains a testbed implementation of the new intersection - code. -*/ - -#include "config.h" -#include "art_svp_intersect.h" - -#include <math.h> /* for sqrt */ - -/* Sanitychecking verifies the main invariant on every priority queue - point. Do not use in production, as it slows things down way too - much. */ -#define noSANITYCHECK - -/* This can be used in production, to prevent hangs. Eventually, it - should not be necessary. */ -#define CHEAP_SANITYCHECK - -#include "art_misc.h" - -/* A priority queue - perhaps move to a separate file if it becomes - needed somewhere else */ - -#define ART_PRIQ_USE_HEAP - -typedef struct _ArtPriQ ArtPriQ; -typedef struct _ArtPriPoint ArtPriPoint; - -struct _ArtPriQ { - gint n_items; - gint n_items_max; - ArtPriPoint **items; -}; - -struct _ArtPriPoint { - gdouble x; - gdouble y; - gpointer user_data; -}; - -static ArtPriQ * -art_pri_new (void) -{ - ArtPriQ *result = art_new (ArtPriQ, 1); - - result->n_items = 0; - result->n_items_max = 16; - result->items = art_new (ArtPriPoint *, result->n_items_max); - return result; -} - -static void -art_pri_free (ArtPriQ *pq) -{ - art_free (pq->items); - art_free (pq); -} - -static art_boolean -art_pri_empty (ArtPriQ *pq) -{ - return pq->n_items == 0; -} - -#ifdef ART_PRIQ_USE_HEAP - -/* This heap implementation is based on Vasek Chvatal's course notes: - http://www.cs.rutgers.edu/~chvatal/notes/pq.html#heap */ - -static void -art_pri_bubble_up (ArtPriQ *pq, gint vacant, ArtPriPoint *missing) -{ - ArtPriPoint **items = pq->items; - gint parent; - - parent = (vacant - 1) >> 1; - while (vacant > 0 && (missing->y < items[parent]->y || - (missing->y == items[parent]->y && - missing->x < items[parent]->x))) - { - items[vacant] = items[parent]; - vacant = parent; - parent = (vacant - 1) >> 1; - } - - items[vacant] = missing; -} - -static void -art_pri_insert (ArtPriQ *pq, ArtPriPoint *point) -{ - if (pq->n_items == pq->n_items_max) - art_expand (pq->items, ArtPriPoint *, pq->n_items_max); - - art_pri_bubble_up (pq, pq->n_items++, point); -} - -static void -art_pri_sift_down_from_root (ArtPriQ *pq, ArtPriPoint *missing) -{ - ArtPriPoint **items = pq->items; - gint vacant = 0, child = 2; - gint n = pq->n_items; - - while (child < n) - { - if (items[child - 1]->y < items[child]->y || - (items[child - 1]->y == items[child]->y && - items[child - 1]->x < items[child]->x)) - child--; - items[vacant] = items[child]; - vacant = child; - child = (vacant + 1) << 1; - } - if (child == n) - { - items[vacant] = items[n - 1]; - vacant = n - 1; - } - - art_pri_bubble_up (pq, vacant, missing); -} - -static ArtPriPoint * -art_pri_choose (ArtPriQ *pq) -{ - ArtPriPoint *result = pq->items[0]; - - art_pri_sift_down_from_root (pq, pq->items[--pq->n_items]); - return result; -} - -#else - -/* Choose least point in queue */ -static ArtPriPoint * -art_pri_choose (ArtPriQ *pq) -{ - gint i; - gint best = 0; - gdouble best_x, best_y; - gdouble y; - ArtPriPoint *result; - - if (pq->n_items == 0) - return NULL; - - best_x = pq->items[best]->x; - best_y = pq->items[best]->y; - - for (i = 1; i < pq->n_items; i++) - { - y = pq->items[i]->y; - if (y < best_y || (y == best_y && pq->items[i]->x < best_x)) - { - best = i; - best_x = pq->items[best]->x; - best_y = y; - } - } - result = pq->items[best]; - pq->items[best] = pq->items[--pq->n_items]; - return result; -} - -static void -art_pri_insert (ArtPriQ *pq, ArtPriPoint *point) -{ - if (pq->n_items == pq->n_items_max) - art_expand (pq->items, ArtPriPoint *, pq->n_items_max); - - pq->items[pq->n_items++] = point; -} - -#endif - -#ifdef TEST_PRIQ - -#include <stdlib.h> /* for rand() */ -#include <stdio.h> - -static double -double_rand (gdouble lo, gdouble hi, gint quant) -{ - gint tmp = rand () / (RAND_MAX * (1.0 / quant)) + 0.5; - return lo + tmp * ((hi - lo) / quant); -} - -/* - * This custom allocator for priority queue points is here so I can - * test speed. It doesn't look like it will be that significant, but - * if I want a small improvement later, it's something. - */ - -typedef ArtPriPoint *ArtPriPtPool; - -static ArtPriPtPool * -art_pri_pt_pool_new (void) -{ - ArtPriPtPool *result = art_new (ArtPriPtPool, 1); - *result = NULL; - return result; -} - -static ArtPriPoint * -art_pri_pt_alloc (ArtPriPtPool *pool) -{ - ArtPriPoint *result = *pool; - if (result == NULL) - return art_new (ArtPriPoint, 1); - else - { - *pool = result->user_data; - return result; - } -} - -static void -art_pri_pt_free (ArtPriPtPool *pool, ArtPriPoint *pt) -{ - pt->user_data = *pool; - *pool = pt; -} - -static void -art_pri_pt_pool_free (ArtPriPtPool *pool) -{ - ArtPriPoint *pt = *pool; - while (pt != NULL) - { - ArtPriPoint *next = pt->user_data; - art_free (pt); - pt = next; - } - art_free (pool); -} - -gint -main (gint argc, gchar **argv) -{ - ArtPriPtPool *pool = art_pri_pt_pool_new (); - ArtPriQ *pq; - gint i, j; - const gint n_iter = 1; - const gint pq_size = 100; - - for (j = 0; j < n_iter; j++) - { - pq = art_pri_new (); - - for (i = 0; i < pq_size; i++) - { - ArtPriPoint *pt = art_pri_pt_alloc (pool); - pt->x = double_rand (0, 1, 100); - pt->y = double_rand (0, 1, 100); - pt->user_data = (gpointer)i; - art_pri_insert (pq, pt); - } - - while (!art_pri_empty (pq)) - { - ArtPriPoint *pt = art_pri_choose (pq); - if (n_iter == 1) - printf ("(%g, %g), %d\n", pt->x, pt->y, (gint)pt->user_data); - art_pri_pt_free (pool, pt); - } - - art_pri_free (pq); - } - art_pri_pt_pool_free (pool); - return 0; -} - -#else /* TEST_PRIQ */ - -/* A virtual class for an "svp writer". A client of this object creates an - SVP by repeatedly calling "add segment" and "add point" methods on it. -*/ - -typedef struct _ArtSvpWriterRewind ArtSvpWriterRewind; - -/* An implementation of the svp writer virtual class that applies the - winding rule. */ - -struct _ArtSvpWriterRewind { - ArtSvpWriter super; - ArtWindRule rule; - ArtSVP *svp; - gint n_segs_max; - gint *n_points_max; -}; - -static gint -art_svp_writer_rewind_add_segment (ArtSvpWriter *self, gint wind_left, - gint delta_wind, gdouble x, gdouble y) -{ - ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self; - ArtSVP *svp; - ArtSVPSeg *seg; - art_boolean left_filled, right_filled; - gint wind_right = wind_left + delta_wind; - gint seg_num; - const gint init_n_points_max = 4; - - switch (swr->rule) - { - case ART_WIND_RULE_NONZERO: - left_filled = (wind_left != 0); - right_filled = (wind_right != 0); - break; - case ART_WIND_RULE_INTERSECT: - left_filled = (wind_left > 1); - right_filled = (wind_right > 1); - break; - case ART_WIND_RULE_ODDEVEN: - left_filled = (wind_left & 1); - right_filled = (wind_right & 1); - break; - case ART_WIND_RULE_POSITIVE: - left_filled = (wind_left > 0); - right_filled = (wind_right > 0); - break; - default: - art_die ("Unknown wind rule %d\n", swr->rule); - } - if (left_filled == right_filled) - { - /* discard segment now */ - return -1; - } - - svp = swr->svp; - seg_num = svp->n_segs++; - if (swr->n_segs_max == seg_num) - { - swr->n_segs_max <<= 1; - svp = (ArtSVP *)art_realloc (svp, sizeof (ArtSVP) + - (swr->n_segs_max - 1) * - sizeof (ArtSVPSeg)); - swr->svp = svp; - swr->n_points_max = art_renew (swr->n_points_max, int, - swr->n_segs_max); - } - seg = &svp->segs[seg_num]; - seg->n_points = 1; - seg->dir = right_filled; - swr->n_points_max[seg_num] = init_n_points_max; - seg->bbox.x0 = x; - seg->bbox.y0 = y; - seg->bbox.x1 = x; - seg->bbox.y1 = y; - seg->points = art_new (ArtPoint, init_n_points_max); - seg->points[0].x = x; - seg->points[0].y = y; - return seg_num; -} - -static void -art_svp_writer_rewind_add_point (ArtSvpWriter *self, gint seg_id, - gdouble x, gdouble y) -{ - ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self; - ArtSVPSeg *seg; - gint n_points; - - if (seg_id < 0) - /* omitted segment */ - return; - - seg = &swr->svp->segs[seg_id]; - n_points = seg->n_points++; - if (swr->n_points_max[seg_id] == n_points) - art_expand (seg->points, ArtPoint, swr->n_points_max[seg_id]); - seg->points[n_points].x = x; - seg->points[n_points].y = y; - if (x < seg->bbox.x0) - seg->bbox.x0 = x; - if (x > seg->bbox.x1) - seg->bbox.x1 = x; - seg->bbox.y1 = y; -} - -static void -art_svp_writer_rewind_close_segment (ArtSvpWriter *self, gint seg_id) -{ - /* Not needed for this simple implementation. A potential future - optimization is to merge segments that can be merged safely. */ -#ifdef SANITYCHECK - ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self; - ArtSVPSeg *seg; - - if (seg_id >= 0) - { - seg = &swr->svp->segs[seg_id]; - if (seg->n_points < 2) - art_warn ("*** closing segment %d with only %d point%s\n", - seg_id, seg->n_points, seg->n_points == 1 ? "" : "s"); - } -#endif - -} - -ArtSVP * -art_svp_writer_rewind_reap (ArtSvpWriter *self) -{ - ArtSvpWriterRewind *swr = (ArtSvpWriterRewind *)self; - ArtSVP *result = swr->svp; - - art_free (swr->n_points_max); - art_free (swr); - return result; -} - -ArtSvpWriter * -art_svp_writer_rewind_new (ArtWindRule rule) -{ - ArtSvpWriterRewind *result = art_new (ArtSvpWriterRewind, 1); - - result->super.add_segment = art_svp_writer_rewind_add_segment; - result->super.add_point = art_svp_writer_rewind_add_point; - result->super.close_segment = art_svp_writer_rewind_close_segment; - - result->rule = rule; - result->n_segs_max = 16; - result->svp = art_alloc (sizeof (ArtSVP) + - (result->n_segs_max - 1) * sizeof (ArtSVPSeg)); - result->svp->n_segs = 0; - result->n_points_max = art_new (int, result->n_segs_max); - - return &result->super; -} - -/* Now, data structures for the active list */ - -typedef struct _ArtActiveSeg ArtActiveSeg; - -/* Note: BNEG is 1 for \ lines, and 0 for /. Thus, - x[(flags & BNEG) ^ 1] <= x[flags & BNEG] */ -#define ART_ACTIVE_FLAGS_BNEG 1 - -/* This flag is set if the segment has been inserted into the active - list. */ -#define ART_ACTIVE_FLAGS_IN_ACTIVE 2 - -/* This flag is set when the segment is to be deleted in the - horiz commit process. */ -#define ART_ACTIVE_FLAGS_DEL 4 - -/* This flag is set if the seg_id is a valid output segment. */ -#define ART_ACTIVE_FLAGS_OUT 8 - -/* This flag is set if the segment is in the horiz list. */ -#define ART_ACTIVE_FLAGS_IN_HORIZ 16 - -struct _ArtActiveSeg { - gint flags; - gint wind_left, delta_wind; - ArtActiveSeg *left, *right; /* doubly linked list structure */ - - const ArtSVPSeg *in_seg; - gint in_curs; - - gdouble x[2]; - gdouble y0, y1; - gdouble a, b, c; /* line equation; ax+by+c = 0 for the line, a^2 + b^2 = 1, - and a>0 */ - - /* bottom point and intersection point stack */ - gint n_stack; - gint n_stack_max; - ArtPoint *stack; - - /* horiz commit list */ - ArtActiveSeg *horiz_left, *horiz_right; - gdouble horiz_x; - gint horiz_delta_wind; - gint seg_id; -}; - -typedef struct _ArtIntersectCtx ArtIntersectCtx; - -struct _ArtIntersectCtx { - const ArtSVP *in; - ArtSvpWriter *out; - - ArtPriQ *pq; - - ArtActiveSeg *active_head; - - gdouble y; - ArtActiveSeg *horiz_first; - ArtActiveSeg *horiz_last; - - /* segment index of next input segment to be added to pri q */ - gint in_curs; -}; - -#define EPSILON_A 1e-5 /* Threshold for breaking lines at point insertions */ - -/** - * art_svp_intersect_setup_seg: Set up an active segment from input segment. - * @seg: Active segment. - * @pri_pt: Priority queue point to initialize. - * - * Sets the x[], a, b, c, flags, and stack fields according to the - * line from the current cursor value. Sets the priority queue point - * to the bottom point of this line. Also advances the input segment - * cursor. - **/ -static void -art_svp_intersect_setup_seg (ArtActiveSeg *seg, ArtPriPoint *pri_pt) -{ - const ArtSVPSeg *in_seg = seg->in_seg; - gint in_curs = seg->in_curs++; - gdouble x0, y0, x1, y1; - gdouble dx, dy, s; - gdouble a, b, r2; - - x0 = in_seg->points[in_curs].x; - y0 = in_seg->points[in_curs].y; - x1 = in_seg->points[in_curs + 1].x; - y1 = in_seg->points[in_curs + 1].y; - pri_pt->x = x1; - pri_pt->y = y1; - dx = x1 - x0; - dy = y1 - y0; - r2 = dx * dx + dy * dy; - s = r2 == 0 ? 1 : 1 / sqrt (r2); - seg->a = a = dy * s; - seg->b = b = -dx * s; - seg->c = -(a * x0 + b * y0); - seg->flags = (seg->flags & ~ART_ACTIVE_FLAGS_BNEG) | (dx > 0); - seg->x[0] = x0; - seg->x[1] = x1; - seg->y0 = y0; - seg->y1 = y1; - seg->n_stack = 1; - seg->stack[0].x = x1; - seg->stack[0].y = y1; -} - -/** - * art_svp_intersect_add_horiz: Add point to horizontal list. - * @ctx: Intersector context. - * @seg: Segment with point to insert into horizontal list. - * - * Inserts @seg into horizontal list, keeping it in ascending horiz_x - * order. - * - * Note: the horiz_commit routine processes "clusters" of segs in the - * horiz list, all sharing the same horiz_x value. The cluster is - * processed in active list order, rather than horiz list order. Thus, - * the order of segs in the horiz list sharing the same horiz_x - * _should_ be irrelevant. Even so, we use b as a secondary sorting key, - * as a "belt and suspenders" defensive coding tactic. - **/ -static void -art_svp_intersect_add_horiz (ArtIntersectCtx *ctx, ArtActiveSeg *seg) -{ - ArtActiveSeg **pp = &ctx->horiz_last; - ArtActiveSeg *place; - ArtActiveSeg *place_right = NULL; - -#ifdef CHEAP_SANITYCHECK - if (seg->flags & ART_ACTIVE_FLAGS_IN_HORIZ) - { - art_warn ("*** attempt to put segment in horiz list twice\n"); - return; - } - seg->flags |= ART_ACTIVE_FLAGS_IN_HORIZ; -#endif - - for (place = *pp; place != NULL && (place->horiz_x > seg->horiz_x || - (place->horiz_x == seg->horiz_x && - place->b < seg->b)); - place = *pp) - { - place_right = place; - pp = &place->horiz_left; - } - *pp = seg; - seg->horiz_left = place; - seg->horiz_right = place_right; - if (place == NULL) - ctx->horiz_first = seg; - else - place->horiz_right = seg; -} - -static void -art_svp_intersect_push_pt (ArtIntersectCtx *ctx, ArtActiveSeg *seg, - gdouble x, gdouble y) -{ - ArtPriPoint *pri_pt; - gint n_stack = seg->n_stack; - - if (n_stack == seg->n_stack_max) - art_expand (seg->stack, ArtPoint, seg->n_stack_max); - seg->stack[n_stack].x = x; - seg->stack[n_stack].y = y; - seg->n_stack++; - - seg->x[1] = x; - seg->y1 = y; - - pri_pt = art_new (ArtPriPoint, 1); - pri_pt->x = x; - pri_pt->y = y; - pri_pt->user_data = seg; - art_pri_insert (ctx->pq, pri_pt); -} - -typedef enum { - ART_BREAK_LEFT = 1, - ART_BREAK_RIGHT = 2 -} ArtBreakFlags; - -/** - * art_svp_intersect_break: Break an active segment. - * - * Note: y must be greater than the top point's y, and less than - * the bottom's. - * - * Return value: x coordinate of break point. - */ -static double -art_svp_intersect_break (ArtIntersectCtx *ctx, ArtActiveSeg *seg, - gdouble x_ref, gdouble y, ArtBreakFlags break_flags) -{ - gdouble x0, y0, x1, y1; - const ArtSVPSeg *in_seg = seg->in_seg; - gint in_curs = seg->in_curs; - gdouble x; - - x0 = in_seg->points[in_curs - 1].x; - y0 = in_seg->points[in_curs - 1].y; - x1 = in_seg->points[in_curs].x; - y1 = in_seg->points[in_curs].y; - x = x0 + (x1 - x0) * ((y - y0) / (y1 - y0)); - if ((break_flags == ART_BREAK_LEFT && x > x_ref) || - (break_flags == ART_BREAK_RIGHT && x < x_ref)) - { - } - - /* I think we can count on min(x0, x1) <= x <= max(x0, x1) with sane - arithmetic, but it might be worthwhile to check just in case. */ - - if (y > ctx->y) - art_svp_intersect_push_pt (ctx, seg, x, y); - else - { - seg->x[0] = x; - seg->y0 = y; - seg->horiz_x = x; - art_svp_intersect_add_horiz (ctx, seg); - } - - return x; -} - -/** - * art_svp_intersect_add_point: Add a point, breaking nearby neighbors. - * @ctx: Intersector context. - * @x: X coordinate of point to add. - * @y: Y coordinate of point to add. - * @seg: "nearby" segment, or NULL if leftmost. - * - * Return value: Segment immediately to the left of the new point, or - * NULL if the new point is leftmost. - **/ -static ArtActiveSeg * -art_svp_intersect_add_point (ArtIntersectCtx *ctx, gdouble x, gdouble y, - ArtActiveSeg *seg, ArtBreakFlags break_flags) -{ - ArtActiveSeg *left, *right; - gdouble x_min = x, x_max = x; - art_boolean left_live, right_live; - gdouble d; - gdouble new_x; - ArtActiveSeg *test, *result = NULL; - gdouble x_test; - - left = seg; - if (left == NULL) - right = ctx->active_head; - else - right = left->right; - left_live = (break_flags & ART_BREAK_LEFT) && (left != NULL); - right_live = (break_flags & ART_BREAK_RIGHT) && (right != NULL); - while (left_live || right_live) - { - if (left_live) - { - if (x <= left->x[left->flags & ART_ACTIVE_FLAGS_BNEG] && - /* It may be that one of these conjuncts turns out to be always - true. We test both anyway, to be defensive. */ - y != left->y0 && y < left->y1) - { - d = x_min * left->a + y * left->b + left->c; - if (d < EPSILON_A) - { - new_x = art_svp_intersect_break (ctx, left, x_min, y, - ART_BREAK_LEFT); - if (new_x > x_max) - { - x_max = new_x; - right_live = (right != NULL); - } - else if (new_x < x_min) - x_min = new_x; - left = left->left; - left_live = (left != NULL); - } - else - left_live = ART_FALSE; - } - else - left_live = ART_FALSE; - } - else if (right_live) - { - if (x >= right->x[(right->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1] && - /* It may be that one of these conjuncts turns out to be always - true. We test both anyway, to be defensive. */ - y != right->y0 && y < right->y1) - { - d = x_max * right->a + y * right->b + right->c; - if (d > -EPSILON_A) - { - new_x = art_svp_intersect_break (ctx, right, x_max, y, - ART_BREAK_RIGHT); - if (new_x < x_min) - { - x_min = new_x; - left_live = (left != NULL); - } - else if (new_x >= x_max) - x_max = new_x; - right = right->right; - right_live = (right != NULL); - } - else - right_live = ART_FALSE; - } - else - right_live = ART_FALSE; - } - } - - /* Ascending order is guaranteed by break_flags. Thus, we don't need - to actually fix up non-ascending pairs. */ - - /* Now, (left, right) defines an interval of segments broken. Sort - into ascending x order. */ - test = left == NULL ? ctx->active_head : left->right; - result = left; - if (test != NULL && test != right) - { - if (y == test->y0) - x_test = test->x[0]; - else /* assert y == test->y1, I think */ - x_test = test->x[1]; - for (;;) - { - if (x_test <= x) - result = test; - test = test->right; - if (test == right) - break; - new_x = x_test; - if (new_x < x_test) - { - art_warn ("art_svp_intersect_add_point: non-ascending x\n"); - } - x_test = new_x; - } - } - return result; -} - -static void -art_svp_intersect_swap_active (ArtIntersectCtx *ctx, - ArtActiveSeg *left_seg, ArtActiveSeg *right_seg) -{ - right_seg->left = left_seg->left; - if (right_seg->left != NULL) - right_seg->left->right = right_seg; - else - ctx->active_head = right_seg; - left_seg->right = right_seg->right; - if (left_seg->right != NULL) - left_seg->right->left = left_seg; - left_seg->left = right_seg; - right_seg->right = left_seg; -} - -/** - * art_svp_intersect_test_cross: Test crossing of a pair of active segments. - * @ctx: Intersector context. - * @left_seg: Left segment of the pair. - * @right_seg: Right segment of the pair. - * @break_flags: Flags indicating whether to break neighbors. - * - * Tests crossing of @left_seg and @right_seg. If there is a crossing, - * inserts the intersection point into both segments. - * - * Return value: True if the intersection took place at the current - * scan line, indicating further iteration is needed. - **/ -static art_boolean -art_svp_intersect_test_cross (ArtIntersectCtx *ctx, - ArtActiveSeg *left_seg, ArtActiveSeg *right_seg, - ArtBreakFlags break_flags) -{ - gdouble left_x0, left_y0, left_x1; - gdouble left_y1 = left_seg->y1; - gdouble right_y1 = right_seg->y1; - gdouble d; - - const ArtSVPSeg *in_seg; - gint in_curs; - gdouble d0, d1, t; - gdouble x, y; /* intersection point */ - - if (left_seg->y0 == right_seg->y0 && left_seg->x[0] == right_seg->x[0]) - { - /* Top points of left and right segments coincide. This case - feels like a bit of duplication - we may want to merge it - with the cases below. However, this way, we're sure that this - logic makes only localized changes. */ - - if (left_y1 < right_y1) - { - /* Test left (x1, y1) against right segment */ - gdouble left_x1 = left_seg->x[1]; - - if (left_x1 < - right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1] || - left_y1 == right_seg->y0) - return ART_FALSE; - d = left_x1 * right_seg->a + left_y1 * right_seg->b + right_seg->c; - if (d < -EPSILON_A) - return ART_FALSE; - else if (d < EPSILON_A) - { - /* I'm unsure about the break flags here. */ - gdouble right_x1 = art_svp_intersect_break (ctx, right_seg, - left_x1, left_y1, - ART_BREAK_RIGHT); - if (left_x1 <= right_x1) - return ART_FALSE; - } - } - else if (left_y1 > right_y1) - { - /* Test right (x1, y1) against left segment */ - gdouble right_x1 = right_seg->x[1]; - - if (right_x1 > left_seg->x[left_seg->flags & ART_ACTIVE_FLAGS_BNEG] || - right_y1 == left_seg->y0) - return ART_FALSE; - d = right_x1 * left_seg->a + right_y1 * left_seg->b + left_seg->c; - if (d > EPSILON_A) - return ART_FALSE; - else if (d > -EPSILON_A) - { - /* See above regarding break flags. */ - gdouble left_x1 = art_svp_intersect_break (ctx, left_seg, - right_x1, right_y1, - ART_BREAK_LEFT); - if (left_x1 <= right_x1) - return ART_FALSE; - } - } - else /* left_y1 == right_y1 */ - { - gdouble left_x1 = left_seg->x[1]; - gdouble right_x1 = right_seg->x[1]; - - if (left_x1 <= right_x1) - return ART_FALSE; - } - art_svp_intersect_swap_active (ctx, left_seg, right_seg); - return ART_TRUE; - } - - if (left_y1 < right_y1) - { - /* Test left (x1, y1) against right segment */ - gdouble left_x1 = left_seg->x[1]; - - if (left_x1 < - right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1] || - left_y1 == right_seg->y0) - return ART_FALSE; - d = left_x1 * right_seg->a + left_y1 * right_seg->b + right_seg->c; - if (d < -EPSILON_A) - return ART_FALSE; - else if (d < EPSILON_A) - { - gdouble right_x1 = art_svp_intersect_break (ctx, right_seg, - left_x1, left_y1, - ART_BREAK_RIGHT); - if (left_x1 <= right_x1) - return ART_FALSE; - } - } - else if (left_y1 > right_y1) - { - /* Test right (x1, y1) against left segment */ - gdouble right_x1 = right_seg->x[1]; - - if (right_x1 > left_seg->x[left_seg->flags & ART_ACTIVE_FLAGS_BNEG] || - right_y1 == left_seg->y0) - return ART_FALSE; - d = right_x1 * left_seg->a + right_y1 * left_seg->b + left_seg->c; - if (d > EPSILON_A) - return ART_FALSE; - else if (d > -EPSILON_A) - { - gdouble left_x1 = art_svp_intersect_break (ctx, left_seg, - right_x1, right_y1, - ART_BREAK_LEFT); - if (left_x1 <= right_x1) - return ART_FALSE; - } - } - else /* left_y1 == right_y1 */ - { - gdouble left_x1 = left_seg->x[1]; - gdouble right_x1 = right_seg->x[1]; - - if (left_x1 <= right_x1) - return ART_FALSE; - } - - /* The segments cross. Find the intersection point. */ - - in_seg = left_seg->in_seg; - in_curs = left_seg->in_curs; - left_x0 = in_seg->points[in_curs - 1].x; - left_y0 = in_seg->points[in_curs - 1].y; - left_x1 = in_seg->points[in_curs].x; - left_y1 = in_seg->points[in_curs].y; - d0 = left_x0 * right_seg->a + left_y0 * right_seg->b + right_seg->c; - d1 = left_x1 * right_seg->a + left_y1 * right_seg->b + right_seg->c; - if (d0 == d1) - { - x = left_x0; - y = left_y0; - } - else - { - /* Is this division always safe? It could possibly overflow. */ - t = d0 / (d0 - d1); - if (t <= 0) - { - x = left_x0; - y = left_y0; - } - else if (t >= 1) - { - x = left_x1; - y = left_y1; - } - else - { - x = left_x0 + t * (left_x1 - left_x0); - y = left_y0 + t * (left_y1 - left_y0); - } - } - - /* Make sure intersection point is within bounds of right seg. */ - if (y < right_seg->y0) - { - x = right_seg->x[0]; - y = right_seg->y0; - } - else if (y > right_seg->y1) - { - x = right_seg->x[1]; - y = right_seg->y1; - } - else if (x < right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1]) - x = right_seg->x[(right_seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1]; - else if (x > right_seg->x[right_seg->flags & ART_ACTIVE_FLAGS_BNEG]) - x = right_seg->x[right_seg->flags & ART_ACTIVE_FLAGS_BNEG]; - - if (y == left_seg->y0) - { - if (y != right_seg->y0) - { - art_svp_intersect_push_pt (ctx, right_seg, x, y); - if ((break_flags & ART_BREAK_RIGHT) && right_seg->right != NULL) - art_svp_intersect_add_point (ctx, x, y, right_seg->right, - break_flags); - } - else - { - /* Intersection takes place at current scan line; process - immediately rather than queueing intersection point into - priq. */ - ArtActiveSeg *winner, *loser; - - /* Choose "most vertical" segement */ - if (left_seg->a > right_seg->a) - { - winner = left_seg; - loser = right_seg; - } - else - { - winner = right_seg; - loser = left_seg; - } - - loser->x[0] = winner->x[0]; - loser->horiz_x = loser->x[0]; - loser->horiz_delta_wind += loser->delta_wind; - winner->horiz_delta_wind -= loser->delta_wind; - - art_svp_intersect_swap_active (ctx, left_seg, right_seg); - return ART_TRUE; - } - } - else if (y == right_seg->y0) - { - art_svp_intersect_push_pt (ctx, left_seg, x, y); - if ((break_flags & ART_BREAK_LEFT) && left_seg->left != NULL) - art_svp_intersect_add_point (ctx, x, y, left_seg->left, - break_flags); - } - else - { - /* Insert the intersection point into both segments. */ - art_svp_intersect_push_pt (ctx, left_seg, x, y); - art_svp_intersect_push_pt (ctx, right_seg, x, y); - if ((break_flags & ART_BREAK_LEFT) && left_seg->left != NULL) - art_svp_intersect_add_point (ctx, x, y, left_seg->left, break_flags); - if ((break_flags & ART_BREAK_RIGHT) && right_seg->right != NULL) - art_svp_intersect_add_point (ctx, x, y, right_seg->right, break_flags); - } - return ART_FALSE; -} - -/** - * art_svp_intersect_active_delete: Delete segment from active list. - * @ctx: Intersection context. - * @seg: Segment to delete. - * - * Deletes @seg from the active list. - **/ -static /* todo inline */ void -art_svp_intersect_active_delete (ArtIntersectCtx *ctx, ArtActiveSeg *seg) -{ - ArtActiveSeg *left = seg->left, *right = seg->right; - - if (left != NULL) - left->right = right; - else - ctx->active_head = right; - if (right != NULL) - right->left = left; -} - -/** - * art_svp_intersect_active_free: Free an active segment. - * @seg: Segment to delete. - * - * Frees @seg. - **/ -static /* todo inline */ void -art_svp_intersect_active_free (ArtActiveSeg *seg) -{ - art_free (seg->stack); - art_free (seg); -} - -/** - * art_svp_intersect_insert_cross: Test crossings of newly inserted line. - * - * Tests @seg against its left and right neighbors for intersections. - * Precondition: the line in @seg is not purely horizontal. - **/ -static void -art_svp_intersect_insert_cross (ArtIntersectCtx *ctx, - ArtActiveSeg *seg) -{ - ArtActiveSeg *left = seg, *right = seg; - - for (;;) - { - if (left != NULL) - { - ArtActiveSeg *leftc; - - for (leftc = left->left; leftc != NULL; leftc = leftc->left) - if (!(leftc->flags & ART_ACTIVE_FLAGS_DEL)) - break; - if (leftc != NULL && - art_svp_intersect_test_cross (ctx, leftc, left, - ART_BREAK_LEFT)) - { - if (left == right || right == NULL) - right = left->right; - } - else - { - left = NULL; - } - } - else if (right != NULL && right->right != NULL) - { - ArtActiveSeg *rightc; - - for (rightc = right->right; rightc != NULL; rightc = rightc->right) - if (!(rightc->flags & ART_ACTIVE_FLAGS_DEL)) - break; - if (rightc != NULL && - art_svp_intersect_test_cross (ctx, right, rightc, - ART_BREAK_RIGHT)) - { - if (left == right || left == NULL) - left = right->left; - } - else - { - right = NULL; - } - } - else - break; - } -} - -/** - * art_svp_intersect_horiz: Add horizontal line segment. - * @ctx: Intersector context. - * @seg: Segment on which to add horizontal line. - * @x0: Old x position. - * @x1: New x position. - * - * Adds a horizontal line from @x0 to @x1, and updates the current - * location of @seg to @x1. - **/ -static void -art_svp_intersect_horiz (ArtIntersectCtx *ctx, ArtActiveSeg *seg, - gdouble x0, gdouble x1) -{ - ArtActiveSeg *hs; - - if (x0 == x1) - return; - - hs = art_new (ArtActiveSeg, 1); - - hs->flags = ART_ACTIVE_FLAGS_DEL | (seg->flags & ART_ACTIVE_FLAGS_OUT); - if (seg->flags & ART_ACTIVE_FLAGS_OUT) - { - ArtSvpWriter *swr = ctx->out; - - swr->add_point (swr, seg->seg_id, x0, ctx->y); - } - hs->seg_id = seg->seg_id; - hs->horiz_x = x0; - hs->horiz_delta_wind = seg->delta_wind; - hs->stack = NULL; - - /* Ideally, the (a, b, c) values will never be read. However, there - are probably some tests remaining that don't check for _DEL - before evaluating the line equation. For those, these - initializations will at least prevent a UMR of the values, which - can crash on some platforms. */ - hs->a = 0.0; - hs->b = 0.0; - hs->c = 0.0; - - seg->horiz_delta_wind -= seg->delta_wind; - - art_svp_intersect_add_horiz (ctx, hs); - - if (x0 > x1) - { - ArtActiveSeg *left; - art_boolean first = ART_TRUE; - - for (left = seg->left; left != NULL; left = seg->left) - { - gint left_bneg = left->flags & ART_ACTIVE_FLAGS_BNEG; - - if (left->x[left_bneg] <= x1) - break; - if (left->x[left_bneg ^ 1] <= x1 && - x1 * left->a + ctx->y * left->b + left->c >= 0) - break; - if (left->y0 != ctx->y && left->y1 != ctx->y) - { - art_svp_intersect_break (ctx, left, x1, ctx->y, ART_BREAK_LEFT); - } - art_svp_intersect_swap_active (ctx, left, seg); - if (first && left->right != NULL) - { - art_svp_intersect_test_cross (ctx, left, left->right, - ART_BREAK_RIGHT); - first = ART_FALSE; - } - } - } - else - { - ArtActiveSeg *right; - art_boolean first = ART_TRUE; - - for (right = seg->right; right != NULL; right = seg->right) - { - gint right_bneg = right->flags & ART_ACTIVE_FLAGS_BNEG; - - if (right->x[right_bneg ^ 1] >= x1) - break; - if (right->x[right_bneg] >= x1 && - x1 * right->a + ctx->y * right->b + right->c <= 0) - break; - if (right->y0 != ctx->y && right->y1 != ctx->y) - { - art_svp_intersect_break (ctx, right, x1, ctx->y, - ART_BREAK_LEFT); - } - art_svp_intersect_swap_active (ctx, seg, right); - if (first && right->left != NULL) - { - art_svp_intersect_test_cross (ctx, right->left, right, - ART_BREAK_RIGHT); - first = ART_FALSE; - } - } - } - - seg->x[0] = x1; - seg->x[1] = x1; - seg->horiz_x = x1; - seg->flags &= ~ART_ACTIVE_FLAGS_OUT; -} - -/** - * art_svp_intersect_insert_line: Insert a line into the active list. - * @ctx: Intersector context. - * @seg: Segment containing line to insert. - * - * Inserts the line into the intersector context, taking care of any - * intersections, and adding the appropriate horizontal points to the - * active list. - **/ -static void -art_svp_intersect_insert_line (ArtIntersectCtx *ctx, ArtActiveSeg *seg) -{ - if (seg->y1 == seg->y0) - { - art_svp_intersect_horiz (ctx, seg, seg->x[0], seg->x[1]); - } - else - { - art_svp_intersect_insert_cross (ctx, seg); - art_svp_intersect_add_horiz (ctx, seg); - } -} - -static void -art_svp_intersect_process_intersection (ArtIntersectCtx *ctx, - ArtActiveSeg *seg) -{ - gint n_stack = --seg->n_stack; - seg->x[1] = seg->stack[n_stack - 1].x; - seg->y1 = seg->stack[n_stack - 1].y; - seg->x[0] = seg->stack[n_stack].x; - seg->y0 = seg->stack[n_stack].y; - seg->horiz_x = seg->x[0]; - art_svp_intersect_insert_line (ctx, seg); -} - -static void -art_svp_intersect_advance_cursor (ArtIntersectCtx *ctx, ArtActiveSeg *seg, - ArtPriPoint *pri_pt) -{ - const ArtSVPSeg *in_seg = seg->in_seg; - gint in_curs = seg->in_curs; - ArtSvpWriter *swr = seg->flags & ART_ACTIVE_FLAGS_OUT ? ctx->out : NULL; - - if (swr != NULL) - swr->add_point (swr, seg->seg_id, seg->x[1], seg->y1); - if (in_curs + 1 == in_seg->n_points) - { - ArtActiveSeg *left = seg->left, *right = seg->right; - -#if 0 - if (swr != NULL) - swr->close_segment (swr, seg->seg_id); - seg->flags &= ~ART_ACTIVE_FLAGS_OUT; -#endif - seg->flags |= ART_ACTIVE_FLAGS_DEL; - art_svp_intersect_add_horiz (ctx, seg); - art_svp_intersect_active_delete (ctx, seg); - if (left != NULL && right != NULL) - art_svp_intersect_test_cross (ctx, left, right, - ART_BREAK_LEFT | ART_BREAK_RIGHT); - art_free (pri_pt); - } - else - { - seg->horiz_x = seg->x[1]; - - art_svp_intersect_setup_seg (seg, pri_pt); - art_pri_insert (ctx->pq, pri_pt); - art_svp_intersect_insert_line (ctx, seg); - } -} - -static void -art_svp_intersect_add_seg (ArtIntersectCtx *ctx, const ArtSVPSeg *in_seg) -{ - ArtActiveSeg *seg = art_new (ArtActiveSeg, 1); - ArtActiveSeg *test; - gdouble x0, y0; - ArtActiveSeg *beg_range; - ArtActiveSeg *last = NULL; - ArtActiveSeg *left, *right; - ArtPriPoint *pri_pt = art_new (ArtPriPoint, 1); - - seg->flags = 0; - seg->in_seg = in_seg; - seg->in_curs = 0; - - seg->n_stack_max = 4; - seg->stack = art_new (ArtPoint, seg->n_stack_max); - - seg->horiz_delta_wind = 0; - - seg->wind_left = 0; - - pri_pt->user_data = seg; - art_svp_intersect_setup_seg (seg, pri_pt); - art_pri_insert (ctx->pq, pri_pt); - - /* Find insertion place for new segment */ - /* This is currently a left-to-right scan, but should be replaced - with a binary search as soon as it's validated. */ - - x0 = in_seg->points[0].x; - y0 = in_seg->points[0].y; - beg_range = NULL; - for (test = ctx->active_head; test != NULL; test = test->right) - { - gdouble d; - gint test_bneg = test->flags & ART_ACTIVE_FLAGS_BNEG; - - if (x0 < test->x[test_bneg]) - { - if (x0 < test->x[test_bneg ^ 1]) - break; - d = x0 * test->a + y0 * test->b + test->c; - if (d < 0) - break; - } - last = test; - } - - left = art_svp_intersect_add_point (ctx, x0, y0, last, - ART_BREAK_LEFT | ART_BREAK_RIGHT); - seg->left = left; - if (left == NULL) - { - right = ctx->active_head; - ctx->active_head = seg; - } - else - { - right = left->right; - left->right = seg; - } - seg->right = right; - if (right != NULL) - right->left = seg; - - seg->delta_wind = in_seg->dir ? 1 : -1; - seg->horiz_x = x0; - - art_svp_intersect_insert_line (ctx, seg); -} - -/** - * art_svp_intersect_horiz_commit: Commit points in horiz list to output. - * @ctx: Intersection context. - * - * The main function of the horizontal commit is to output new - * points to the output writer. - * - * This "commit" pass is also where winding numbers are assigned, - * because doing it here provides much greater tolerance for inputs - * which are not in strict SVP order. - * - * Each cluster in the horiz_list contains both segments that are in - * the active list (ART_ACTIVE_FLAGS_DEL is false) and that are not, - * and are scheduled to be deleted (ART_ACTIVE_FLAGS_DEL is true). We - * need to deal with both. - **/ -static void -art_svp_intersect_horiz_commit (ArtIntersectCtx *ctx) -{ - ArtActiveSeg *seg; - gint winding_number = 0; /* initialization just to avoid warning */ - gint horiz_wind = 0; - gdouble last_x = 0; /* initialization just to avoid warning */ - - /* Output points to svp writer. */ - for (seg = ctx->horiz_first; seg != NULL;) - { - /* Find a cluster with common horiz_x, */ - ArtActiveSeg *curs; - gdouble x = seg->horiz_x; - - /* Generate any horizontal segments. */ - if (horiz_wind != 0) - { - ArtSvpWriter *swr = ctx->out; - gint seg_id; - - seg_id = swr->add_segment (swr, winding_number, horiz_wind, - last_x, ctx->y); - swr->add_point (swr, seg_id, x, ctx->y); - swr->close_segment (swr, seg_id); - } - - /* Find first active segment in cluster. */ - - for (curs = seg; curs != NULL && curs->horiz_x == x; - curs = curs->horiz_right) - if (!(curs->flags & ART_ACTIVE_FLAGS_DEL)) - break; - - if (curs != NULL && curs->horiz_x == x) - { - /* There exists at least one active segment in this cluster. */ - - /* Find beginning of cluster. */ - for (; curs->left != NULL; curs = curs->left) - if (curs->left->horiz_x != x) - break; - - if (curs->left != NULL) - winding_number = curs->left->wind_left + curs->left->delta_wind; - else - winding_number = 0; - - do - { - if (!(curs->flags & ART_ACTIVE_FLAGS_OUT) || - curs->wind_left != winding_number) - { - ArtSvpWriter *swr = ctx->out; - - if (curs->flags & ART_ACTIVE_FLAGS_OUT) - { - swr->add_point (swr, curs->seg_id, - curs->horiz_x, ctx->y); - swr->close_segment (swr, curs->seg_id); - } - - curs->seg_id = swr->add_segment (swr, winding_number, - curs->delta_wind, - x, ctx->y); - curs->flags |= ART_ACTIVE_FLAGS_OUT; - } - curs->wind_left = winding_number; - winding_number += curs->delta_wind; - curs = curs->right; - } - while (curs != NULL && curs->horiz_x == x); - } - - /* Skip past cluster. */ - do - { - ArtActiveSeg *next = seg->horiz_right; - - seg->flags &= ~ART_ACTIVE_FLAGS_IN_HORIZ; - horiz_wind += seg->horiz_delta_wind; - seg->horiz_delta_wind = 0; - if (seg->flags & ART_ACTIVE_FLAGS_DEL) - { - if (seg->flags & ART_ACTIVE_FLAGS_OUT) - { - ArtSvpWriter *swr = ctx->out; - swr->close_segment (swr, seg->seg_id); - } - art_svp_intersect_active_free (seg); - } - seg = next; - } - while (seg != NULL && seg->horiz_x == x); - - last_x = x; - } - ctx->horiz_first = NULL; - ctx->horiz_last = NULL; -} - -#ifdef SANITYCHECK -static void -art_svp_intersect_sanitycheck (ArtIntersectCtx *ctx) -{ - ArtActiveSeg *seg; - ArtActiveSeg *last = NULL; - gdouble d; - - for (seg = ctx->active_head; seg != NULL; seg = seg->right) - { - if (seg->left != last) - { - art_warn ("*** art_svp_intersect_sanitycheck: last=%lx, seg->left=%lx\n", - (unsigned long)last, (unsigned long)seg->left); - } - if (last != NULL) - { - /* pairwise compare with previous seg */ - - /* First the top. */ - if (last->y0 < seg->y0) - { - } - else - { - } - - /* Then the bottom. */ - if (last->y1 < seg->y1) - { - if (!((last->x[1] < - seg->x[(seg->flags & ART_ACTIVE_FLAGS_BNEG) ^ 1]) || - last->y1 == seg->y0)) - { - d = last->x[1] * seg->a + last->y1 * seg->b + seg->c; - if (d >= -EPSILON_A) - art_warn ("*** bottom (%g, %g) of %lx is not clear of %lx to right (d = %g)\n", - last->x[1], last->y1, (unsigned long) last, - (unsigned long) seg, d); - } - } - else if (last->y1 > seg->y1) - - { - if (!((seg->x[1] > - last->x[last->flags & ART_ACTIVE_FLAGS_BNEG]) || - seg->y1 == last->y0)) - { - d = seg->x[1] * last->a + seg->y1 * last->b + last->c; - if (d <= EPSILON_A) - art_warn ("*** bottom (%g, %g) of %lx is not clear of %lx to left (d = %g)\n", - seg->x[1], seg->y1, (unsigned long) seg, - (unsigned long) last, d); - } - } - else - { - if (last->x[1] > seg->x[1]) - art_warn ("*** bottoms (%g, %g) of %lx and (%g, %g) of %lx out of order\n", - last->x[1], last->y1, (unsigned long)last, - seg->x[1], seg->y1, (unsigned long)seg); - } - } - last = seg; - } -} -#endif - -void -art_svp_intersector (const ArtSVP *in, ArtSvpWriter *out) -{ - ArtIntersectCtx *ctx; - ArtPriQ *pq; - ArtPriPoint *first_point; - - if (in->n_segs == 0) - return; - - ctx = art_new (ArtIntersectCtx, 1); - ctx->in = in; - ctx->out = out; - pq = art_pri_new (); - ctx->pq = pq; - - ctx->active_head = NULL; - - ctx->horiz_first = NULL; - ctx->horiz_last = NULL; - - ctx->in_curs = 0; - first_point = art_new (ArtPriPoint, 1); - first_point->x = in->segs[0].points[0].x; - first_point->y = in->segs[0].points[0].y; - first_point->user_data = NULL; - ctx->y = first_point->y; - art_pri_insert (pq, first_point); - - while (!art_pri_empty (pq)) - { - ArtPriPoint *pri_point = art_pri_choose (pq); - ArtActiveSeg *seg = (ArtActiveSeg *)pri_point->user_data; - -#ifdef SANITYCHECK - art_svp_intersect_sanitycheck (ctx); -#endif - - if (ctx->y != pri_point->y) - { - art_svp_intersect_horiz_commit (ctx); - ctx->y = pri_point->y; - } - - if (seg == NULL) - { - /* Insert new segment from input */ - const ArtSVPSeg *in_seg = &in->segs[ctx->in_curs++]; - art_svp_intersect_add_seg (ctx, in_seg); - if (ctx->in_curs < in->n_segs) - { - const ArtSVPSeg *next_seg = &in->segs[ctx->in_curs]; - pri_point->x = next_seg->points[0].x; - pri_point->y = next_seg->points[0].y; - /* user_data is already NULL */ - art_pri_insert (pq, pri_point); - } - else - art_free (pri_point); - } - else - { - gint n_stack = seg->n_stack; - - if (n_stack > 1) - { - art_svp_intersect_process_intersection (ctx, seg); - art_free (pri_point); - } - else - { - art_svp_intersect_advance_cursor (ctx, seg, pri_point); - } - } - } - - art_svp_intersect_horiz_commit (ctx); - - art_pri_free (pq); - art_free (ctx); -} - -#endif /* not TEST_PRIQ */ diff --git a/libart_lgpl/art_svp_intersect.h b/libart_lgpl/art_svp_intersect.h deleted file mode 100644 index b585ed20f5..0000000000 --- a/libart_lgpl/art_svp_intersect.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 2001 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_INTERSECT_H__ -#define __ART_SVP_INTERSECT_H__ - -/* The funky new SVP intersector. */ - -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef ART_WIND_RULE_DEFINED -#define ART_WIND_RULE_DEFINED -typedef enum { - ART_WIND_RULE_NONZERO, - ART_WIND_RULE_INTERSECT, - ART_WIND_RULE_ODDEVEN, - ART_WIND_RULE_POSITIVE -} ArtWindRule; -#endif - -typedef struct _ArtSvpWriter ArtSvpWriter; - -struct _ArtSvpWriter { - gint (*add_segment) (ArtSvpWriter *self, gint wind_left, gint delta_wind, - gdouble x, gdouble y); - void (*add_point) (ArtSvpWriter *self, gint seg_id, gdouble x, gdouble y); - void (*close_segment) (ArtSvpWriter *self, gint seg_id); -}; - -ArtSvpWriter * -art_svp_writer_rewind_new (ArtWindRule rule); - -ArtSVP * -art_svp_writer_rewind_reap (ArtSvpWriter *self); - -#if 0 /* XXX already declared in art_svp.h */ -gint -art_svp_seg_compare (gconstpointer s1, gconstpointer s2); -#endif - -void -art_svp_intersector (const ArtSVP *in, ArtSvpWriter *out); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_INTERSECT_H__ */ diff --git a/libart_lgpl/art_svp_ops.c b/libart_lgpl/art_svp_ops.c deleted file mode 100644 index 72d360282a..0000000000 --- a/libart_lgpl/art_svp_ops.c +++ /dev/null @@ -1,168 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Vector path set operations, over sorted vpaths. */ - -#include "config.h" -#include "art_svp_ops.h" - -#include "art_misc.h" - -#include "art_svp.h" -#include "art_vpath.h" -#include "art_svp_vpath.h" -#include "art_svp.h" -#ifdef ART_USE_NEW_INTERSECTOR -#include "art_svp_intersect.h" -#else -#include "art_svp_wind.h" -#endif -#include "art_vpath_svp.h" - -/* Merge the segments of the two svp's. The resulting svp will share - segments with args passed in, so be super-careful with the - allocation. */ -/** - * art_svp_merge: Merge the segments of two svp's. - * @svp1: One svp to merge. - * @svp2: The other svp to merge. - * - * Merges the segments of two SVP's into a new one. The resulting - * #ArtSVP data structure will share the segments of the argument - * svp's, so it is probably a good idea to free it shallowly, - * especially if the arguments will be freed with art_svp_free(). - * - * Return value: The merged #ArtSVP. - **/ -static ArtSVP * -art_svp_merge (const ArtSVP *svp1, const ArtSVP *svp2) -{ - ArtSVP *svp_new; - gint ix; - gint ix1, ix2; - - svp_new = (ArtSVP *)art_alloc (sizeof (ArtSVP) + - (svp1->n_segs + svp2->n_segs - 1) * - sizeof (ArtSVPSeg)); - ix1 = 0; - ix2 = 0; - for (ix = 0; ix < svp1->n_segs + svp2->n_segs; ix++) - { - if (ix1 < svp1->n_segs && - (ix2 == svp2->n_segs || - art_svp_seg_compare (&svp1->segs[ix1], &svp2->segs[ix2]) < 1)) - svp_new->segs[ix] = svp1->segs[ix1++]; - else - svp_new->segs[ix] = svp2->segs[ix2++]; - } - - svp_new->n_segs = ix; - return svp_new; -} - -#ifndef ART_USE_NEW_INTERSECTOR -static ArtSVP * -art_svp_merge_perturbed (const ArtSVP *svp1, const ArtSVP *svp2) -{ - ArtVpath *vpath1, *vpath2; - ArtVpath *vpath1_p, *vpath2_p; - ArtSVP *svp1_p, *svp2_p; - ArtSVP *svp_new; - - vpath1 = art_vpath_from_svp (svp1); - vpath1_p = art_vpath_perturb (vpath1); - art_free (vpath1); - svp1_p = art_svp_from_vpath (vpath1_p); - art_free (vpath1_p); - - vpath2 = art_vpath_from_svp (svp2); - vpath2_p = art_vpath_perturb (vpath2); - art_free (vpath2); - svp2_p = art_svp_from_vpath (vpath2_p); - art_free (vpath2_p); - - svp_new = art_svp_merge (svp1_p, svp2_p); - art_free (svp1_p); - art_free (svp2_p); - - return svp_new; -} -#endif - -/* Compute the intersection of two vector paths. - - Status of this routine: - - Basic correctness: Seems to work. - - Numerical stability: We cheat (adding random perturbation). Thus, - it seems very likely that no numerical stability problems will be - seen in practice. - - Speed: Would be better if we didn't go to unsorted vector path - and back to add the perturbation. - - Precision: The perturbation fuzzes the coordinates slightly. In - cases of butting segments, razor thin long isolated segments may - appear. - -*/ - -/** - * art_svp_intersect: Compute the intersection of two sorted vector paths. - * @svp1: One sorted vector path. - * @svp2: The other sorted vector path. - * - * Computes the intersection of the two argument svp's. Given two - * svp's with winding numbers of 0 and 1 everywhere, the resulting - * winding number will be 1 where both of the argument svp's has a - * winding number 1, 0 otherwise. The result is newly allocated. - * - * Currently, this routine has accuracy problems pending the - * implementation of the new intersector. - * - * Return value: The intersection of @svp1 and @svp2. - **/ -ArtSVP * -art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2) -{ -#ifdef ART_USE_NEW_INTERSECTOR - ArtSVP *svp3, *svp_new; - ArtSvpWriter *swr; - - svp3 = art_svp_merge (svp1, svp2); - swr = art_svp_writer_rewind_new (ART_WIND_RULE_INTERSECT); - art_svp_intersector (svp3, swr); - svp_new = art_svp_writer_rewind_reap (swr); - art_free (svp3); /* shallow free because svp3 contains shared segments */ - - return svp_new; -#else - ArtSVP *svp3, *svp4, *svp_new; - - svp3 = art_svp_merge_perturbed (svp1, svp2); - svp4 = art_svp_uncross (svp3); - art_svp_free (svp3); - - svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_INTERSECT); - art_svp_free (svp4); - return svp_new; -#endif -} - diff --git a/libart_lgpl/art_svp_ops.h b/libart_lgpl/art_svp_ops.h deleted file mode 100644 index 8f150c28dc..0000000000 --- a/libart_lgpl/art_svp_ops.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_OPS_H__ -#define __ART_SVP_OPS_H__ - -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Vector path set operations, over sorted vpaths. */ - -ArtSVP *art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_OPS_H__ */ diff --git a/libart_lgpl/art_svp_point.c b/libart_lgpl/art_svp_point.c deleted file mode 100644 index 8278bca55e..0000000000 --- a/libart_lgpl/art_svp_point.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1999 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_svp_point.h" - -#include <math.h> -#include "art_misc.h" - -#include "art_svp.h" - -/* Determine whether a point is inside, or near, an svp. */ - -/* return winding number of point wrt svp */ -/** - * art_svp_point_wind: Determine winding number of a point with respect to svp. - * @svp: The svp. - * @x: The X coordinate of the point. - * @y: The Y coordinate of the point. - * - * Determine the winding number of the point @x, @y with respect to @svp. - * - * Return value: the winding number. - **/ -gint -art_svp_point_wind (ArtSVP *svp, gdouble x, gdouble y) -{ - gint i, j; - gint wind = 0; - - for (i = 0; i < svp->n_segs; i++) - { - ArtSVPSeg *seg = &svp->segs[i]; - - if (seg->bbox.y0 > y) - break; - - if (seg->bbox.y1 > y) - { - if (seg->bbox.x1 < x) - wind += seg->dir ? 1 : -1; - else if (seg->bbox.x0 <= x) - { - gdouble x0, y0, x1, y1, dx, dy; - - for (j = 0; j < seg->n_points - 1; j++) - { - if (seg->points[j + 1].y > y) - break; - } - x0 = seg->points[j].x; - y0 = seg->points[j].y; - x1 = seg->points[j + 1].x; - y1 = seg->points[j + 1].y; - - dx = x1 - x0; - dy = y1 - y0; - if ((x - x0) * dy > (y - y0) * dx) - wind += seg->dir ? 1 : -1; - } - } - } - - return wind; -} - -/** - * art_svp_point_dist: Determine distance between point and svp. - * @svp: The svp. - * @x: The X coordinate of the point. - * @y: The Y coordinate of the point. - * - * Determines the distance of the point @x, @y to the closest edge in - * @svp. A large number is returned if @svp is empty. - * - * Return value: the distance. - **/ -gdouble -art_svp_point_dist (ArtSVP *svp, gdouble x, gdouble y) -{ - gint i, j; - gdouble dist_sq; - gdouble best_sq = -1; - - for (i = 0; i < svp->n_segs; i++) - { - ArtSVPSeg *seg = &svp->segs[i]; - for (j = 0; j < seg->n_points - 1; j++) - { - gdouble x0 = seg->points[j].x; - gdouble y0 = seg->points[j].y; - gdouble x1 = seg->points[j + 1].x; - gdouble y1 = seg->points[j + 1].y; - - gdouble dx = x1 - x0; - gdouble dy = y1 - y0; - - gdouble dxx0 = x - x0; - gdouble dyy0 = y - y0; - - gdouble dot = dxx0 * dx + dyy0 * dy; - - if (dot < 0) - dist_sq = dxx0 * dxx0 + dyy0 * dyy0; - else - { - gdouble rr = dx * dx + dy * dy; - - if (dot > rr) - dist_sq = (x - x1) * (x - x1) + (y - y1) * (y - y1); - else - { - gdouble perp = (y - y0) * dx - (x - x0) * dy; - - dist_sq = perp * perp / rr; - } - } - if (best_sq < 0 || dist_sq < best_sq) - best_sq = dist_sq; - } - } - - if (best_sq >= 0) - return sqrt (best_sq); - else - return 1e12; -} - diff --git a/libart_lgpl/art_svp_point.h b/libart_lgpl/art_svp_point.h deleted file mode 100644 index 53faaba37e..0000000000 --- a/libart_lgpl/art_svp_point.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1999 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_POINT_H__ -#define __ART_SVP_POINT_H__ - -/* Determine whether a point is inside, or near, an svp. */ - -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -gint -art_svp_point_wind (ArtSVP *svp, gdouble x, gdouble y); - -gdouble -art_svp_point_dist (ArtSVP *svp, gdouble x, gdouble y); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_H__ */ - diff --git a/libart_lgpl/art_svp_render_aa.c b/libart_lgpl/art_svp_render_aa.c deleted file mode 100644 index a6efa4ae0c..0000000000 --- a/libart_lgpl/art_svp_render_aa.c +++ /dev/null @@ -1,462 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* The spiffy antialiased renderer for sorted vector paths. */ - -#include "config.h" -#include "art_svp_render_aa.h" - -#include <math.h> -#include <string.h> /* for memmove */ -#include "art_misc.h" - -#include "art_rect.h" -#include "art_svp.h" - -#include <stdio.h> - -typedef gdouble artfloat; - -struct _ArtSVPRenderAAIter { - const ArtSVP *svp; - gint x0, x1; - gint y; - gint seg_ix; - - gint *active_segs; - gint n_active_segs; - gint *cursor; - artfloat *seg_x; - artfloat *seg_dx; - - ArtSVPRenderAAStep *steps; -}; - -static void -art_svp_render_insert_active (gint i, gint *active_segs, gint n_active_segs, - artfloat *seg_x, artfloat *seg_dx) -{ - gint j; - artfloat x; - gint tmp1, tmp2; - - /* this is a cheap hack to get ^'s sorted correctly */ - x = seg_x[i] + 0.001 * seg_dx[i]; - for (j = 0; j < n_active_segs && seg_x[active_segs[j]] < x; j++); - - tmp1 = i; - while (j < n_active_segs) - { - tmp2 = active_segs[j]; - active_segs[j] = tmp1; - tmp1 = tmp2; - j++; - } - active_segs[j] = tmp1; -} - -static void -art_svp_render_delete_active (gint *active_segs, gint j, gint n_active_segs) -{ - gint k; - - for (k = j; k < n_active_segs; k++) - active_segs[k] = active_segs[k + 1]; -} - -#define EPSILON 1e-6 - -/* Render the sorted vector path in the given rectangle, antialiased. - - This interface uses a callback for the actual pixel rendering. The - callback is called y1 - y0 times (once for each scan line). The y - coordinate is given as an argument for convenience (it could be - stored in the callback's private data and incremented on each - call). - - The rendered polygon is represented in a semi-runlength format: a - start value and a sequence of "steps". Each step has an x - coordinate and a value delta. The resulting value at position x is - equal to the sum of the start value and all step delta values for - which the step x coordinate is less than or equal to x. An - efficient algorithm will traverse the steps left to right, keeping - a running sum. - - All x coordinates in the steps are guaranteed to be x0 <= x < x1. - (This guarantee is a change from the gfonted vpaar renderer, and is - designed to simplify the callback). - - There is now a further guarantee that no two steps will have the - same x value. This may allow for further speedup and simplification - of renderers. - - The value 0x8000 represents 0% coverage by the polygon, while - 0xff8000 represents 100% coverage. This format is designed so that - >> 16 results in a standard 0x00..0xff value range, with nice - rounding. - - Status of this routine: - - Basic correctness: OK - - Numerical stability: pretty good, although probably not - bulletproof. - - Speed: Needs more aggressive culling of bounding boxes. Can - probably speed up the[x0,x1) clipping of step values. Can do more - of the step calculation in fixed point. - - Precision: No known problems, although it should be tested - thoroughly, especially for symmetry. - -*/ - -ArtSVPRenderAAIter * -art_svp_render_aa_iter (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1) -{ - ArtSVPRenderAAIter *iter = art_new (ArtSVPRenderAAIter, 1); - - iter->svp = svp; - iter->y = y0; - iter->x0 = x0; - iter->x1 = x1; - iter->seg_ix = 0; - - iter->active_segs = art_new (int, svp->n_segs); - iter->cursor = art_new (int, svp->n_segs); - iter->seg_x = art_new (artfloat, svp->n_segs); - iter->seg_dx = art_new (artfloat, svp->n_segs); - iter->steps = art_new (ArtSVPRenderAAStep, x1 - x0); - iter->n_active_segs = 0; - - return iter; -} - -#define ADD_STEP(xpos, xdelta) \ - /* stereotype code fragment for adding a step */ \ - if (n_steps == 0 || steps[n_steps - 1].x < xpos) \ - { \ - sx = n_steps; \ - steps[sx].x = xpos; \ - steps[sx].delta = xdelta; \ - n_steps++; \ - } \ - else \ - { \ - for (sx = n_steps; sx > 0; sx--) \ - { \ - if (steps[sx - 1].x == xpos) \ - { \ - steps[sx - 1].delta += xdelta; \ - sx = n_steps; \ - break; \ - } \ - else if (steps[sx - 1].x < xpos) \ - { \ - break; \ - } \ - } \ - if (sx < n_steps) \ - { \ - memmove (&steps[sx + 1], &steps[sx], \ - (n_steps - sx) * sizeof (steps[0])); \ - steps[sx].x = xpos; \ - steps[sx].delta = xdelta; \ - n_steps++; \ - } \ - } - -void -art_svp_render_aa_iter_step (ArtSVPRenderAAIter *iter, gint *p_start, - ArtSVPRenderAAStep **p_steps, gint *p_n_steps) -{ - const ArtSVP *svp = iter->svp; - gint *active_segs = iter->active_segs; - gint n_active_segs = iter->n_active_segs; - gint *cursor = iter->cursor; - artfloat *seg_x = iter->seg_x; - artfloat *seg_dx = iter->seg_dx; - gint i = iter->seg_ix; - gint j; - gint x0 = iter->x0; - gint x1 = iter->x1; - gint y = iter->y; - gint seg_index; - - gint x; - ArtSVPRenderAAStep *steps = iter->steps; - gint n_steps; - artfloat y_top, y_bot; - artfloat x_top, x_bot; - artfloat x_min, x_max; - gint ix_min, ix_max; - artfloat delta; /* delta should be gint too? */ - gint last, this; - gint xdelta; - artfloat rslope, drslope; - gint start; - const ArtSVPSeg *seg; - gint curs; - artfloat dy; - - gint sx; - - /* insert new active segments */ - for (; i < svp->n_segs && svp->segs[i].bbox.y0 < y + 1; i++) - { - if (svp->segs[i].bbox.y1 > y && - svp->segs[i].bbox.x0 < x1) - { - seg = &svp->segs[i]; - /* move cursor to topmost vector which overlaps [y,y+1) */ - for (curs = 0; seg->points[curs + 1].y < y; curs++); - cursor[i] = curs; - dy = seg->points[curs + 1].y - seg->points[curs].y; - if (fabs (dy) >= EPSILON) - seg_dx[i] = (seg->points[curs + 1].x - seg->points[curs].x) / - dy; - else - seg_dx[i] = 1e12; - seg_x[i] = seg->points[curs].x + - (y - seg->points[curs].y) * seg_dx[i]; - art_svp_render_insert_active (i, active_segs, n_active_segs++, - seg_x, seg_dx); - } - } - - n_steps = 0; - - /* render the runlengths, advancing and deleting as we go */ - start = 0x8000; - - for (j = 0; j < n_active_segs; j++) - { - seg_index = active_segs[j]; - seg = &svp->segs[seg_index]; - curs = cursor[seg_index]; - while (curs != seg->n_points - 1 && - seg->points[curs].y < y + 1) - { - y_top = y; - if (y_top < seg->points[curs].y) - y_top = seg->points[curs].y; - y_bot = y + 1; - if (y_bot > seg->points[curs + 1].y) - y_bot = seg->points[curs + 1].y; - if (y_top != y_bot) { - delta = (seg->dir ? 16711680.0 : -16711680.0) * - (y_bot - y_top); - x_top = seg_x[seg_index] + (y_top - y) * seg_dx[seg_index]; - x_bot = seg_x[seg_index] + (y_bot - y) * seg_dx[seg_index]; - if (x_top < x_bot) - { - x_min = x_top; - x_max = x_bot; - } - else - { - x_min = x_bot; - x_max = x_top; - } - ix_min = floor (x_min); - ix_max = floor (x_max); - if (ix_min >= x1) - { - /* skip; it starts to the right of the render region */ - } - else if (ix_max < x0) - /* it ends to the left of the render region */ - start += delta; - else if (ix_min == ix_max) - { - /* case 1, antialias a single pixel */ - xdelta = (ix_min + 1 - (x_min + x_max) * 0.5) * delta; - - ADD_STEP (ix_min, xdelta) - - if (ix_min + 1 < x1) - { - xdelta = delta - xdelta; - - ADD_STEP (ix_min + 1, xdelta) - } - } - else - { - /* case 2, antialias a run */ - rslope = 1.0 / fabs (seg_dx[seg_index]); - drslope = delta * rslope; - last = - drslope * 0.5 * - (ix_min + 1 - x_min) * (ix_min + 1 - x_min); - xdelta = last; - if (ix_min >= x0) - { - ADD_STEP (ix_min, xdelta) - - x = ix_min + 1; - } - else - { - start += last; - x = x0; - } - if (ix_max > x1) - ix_max = x1; - for (; x < ix_max; x++) - { - this = (seg->dir ? 16711680.0 : -16711680.0) * rslope * - (x + 0.5 - x_min); - xdelta = this - last; - last = this; - - ADD_STEP (x, xdelta) - } - if (x < x1) - { - this = - delta * (1 - 0.5 * - (x_max - ix_max) * (x_max - ix_max) * - rslope); - xdelta = this - last; - last = this; - - ADD_STEP (x, xdelta) - - if (x + 1 < x1) - { - xdelta = delta - last; - - ADD_STEP (x + 1, xdelta) - } - } - } - } - curs++; - if (curs != seg->n_points - 1 && - seg->points[curs].y < y + 1) - { - dy = seg->points[curs + 1].y - seg->points[curs].y; - if (fabs (dy) >= EPSILON) - seg_dx[seg_index] = (seg->points[curs + 1].x - - seg->points[curs].x) / dy; - else - seg_dx[seg_index] = 1e12; - seg_x[seg_index] = seg->points[curs].x + - (y - seg->points[curs].y) * seg_dx[seg_index]; - } - /* break here, instead of duplicating predicate in while? */ - } - if (seg->points[curs].y >= y + 1) - { - curs--; - cursor[seg_index] = curs; - seg_x[seg_index] += seg_dx[seg_index]; - } - else - { - art_svp_render_delete_active (active_segs, j--, - --n_active_segs); - } - } - - *p_start = start; - *p_steps = steps; - *p_n_steps = n_steps; - - iter->seg_ix = i; - iter->n_active_segs = n_active_segs; - iter->y++; -} - -void -art_svp_render_aa_iter_done (ArtSVPRenderAAIter *iter) -{ - art_free (iter->steps); - - art_free (iter->seg_dx); - art_free (iter->seg_x); - art_free (iter->cursor); - art_free (iter->active_segs); - art_free (iter); -} - -/** - * art_svp_render_aa: Render SVP antialiased. - * @svp: The #ArtSVP to render. - * @x0: Left coordinate of destination rectangle. - * @y0: Top coordinate of destination rectangle. - * @x1: Right coordinate of destination rectangle. - * @y1: Bottom coordinate of destination rectangle. - * @callback: The callback which actually paints the pixels. - * @callback_data: Private data for @callback. - * - * Renders the sorted vector path in the given rectangle, antialiased. - * - * This interface uses a callback for the actual pixel rendering. The - * callback is called @y1 - @y0 times (once for each scan line). The y - * coordinate is given as an argument for convenience (it could be - * stored in the callback's private data and incremented on each - * call). - * - * The rendered polygon is represented in a semi-runlength format: a - * start value and a sequence of "steps". Each step has an x - * coordinate and a value delta. The resulting value at position x is - * equal to the sum of the start value and all step delta values for - * which the step x coordinate is less than or equal to x. An - * efficient algorithm will traverse the steps left to right, keeping - * a running sum. - * - * All x coordinates in the steps are guaranteed to be @x0 <= x < @x1. - * (This guarantee is a change from the gfonted vpaar renderer from - * which this routine is derived, and is designed to simplify the - * callback). - * - * The value 0x8000 represents 0% coverage by the polygon, while - * 0xff8000 represents 100% coverage. This format is designed so that - * >> 16 results in a standard 0x00..0xff value range, with nice - * rounding. - * - **/ -void -art_svp_render_aa (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - void (*callback) (gpointer callback_data, - gint y, - gint start, - ArtSVPRenderAAStep *steps, gint n_steps), - gpointer callback_data) -{ - ArtSVPRenderAAIter *iter; - gint y; - gint start; - ArtSVPRenderAAStep *steps; - gint n_steps; - - iter = art_svp_render_aa_iter (svp, x0, y0, x1, y1); - - for (y = y0; y < y1; y++) - { - art_svp_render_aa_iter_step (iter, &start, &steps, &n_steps); - (*callback) (callback_data, y, start, steps, n_steps); - } - - art_svp_render_aa_iter_done (iter); -} diff --git a/libart_lgpl/art_svp_render_aa.h b/libart_lgpl/art_svp_render_aa.h deleted file mode 100644 index 5b5d7ace62..0000000000 --- a/libart_lgpl/art_svp_render_aa.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_RENDER_AA_H__ -#define __ART_SVP_RENDER_AA_H__ - -/* The spiffy antialiased renderer for sorted vector paths. */ - -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct _ArtSVPRenderAAStep ArtSVPRenderAAStep; -typedef struct _ArtSVPRenderAAIter ArtSVPRenderAAIter; - -struct _ArtSVPRenderAAStep { - gint x; - gint delta; /* stored with 16 fractional bits */ -}; - -ArtSVPRenderAAIter * -art_svp_render_aa_iter (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1); - -void -art_svp_render_aa_iter_step (ArtSVPRenderAAIter *iter, gint *p_start, - ArtSVPRenderAAStep **p_steps, gint *p_n_steps); - -void -art_svp_render_aa_iter_done (ArtSVPRenderAAIter *iter); - -void -art_svp_render_aa (const ArtSVP *svp, - gint x0, gint y0, gint x1, gint y1, - void (*callback) (gpointer callback_data, - gint y, - gint start, - ArtSVPRenderAAStep *steps, gint n_steps), - gpointer callback_data); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_RENDER_AA_H__ */ diff --git a/libart_lgpl/art_svp_vpath.c b/libart_lgpl/art_svp_vpath.c deleted file mode 100644 index b75bbea6f7..0000000000 --- a/libart_lgpl/art_svp_vpath.c +++ /dev/null @@ -1,214 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Sort vector paths into sorted vector paths */ - -#include "config.h" -#include "art_svp_vpath.h" - -#include <stdlib.h> -#include <math.h> - -#include "art_misc.h" - -#include "art_vpath.h" -#include "art_svp.h" - -/* reverse a list of points in place */ -static void -reverse_points (ArtPoint *points, gint n_points) -{ - gint i; - ArtPoint tmp_p; - - for (i = 0; i < (n_points >> 1); i++) - { - tmp_p = points[i]; - points[i] = points[n_points - (i + 1)]; - points[n_points - (i + 1)] = tmp_p; - } -} - -/** - * art_svp_from_vpath: Convert a vpath to a sorted vector path. - * @vpath: #ArtVPath to convert. - * - * Converts a vector path into sorted vector path form. The svp form is - * more efficient for rendering and other vector operations. - * - * Basically, the implementation is to traverse the vector path, - * generating a new segment for each "run" of points in the vector - * path with monotonically increasing Y values. All the resulting - * values are then sorted. - * - * Note: I'm not sure that the sorting rule is correct with respect - * to numerical stability issues. - * - * Return value: Resulting sorted vector path. - **/ -ArtSVP * -art_svp_from_vpath (ArtVpath *vpath) -{ - gint n_segs, n_segs_max; - ArtSVP *svp; - gint dir; - gint new_dir; - gint i; - ArtPoint *points; - gint n_points, n_points_max; - gdouble x, y; - gdouble x_min, x_max; - - n_segs = 0; - n_segs_max = 16; - svp = (ArtSVP *)art_alloc (sizeof (ArtSVP) + - (n_segs_max - 1) * sizeof (ArtSVPSeg)); - - dir = 0; - n_points = 0; - n_points_max = 0; - points = NULL; - i = 0; - - x = y = 0; /* unnecessary, given "first code must not be LINETO" invariant, - but it makes gcc -Wall -ansi -pedantic happier */ - x_min = x_max = 0; /* same */ - - while (vpath[i].code != ART_END) { - if (vpath[i].code == ART_MOVETO || vpath[i].code == ART_MOVETO_OPEN) - { - if (points != NULL && n_points >= 2) - { - if (n_segs == n_segs_max) - { - n_segs_max <<= 1; - svp = (ArtSVP *)art_realloc (svp, sizeof (ArtSVP) + - (n_segs_max - 1) * - sizeof (ArtSVPSeg)); - } - svp->segs[n_segs].n_points = n_points; - svp->segs[n_segs].dir = (dir > 0); - if (dir < 0) - reverse_points (points, n_points); - svp->segs[n_segs].points = points; - svp->segs[n_segs].bbox.x0 = x_min; - svp->segs[n_segs].bbox.x1 = x_max; - svp->segs[n_segs].bbox.y0 = points[0].y; - svp->segs[n_segs].bbox.y1 = points[n_points - 1].y; - n_segs++; - points = NULL; - } - - if (points == NULL) - { - n_points_max = 4; - points = art_new (ArtPoint, n_points_max); - } - - n_points = 1; - points[0].x = x = vpath[i].x; - points[0].y = y = vpath[i].y; - x_min = x; - x_max = x; - dir = 0; - } - else /* must be LINETO */ - { - new_dir = (vpath[i].y > y || - (vpath[i].y == y && vpath[i].x > x)) ? 1 : -1; - if (dir && dir != new_dir) - { - /* new segment */ - x = points[n_points - 1].x; - y = points[n_points - 1].y; - if (n_segs == n_segs_max) - { - n_segs_max <<= 1; - svp = (ArtSVP *)art_realloc (svp, sizeof (ArtSVP) + - (n_segs_max - 1) * - sizeof (ArtSVPSeg)); - } - svp->segs[n_segs].n_points = n_points; - svp->segs[n_segs].dir = (dir > 0); - if (dir < 0) - reverse_points (points, n_points); - svp->segs[n_segs].points = points; - svp->segs[n_segs].bbox.x0 = x_min; - svp->segs[n_segs].bbox.x1 = x_max; - svp->segs[n_segs].bbox.y0 = points[0].y; - svp->segs[n_segs].bbox.y1 = points[n_points - 1].y; - n_segs++; - - n_points = 1; - n_points_max = 4; - points = art_new (ArtPoint, n_points_max); - points[0].x = x; - points[0].y = y; - x_min = x; - x_max = x; - } - - if (points != NULL) - { - if (n_points == n_points_max) - art_expand (points, ArtPoint, n_points_max); - points[n_points].x = x = vpath[i].x; - points[n_points].y = y = vpath[i].y; - if (x < x_min) x_min = x; - else if (x > x_max) x_max = x; - n_points++; - } - dir = new_dir; - } - i++; - } - - if (points != NULL) - { - if (n_points >= 2) - { - if (n_segs == n_segs_max) - { - n_segs_max <<= 1; - svp = (ArtSVP *)art_realloc (svp, sizeof (ArtSVP) + - (n_segs_max - 1) * - sizeof (ArtSVPSeg)); - } - svp->segs[n_segs].n_points = n_points; - svp->segs[n_segs].dir = (dir > 0); - if (dir < 0) - reverse_points (points, n_points); - svp->segs[n_segs].points = points; - svp->segs[n_segs].bbox.x0 = x_min; - svp->segs[n_segs].bbox.x1 = x_max; - svp->segs[n_segs].bbox.y0 = points[0].y; - svp->segs[n_segs].bbox.y1 = points[n_points - 1].y; - n_segs++; - } - else - art_free (points); - } - - svp->n_segs = n_segs; - - qsort (&svp->segs, n_segs, sizeof (ArtSVPSeg), art_svp_seg_compare); - - return svp; -} - diff --git a/libart_lgpl/art_svp_vpath.h b/libart_lgpl/art_svp_vpath.h deleted file mode 100644 index ae75adcc84..0000000000 --- a/libart_lgpl/art_svp_vpath.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_VPATH_H__ -#define __ART_SVP_VPATH_H__ - -#include <libart_lgpl/art_svp.h> -#include <libart_lgpl/art_vpath.h> - -/* Sort vector paths into sorted vector paths. */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -ArtSVP * -art_svp_from_vpath (ArtVpath *vpath); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_VPATH_H__ */ diff --git a/libart_lgpl/art_svp_vpath_stroke.c b/libart_lgpl/art_svp_vpath_stroke.c deleted file mode 100644 index c231048103..0000000000 --- a/libart_lgpl/art_svp_vpath_stroke.c +++ /dev/null @@ -1,617 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_svp_vpath_stroke.h" - -#include <stdlib.h> -#include <math.h> - -#include "art_misc.h" - -#include "art_vpath.h" -#include "art_svp.h" -#ifdef ART_USE_NEW_INTERSECTOR -#include "art_svp_intersect.h" -#else -#include "art_svp_wind.h" -#endif -#include "art_svp_vpath.h" - -#define EPSILON 1e-6 -#define EPSILON_2 1e-12 - -#define yes_OPTIMIZE_INNER - -/* Render an arc segment starting at (xc + x0, yc + y0) to (xc + x1, - yc + y1), centered at (xc, yc), and with given radius. Both x0^2 + - y0^2 and x1^2 + y1^2 should be equal to radius^2. - - A positive value of radius means curve to the left, negative means - curve to the right. -*/ -static void -art_svp_vpath_stroke_arc (ArtVpath **p_vpath, gint *pn, gint *pn_max, - gdouble xc, gdouble yc, - gdouble x0, gdouble y0, - gdouble x1, gdouble y1, - gdouble radius, - gdouble flatness) -{ - gdouble theta; - gdouble th_0, th_1; - gint n_pts; - gint i; - gdouble aradius; - - aradius = fabs (radius); - theta = 2 * M_SQRT2 * sqrt (flatness / aradius); - th_0 = atan2 (y0, x0); - th_1 = atan2 (y1, x1); - if (radius > 0) - { - /* curve to the left */ - if (th_0 < th_1) th_0 += M_PI * 2; - n_pts = ceil ((th_0 - th_1) / theta); - } - else - { - /* curve to the right */ - if (th_1 < th_0) th_1 += M_PI * 2; - n_pts = ceil ((th_1 - th_0) / theta); - } - art_vpath_add_point (p_vpath, pn, pn_max, - ART_LINETO, xc + x0, yc + y0); - for (i = 1; i < n_pts; i++) - { - theta = th_0 + (th_1 - th_0) * i / n_pts; - art_vpath_add_point (p_vpath, pn, pn_max, - ART_LINETO, xc + cos (theta) * aradius, - yc + sin (theta) * aradius); - } - art_vpath_add_point (p_vpath, pn, pn_max, - ART_LINETO, xc + x1, yc + y1); -} - -/* Assume that forw and rev are at point i0. Bring them to i1, - joining with the vector i1 - i2. - - This used to be true, but isn't now that the stroke_raw code is - filtering out (near)zero length vectors: {It so happens that all - invocations of this function maintain the precondition i1 = i0 + 1, - so we could decrease the number of arguments by one. We haven't - done that here, though.} - - forw is to the line's right and rev is to its left. - - Precondition: no zero-length vectors, otherwise a divide by - zero will happen. */ -static void -render_seg (ArtVpath **p_forw, gint *pn_forw, gint *pn_forw_max, - ArtVpath **p_rev, gint *pn_rev, gint *pn_rev_max, - ArtVpath *vpath, gint i0, gint i1, gint i2, - ArtPathStrokeJoinType join, - gdouble line_width, gdouble miter_limit, gdouble flatness) -{ - gdouble dx0, dy0; - gdouble dx1, dy1; - gdouble dlx0, dly0; - gdouble dlx1, dly1; - gdouble dmx, dmy; - gdouble dmr2; - gdouble scale; - gdouble cross; - - /* The vectors of the lines from i0 to i1 and i1 to i2. */ - dx0 = vpath[i1].x - vpath[i0].x; - dy0 = vpath[i1].y - vpath[i0].y; - - dx1 = vpath[i2].x - vpath[i1].x; - dy1 = vpath[i2].y - vpath[i1].y; - - /* Set dl[xy]0 to the vector from i0 to i1, rotated counterclockwise - 90 degrees, and scaled to the length of line_width. */ - scale = line_width / sqrt (dx0 * dx0 + dy0 * dy0); - dlx0 = dy0 * scale; - dly0 = -dx0 * scale; - - /* Set dl[xy]1 to the vector from i1 to i2, rotated counterclockwise - 90 degrees, and scaled to the length of line_width. */ - scale = line_width / sqrt (dx1 * dx1 + dy1 * dy1); - dlx1 = dy1 * scale; - dly1 = -dx1 * scale; - - /* now, forw's last point is expected to be colinear along d[xy]0 - to point i0 - dl[xy]0, and rev with i0 + dl[xy]0. */ - - /* positive for positive area (i.e. left turn) */ - cross = dx1 * dy0 - dx0 * dy1; - - dmx = (dlx0 + dlx1) * 0.5; - dmy = (dly0 + dly1) * 0.5; - dmr2 = dmx * dmx + dmy * dmy; - - if (join == ART_PATH_STROKE_JOIN_MITER && - dmr2 * miter_limit * miter_limit < line_width * line_width) - join = ART_PATH_STROKE_JOIN_BEVEL; - - /* the case when dmr2 is zero or very small bothers me - (i.e. near a 180 degree angle) - ALEX: So, we avoid the optimization when dmr2 is very small. This should - be safe since dmx/y is only used in optimization and in MITER case, and MITER - should be converted to BEVEL when dmr2 is very small. */ - if (dmr2 > EPSILON_2) - { - scale = line_width * line_width / dmr2; - dmx *= scale; - dmy *= scale; - } - - if (cross * cross < EPSILON_2 && dx0 * dx1 + dy0 * dy1 >= 0) - { - /* going straight */ - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x - dlx0, vpath[i1].y - dly0); - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x + dlx0, vpath[i1].y + dly0); - } - else if (cross > 0) - { - /* left turn, forw is outside and rev is inside */ - - if ( -#ifdef NO_OPTIMIZE_INNER - 0 && -#endif - (dmr2 > EPSILON_2) && - /* check that i1 + dm[xy] is inside i0-i1 rectangle */ - (dx0 + dmx) * dx0 + (dy0 + dmy) * dy0 > 0 && - /* and that i1 + dm[xy] is inside i1-i2 rectangle */ - ((dx1 - dmx) * dx1 + (dy1 - dmy) * dy1 > 0) -#ifdef PEDANTIC_INNER - && - /* check that i1 + dl[xy]1 is inside i0-i1 rectangle */ - (dx0 + dlx1) * dx0 + (dy0 + dly1) * dy0 > 0 && - /* and that i1 + dl[xy]0 is inside i1-i2 rectangle */ - ((dx1 - dlx0) * dx1 + (dy1 - dly0) * dy1 > 0) -#endif - ) - { - /* can safely add single intersection point */ - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x + dmx, vpath[i1].y + dmy); - } - else - { - /* need to loop-de-loop the inside */ - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x + dlx0, vpath[i1].y + dly0); - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x, vpath[i1].y); - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x + dlx1, vpath[i1].y + dly1); - } - - if (join == ART_PATH_STROKE_JOIN_BEVEL) - { - /* bevel */ - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x - dlx0, vpath[i1].y - dly0); - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x - dlx1, vpath[i1].y - dly1); - } - else if (join == ART_PATH_STROKE_JOIN_MITER) - { - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x - dmx, vpath[i1].y - dmy); - } - else if (join == ART_PATH_STROKE_JOIN_ROUND) - art_svp_vpath_stroke_arc (p_forw, pn_forw, pn_forw_max, - vpath[i1].x, vpath[i1].y, - -dlx0, -dly0, - -dlx1, -dly1, - line_width, - flatness); - } - else - { - /* right turn, rev is outside and forw is inside */ - - if ( -#ifdef NO_OPTIMIZE_INNER - 0 && -#endif - (dmr2 > EPSILON_2) && - /* check that i1 - dm[xy] is inside i0-i1 rectangle */ - (dx0 - dmx) * dx0 + (dy0 - dmy) * dy0 > 0 && - /* and that i1 - dm[xy] is inside i1-i2 rectangle */ - ((dx1 + dmx) * dx1 + (dy1 + dmy) * dy1 > 0) -#ifdef PEDANTIC_INNER - && - /* check that i1 - dl[xy]1 is inside i0-i1 rectangle */ - (dx0 - dlx1) * dx0 + (dy0 - dly1) * dy0 > 0 && - /* and that i1 - dl[xy]0 is inside i1-i2 rectangle */ - ((dx1 + dlx0) * dx1 + (dy1 + dly0) * dy1 > 0) -#endif - ) - { - /* can safely add single intersection point */ - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x - dmx, vpath[i1].y - dmy); - } - else - { - /* need to loop-de-loop the inside */ - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x - dlx0, vpath[i1].y - dly0); - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x, vpath[i1].y); - art_vpath_add_point (p_forw, pn_forw, pn_forw_max, - ART_LINETO, vpath[i1].x - dlx1, vpath[i1].y - dly1); - } - - if (join == ART_PATH_STROKE_JOIN_BEVEL) - { - /* bevel */ - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x + dlx0, vpath[i1].y + dly0); - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x + dlx1, vpath[i1].y + dly1); - } - else if (join == ART_PATH_STROKE_JOIN_MITER) - { - art_vpath_add_point (p_rev, pn_rev, pn_rev_max, - ART_LINETO, vpath[i1].x + dmx, vpath[i1].y + dmy); - } - else if (join == ART_PATH_STROKE_JOIN_ROUND) - art_svp_vpath_stroke_arc (p_rev, pn_rev, pn_rev_max, - vpath[i1].x, vpath[i1].y, - dlx0, dly0, - dlx1, dly1, - -line_width, - flatness); - - } -} - -/* caps i1, under the assumption of a vector from i0 */ -static void -render_cap (ArtVpath **p_result, gint *pn_result, gint *pn_result_max, - ArtVpath *vpath, gint i0, gint i1, - ArtPathStrokeCapType cap, gdouble line_width, gdouble flatness) -{ - gdouble dx0, dy0; - gdouble dlx0, dly0; - gdouble scale; - gint n_pts; - gint i; - - dx0 = vpath[i1].x - vpath[i0].x; - dy0 = vpath[i1].y - vpath[i0].y; - - /* Set dl[xy]0 to the vector from i0 to i1, rotated counterclockwise - 90 degrees, and scaled to the length of line_width. */ - scale = line_width / sqrt (dx0 * dx0 + dy0 * dy0); - dlx0 = dy0 * scale; - dly0 = -dx0 * scale; - - switch (cap) - { - case ART_PATH_STROKE_CAP_BUTT: - art_vpath_add_point (p_result, pn_result, pn_result_max, - ART_LINETO, vpath[i1].x - dlx0, vpath[i1].y - dly0); - art_vpath_add_point (p_result, pn_result, pn_result_max, - ART_LINETO, vpath[i1].x + dlx0, vpath[i1].y + dly0); - break; - case ART_PATH_STROKE_CAP_ROUND: - n_pts = ceil (M_PI / (2.0 * M_SQRT2 * sqrt (flatness / line_width))); - art_vpath_add_point (p_result, pn_result, pn_result_max, - ART_LINETO, vpath[i1].x - dlx0, vpath[i1].y - dly0); - for (i = 1; i < n_pts; i++) - { - gdouble theta, c_th, s_th; - - theta = M_PI * i / n_pts; - c_th = cos (theta); - s_th = sin (theta); - art_vpath_add_point (p_result, pn_result, pn_result_max, - ART_LINETO, - vpath[i1].x - dlx0 * c_th - dly0 * s_th, - vpath[i1].y - dly0 * c_th + dlx0 * s_th); - } - art_vpath_add_point (p_result, pn_result, pn_result_max, - ART_LINETO, vpath[i1].x + dlx0, vpath[i1].y + dly0); - break; - case ART_PATH_STROKE_CAP_SQUARE: - art_vpath_add_point (p_result, pn_result, pn_result_max, - ART_LINETO, - vpath[i1].x - dlx0 - dly0, - vpath[i1].y - dly0 + dlx0); - art_vpath_add_point (p_result, pn_result, pn_result_max, - ART_LINETO, - vpath[i1].x + dlx0 - dly0, - vpath[i1].y + dly0 + dlx0); - break; - } -} - -/** - * art_svp_from_vpath_raw: Stroke a vector path, raw version - * @vpath: #ArtVPath to stroke. - * @join: Join style. - * @cap: Cap style. - * @line_width: Width of stroke. - * @miter_limit: Miter limit. - * @flatness: Flatness. - * - * Exactly the same as art_svp_vpath_stroke(), except that the resulting - * stroke outline may self-intersect and have regions of winding number - * greater than 1. - * - * Return value: Resulting raw stroked outline in svp format. - **/ -ArtVpath * -art_svp_vpath_stroke_raw (ArtVpath *vpath, - ArtPathStrokeJoinType join, - ArtPathStrokeCapType cap, - gdouble line_width, - gdouble miter_limit, - gdouble flatness) -{ - gint begin_idx, end_idx; - gint i; - ArtVpath *forw, *rev; - gint n_forw, n_rev; - gint n_forw_max, n_rev_max; - ArtVpath *result; - gint n_result, n_result_max; - gdouble half_lw = 0.5 * line_width; - gint closed; - gint last, this, next, second; - gdouble dx, dy; - - n_forw_max = 16; - forw = art_new (ArtVpath, n_forw_max); - - n_rev_max = 16; - rev = art_new (ArtVpath, n_rev_max); - - n_result = 0; - n_result_max = 16; - result = art_new (ArtVpath, n_result_max); - - for (begin_idx = 0; vpath[begin_idx].code != ART_END; begin_idx = end_idx) - { - n_forw = 0; - n_rev = 0; - - closed = (vpath[begin_idx].code == ART_MOVETO); - - /* we don't know what the first point joins with until we get to the - last point and see if it's closed. So we start with the second - line in the path. - - Note: this is not strictly true (we now know it's closed from - the opening pathcode), but why fix code that isn't broken? - */ - - this = begin_idx; - /* skip over identical points at the beginning of the subpath */ - for (i = this + 1; vpath[i].code == ART_LINETO; i++) - { - dx = vpath[i].x - vpath[this].x; - dy = vpath[i].y - vpath[this].y; - if (dx * dx + dy * dy > EPSILON_2) - break; - } - next = i; - second = next; - - /* invariant: this doesn't coincide with next */ - while (vpath[next].code == ART_LINETO) - { - last = this; - this = next; - /* skip over identical points after the beginning of the subpath */ - for (i = this + 1; vpath[i].code == ART_LINETO; i++) - { - dx = vpath[i].x - vpath[this].x; - dy = vpath[i].y - vpath[this].y; - if (dx * dx + dy * dy > EPSILON_2) - break; - } - next = i; - if (vpath[next].code != ART_LINETO) - { - /* reached end of path */ - /* make "closed" detection conform to PostScript - semantics (i.e. explicit closepath code rather than - just the fact that end of the path is the beginning) */ - if (closed && - vpath[this].x == vpath[begin_idx].x && - vpath[this].y == vpath[begin_idx].y) - { - gint j; - - /* path is closed, render join to beginning */ - render_seg (&forw, &n_forw, &n_forw_max, - &rev, &n_rev, &n_rev_max, - vpath, last, this, second, - join, half_lw, miter_limit, flatness); - - /* do forward path */ - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_MOVETO, forw[n_forw - 1].x, - forw[n_forw - 1].y); - for (j = 0; j < n_forw; j++) - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_LINETO, forw[j].x, - forw[j].y); - - /* do reverse path, reversed */ - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_MOVETO, rev[0].x, - rev[0].y); - for (j = n_rev - 1; j >= 0; j--) - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_LINETO, rev[j].x, - rev[j].y); - } - else - { - /* path is open */ - gint j; - - /* add to forw rather than result to ensure that - forw has at least one point. */ - render_cap (&forw, &n_forw, &n_forw_max, - vpath, last, this, - cap, half_lw, flatness); - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_MOVETO, forw[0].x, - forw[0].y); - for (j = 1; j < n_forw; j++) - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_LINETO, forw[j].x, - forw[j].y); - for (j = n_rev - 1; j >= 0; j--) - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_LINETO, rev[j].x, - rev[j].y); - render_cap (&result, &n_result, &n_result_max, - vpath, second, begin_idx, - cap, half_lw, flatness); - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_LINETO, forw[0].x, - forw[0].y); - } - } - else - render_seg (&forw, &n_forw, &n_forw_max, - &rev, &n_rev, &n_rev_max, - vpath, last, this, next, - join, half_lw, miter_limit, flatness); - } - end_idx = next; - } - - art_free (forw); - art_free (rev); - art_vpath_add_point (&result, &n_result, &n_result_max, ART_END, 0, 0); - return result; -} - -/* Render a vector path into a stroked outline. - - Status of this routine: - - Basic correctness: Only miter and bevel line joins are implemented, - and only butt line caps. Otherwise, seems to be fine. - - Numerical stability: We cheat (adding random perturbation). Thus, - it seems very likely that no numerical stability problems will be - seen in practice. - - Speed: Should be pretty good. - - Precision: The perturbation fuzzes the coordinates slightly, - but not enough to be visible. */ -/** - * art_svp_vpath_stroke: Stroke a vector path. - * @vpath: #ArtVPath to stroke. - * @join: Join style. - * @cap: Cap style. - * @line_width: Width of stroke. - * @miter_limit: Miter limit. - * @flatness: Flatness. - * - * Computes an svp representing the stroked outline of @vpath. The - * width of the stroked line is @line_width. - * - * Lines are joined according to the @join rule. Possible values are - * ART_PATH_STROKE_JOIN_MITER (for mitered joins), - * ART_PATH_STROKE_JOIN_ROUND (for round joins), and - * ART_PATH_STROKE_JOIN_BEVEL (for bevelled joins). The mitered join - * is converted to a bevelled join if the miter would extend to a - * distance of more than @miter_limit * @line_width from the actual - * join point. - * - * If there are open subpaths, the ends of these subpaths are capped - * according to the @cap rule. Possible values are - * ART_PATH_STROKE_CAP_BUTT (squared cap, extends exactly to end - * point), ART_PATH_STROKE_CAP_ROUND (rounded half-circle centered at - * the end point), and ART_PATH_STROKE_CAP_SQUARE (squared cap, - * extending half @line_width past the end point). - * - * The @flatness parameter controls the accuracy of the rendering. It - * is most important for determining the number of points to use to - * approximate circular arcs for round lines and joins. In general, the - * resulting vector path will be within @flatness pixels of the "ideal" - * path containing actual circular arcs. I reserve the right to use - * the @flatness parameter to convert bevelled joins to miters for very - * small turn angles, as this would reduce the number of points in the - * resulting outline path. - * - * The resulting path is "clean" with respect to self-intersections, i.e. - * the winding number is 0 or 1 at each point. - * - * Return value: Resulting stroked outline in svp format. - **/ -ArtSVP * -art_svp_vpath_stroke (ArtVpath *vpath, - ArtPathStrokeJoinType join, - ArtPathStrokeCapType cap, - gdouble line_width, - gdouble miter_limit, - gdouble flatness) -{ -#ifdef ART_USE_NEW_INTERSECTOR - ArtVpath *vpath_stroke; - ArtSVP *svp, *svp2; - ArtSvpWriter *swr; - - vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap, - line_width, miter_limit, flatness); - svp = art_svp_from_vpath (vpath_stroke); - art_free (vpath_stroke); - - swr = art_svp_writer_rewind_new (ART_WIND_RULE_NONZERO); - art_svp_intersector (svp, swr); - - svp2 = art_svp_writer_rewind_reap (swr); - art_svp_free (svp); - return svp2; -#else - ArtVpath *vpath_stroke, *vpath2; - ArtSVP *svp, *svp2, *svp3; - - vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap, - line_width, miter_limit, flatness); - vpath2 = art_vpath_perturb (vpath_stroke); - art_free (vpath_stroke); - svp = art_svp_from_vpath (vpath2); - art_free (vpath2); - svp2 = art_svp_uncross (svp); - art_svp_free (svp); - svp3 = art_svp_rewind_uncrossed (svp2, ART_WIND_RULE_NONZERO); - art_svp_free (svp2); - - return svp3; -#endif -} diff --git a/libart_lgpl/art_svp_vpath_stroke.h b/libart_lgpl/art_svp_vpath_stroke.h deleted file mode 100644 index f945d7cba9..0000000000 --- a/libart_lgpl/art_svp_vpath_stroke.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_VPATH_STROKE_H__ -#define __ART_SVP_VPATH_STROKE_H__ - -/* Sort vector paths into sorted vector paths. */ - -#include <libart_lgpl/art_svp.h> -#include <libart_lgpl/art_vpath.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef enum { - ART_PATH_STROKE_JOIN_MITER, - ART_PATH_STROKE_JOIN_ROUND, - ART_PATH_STROKE_JOIN_BEVEL -} ArtPathStrokeJoinType; - -typedef enum { - ART_PATH_STROKE_CAP_BUTT, - ART_PATH_STROKE_CAP_ROUND, - ART_PATH_STROKE_CAP_SQUARE -} ArtPathStrokeCapType; - -ArtSVP * -art_svp_vpath_stroke (ArtVpath *vpath, - ArtPathStrokeJoinType join, - ArtPathStrokeCapType cap, - gdouble line_width, - gdouble miter_limit, - gdouble flatness); - -/* This version may have winding numbers exceeding 1. */ -ArtVpath * -art_svp_vpath_stroke_raw (ArtVpath *vpath, - ArtPathStrokeJoinType join, - ArtPathStrokeCapType cap, - gdouble line_width, - gdouble miter_limit, - gdouble flatness); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_VPATH_STROKE_H__ */ diff --git a/libart_lgpl/art_svp_wind.h b/libart_lgpl/art_svp_wind.h deleted file mode 100644 index fd999b4bb9..0000000000 --- a/libart_lgpl/art_svp_wind.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_SVP_WIND_H__ -#define __ART_SVP_WIND_H__ - -/* Primitive intersection and winding number operations on sorted - vector paths. */ - -#include <libart_lgpl/art_svp.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef ART_WIND_RULE_DEFINED -#define ART_WIND_RULE_DEFINED -typedef enum { - ART_WIND_RULE_NONZERO, - ART_WIND_RULE_INTERSECT, - ART_WIND_RULE_ODDEVEN, - ART_WIND_RULE_POSITIVE -} ArtWindRule; -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_SVP_WIND_H__ */ diff --git a/libart_lgpl/art_uta.c b/libart_lgpl/art_uta.c deleted file mode 100644 index 138fd8b30c..0000000000 --- a/libart_lgpl/art_uta.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_uta.h" - -#include <string.h> -#include "art_misc.h" - -/** - * art_uta_new: Allocate a new uta. - * @x0: Left coordinate of uta. - * @y0: Top coordinate of uta. - * @x1: Right coordinate of uta. - * @y1: Bottom coordinate of uta. - * - * Allocates a new microtile array. The arguments are in units of - * tiles, not pixels. - * - * Returns: the newly allocated #ArtUta. - **/ -ArtUta * -art_uta_new (gint x0, gint y0, gint x1, gint y1) -{ - ArtUta *uta; - - uta = art_new (ArtUta, 1); - uta->x0 = x0; - uta->y0 = y0; - uta->width = x1 - x0; - uta->height = y1 - y0; - - uta->utiles = art_new (ArtUtaBbox, uta->width * uta->height); - - memset (uta->utiles, 0, uta->width * uta->height * sizeof (ArtUtaBbox)); - return uta; - } - -/** - * art_uta_new_coords: Allocate a new uta, based on pixel coordinates. - * @x0: Left coordinate of uta. - * @y0: Top coordinate of uta. - * @x1: Right coordinate of uta. - * @y1: Bottom coordinate of uta. - * - * Allocates a new microtile array. The arguments are in pixels - * - * Returns: the newly allocated #ArtUta. - **/ -ArtUta * -art_uta_new_coords (gint x0, gint y0, gint x1, gint y1) -{ - return art_uta_new (x0 >> ART_UTILE_SHIFT, y0 >> ART_UTILE_SHIFT, - 1 + (x1 >> ART_UTILE_SHIFT), - 1 + (y1 >> ART_UTILE_SHIFT)); -} - -/** - * art_uta_free: Free a uta. - * @uta: The uta to free. - * - * Frees the microtile array structure, including the actual microtile - * data. - **/ -void -art_uta_free (ArtUta *uta) -{ - art_free (uta->utiles); - art_free (uta); -} - -/* User to Aardvark! */ diff --git a/libart_lgpl/art_uta.h b/libart_lgpl/art_uta.h deleted file mode 100644 index 3101949bb2..0000000000 --- a/libart_lgpl/art_uta.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_UTA_H__ -#define __ART_UTA_H__ - -/* Basic data structures and constructors for microtile arrays */ - -#include <libart_lgpl/art_misc.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef art_u32 ArtUtaBbox; -typedef struct _ArtUta ArtUta; - -#define ART_UTA_BBOX_CONS(x0, y0, x1, y1) (((x0) << 24) | ((y0) << 16) | \ - ((x1) << 8) | (y1)) - -#define ART_UTA_BBOX_X0(ub) ((ub) >> 24) -#define ART_UTA_BBOX_Y0(ub) (((ub) >> 16) & 0xff) -#define ART_UTA_BBOX_X1(ub) (((ub) >> 8) & 0xff) -#define ART_UTA_BBOX_Y1(ub) ((ub) & 0xff) - -#define ART_UTILE_SHIFT 5 -#define ART_UTILE_SIZE (1 << ART_UTILE_SHIFT) - -/* Coordinates are shifted right by ART_UTILE_SHIFT wrt the real - coordinates. */ -struct _ArtUta { - gint x0; - gint y0; - gint width; - gint height; - ArtUtaBbox *utiles; -}; - -ArtUta * -art_uta_new (gint x0, gint y0, gint x1, gint y1); - -ArtUta * -art_uta_new_coords (gint x0, gint y0, gint x1, gint y1); - -void -art_uta_free (ArtUta *uta); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_UTA_H__ */ diff --git a/libart_lgpl/art_uta_rect.c b/libart_lgpl/art_uta_rect.c deleted file mode 100644 index d92cf691b5..0000000000 --- a/libart_lgpl/art_uta_rect.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_uta_rect.h" - -#include "art_misc.h" -#include "art_uta.h" -#include "art_rect.h" - -/** - * art_uta_from_irect: Generate uta covering a rectangle. - * @bbox: The source rectangle. - * - * Generates a uta exactly covering @bbox. Please do not call this - * function with a @bbox with zero height or width. - * - * Return value: the new uta. - **/ -ArtUta * -art_uta_from_irect (ArtIRect *bbox) -{ - ArtUta *uta; - ArtUtaBbox *utiles; - ArtUtaBbox bb; - gint width, height; - gint x, y; - gint xf0, yf0, xf1, yf1; - gint ix; - - uta = art_new (ArtUta, 1); - uta->x0 = bbox->x0 >> ART_UTILE_SHIFT; - uta->y0 = bbox->y0 >> ART_UTILE_SHIFT; - width = ((bbox->x1 + ART_UTILE_SIZE - 1) >> ART_UTILE_SHIFT) - uta->x0; - height = ((bbox->y1 + ART_UTILE_SIZE - 1) >> ART_UTILE_SHIFT) - uta->y0; - utiles = art_new (ArtUtaBbox, width * height); - - uta->width = width; - uta->height = height; - uta->utiles = utiles; - - xf0 = bbox->x0 & (ART_UTILE_SIZE - 1); - yf0 = bbox->y0 & (ART_UTILE_SIZE - 1); - xf1 = ((bbox->x1 - 1) & (ART_UTILE_SIZE - 1)) + 1; - yf1 = ((bbox->y1 - 1) & (ART_UTILE_SIZE - 1)) + 1; - if (height == 1) - { - if (width == 1) - utiles[0] = ART_UTA_BBOX_CONS (xf0, yf0, xf1, yf1); - else - { - utiles[0] = ART_UTA_BBOX_CONS (xf0, yf0, ART_UTILE_SIZE, yf1); - bb = ART_UTA_BBOX_CONS (0, yf0, ART_UTILE_SIZE, yf1); - for (x = 1; x < width - 1; x++) - utiles[x] = bb; - utiles[x] = ART_UTA_BBOX_CONS (0, yf0, xf1, yf1); - } - } - else - { - if (width == 1) - { - utiles[0] = ART_UTA_BBOX_CONS (xf0, yf0, xf1, ART_UTILE_SIZE); - bb = ART_UTA_BBOX_CONS (xf0, 0, xf1, ART_UTILE_SIZE); - for (y = 1; y < height - 1; y++) - utiles[y] = bb; - utiles[y] = ART_UTA_BBOX_CONS (xf0, 0, xf1, yf1); - } - else - { - utiles[0] = - ART_UTA_BBOX_CONS (xf0, yf0, ART_UTILE_SIZE, ART_UTILE_SIZE); - bb = ART_UTA_BBOX_CONS (0, yf0, ART_UTILE_SIZE, ART_UTILE_SIZE); - for (x = 1; x < width - 1; x++) - utiles[x] = bb; - utiles[x] = ART_UTA_BBOX_CONS (0, yf0, xf1, ART_UTILE_SIZE); - ix = width; - for (y = 1; y < height - 1; y++) - { - utiles[ix++] = - ART_UTA_BBOX_CONS (xf0, 0, ART_UTILE_SIZE, ART_UTILE_SIZE); - bb = ART_UTA_BBOX_CONS (0, 0, ART_UTILE_SIZE, ART_UTILE_SIZE); - for (x = 1; x < width - 1; x++) - utiles[ix++] = bb; - utiles[ix++] = ART_UTA_BBOX_CONS (0, 0, xf1, ART_UTILE_SIZE); - } - utiles[ix++] = ART_UTA_BBOX_CONS (xf0, 0, ART_UTILE_SIZE, yf1); - bb = ART_UTA_BBOX_CONS (0, 0, ART_UTILE_SIZE, yf1); - for (x = 1; x < width - 1; x++) - utiles[ix++] = bb; - utiles[ix++] = ART_UTA_BBOX_CONS (0, 0, xf1, yf1); - } - } - return uta; -} diff --git a/libart_lgpl/art_uta_rect.h b/libart_lgpl/art_uta_rect.h deleted file mode 100644 index cf726d81da..0000000000 --- a/libart_lgpl/art_uta_rect.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_UTA_RECT_H__ -#define __ART_UTA_RECT_H__ - -#include <libart_lgpl/art_rect.h> -#include <libart_lgpl/art_uta.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -ArtUta * -art_uta_from_irect (ArtIRect *bbox); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_UTA_RECT_H__ */ diff --git a/libart_lgpl/art_uta_svp.c b/libart_lgpl/art_uta_svp.c deleted file mode 100644 index 2a0f37250e..0000000000 --- a/libart_lgpl/art_uta_svp.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* LGPL Copyright 1998 Raph Levien <raph@acm.org> */ - -#include "config.h" -#include "art_uta_svp.h" - -#include "art_misc.h" -#include "art_vpath.h" -#include "art_uta.h" -#include "art_uta_vpath.h" -#include "art_svp.h" -#include "art_vpath_svp.h" - -/** - * art_uta_from_svp: Generate uta covering an svp. - * @svp: The source svp. - * - * Generates a uta covering @svp. The resulting uta is of course - * approximate, ie it may cover more pixels than covered by @svp. - * - * Note: I will want to replace this with a more direct - * implementation. But this gets the api in place. - * - * Return value: the new uta. - **/ -ArtUta * -art_uta_from_svp (const ArtSVP *svp) -{ - ArtVpath *vpath; - ArtUta *uta; - - vpath = art_vpath_from_svp (svp); - uta = art_uta_from_vpath (vpath); - art_free (vpath); - return uta; -} diff --git a/libart_lgpl/art_uta_svp.h b/libart_lgpl/art_uta_svp.h deleted file mode 100644 index 0d2d489cb0..0000000000 --- a/libart_lgpl/art_uta_svp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_UTA_SVP_H__ -#define __ART_UTA_SVP_H__ - -/* Basic data structures and constructors for microtile arrays */ - -#include <libart_lgpl/art_svp.h> -#include <libart_lgpl/art_uta.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -ArtUta * -art_uta_from_svp (const ArtSVP *svp); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_UTA_SVP_H__ */ - diff --git a/libart_lgpl/art_uta_vpath.c b/libart_lgpl/art_uta_vpath.c deleted file mode 100644 index 841b9614d2..0000000000 --- a/libart_lgpl/art_uta_vpath.c +++ /dev/null @@ -1,376 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include "art_uta_vpath.h" - -#include <math.h> - -#include "art_misc.h" -#include "art_vpath.h" -#include "art_uta.h" - -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif /* MAX */ - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif /* MIN */ - -/** - * art_uta_add_line: Add a line to the uta. - * @uta: The uta to modify. - * @x0: X coordinate of line start point. - * @y0: Y coordinate of line start point. - * @x1: X coordinate of line end point. - * @y1: Y coordinate of line end point. - * @rbuf: Buffer containing first difference of winding number. - * @rbuf_rowstride: Rowstride of @rbuf. - * - * Add the line (@x0, @y0) - (@x1, @y1) to @uta, and also update the - * winding number buffer used for rendering the interior. @rbuf - * contains the first partial difference (in the X direction) of the - * winding number, measured in grid cells. Thus, each time that a line - * crosses a horizontal uta grid line, an entry of @rbuf is - * incremented if @y1 > @y0, decremented otherwise. - * - * Note that edge handling is fairly delicate. Please rtfs for - * details. - **/ -void -art_uta_add_line (ArtUta *uta, gdouble x0, gdouble y0, gdouble x1, gdouble y1, - gint *rbuf, gint rbuf_rowstride) -{ - gint xmin, ymin; - gdouble xmax, ymax; - gint xmaxf, ymaxf; - gint xmaxc, ymaxc; - gint xt0, yt0; - gint xt1, yt1; - gint xf0, yf0; - gint xf1, yf1; - gint ix, ix1; - ArtUtaBbox bb; - - xmin = floor (MIN (x0, x1)); - xmax = MAX (x0, x1); - xmaxf = floor (xmax); - xmaxc = ceil (xmax); - ymin = floor (MIN (y0, y1)); - ymax = MAX (y0, y1); - ymaxf = floor (ymax); - ymaxc = ceil (ymax); - xt0 = (xmin >> ART_UTILE_SHIFT) - uta->x0; - yt0 = (ymin >> ART_UTILE_SHIFT) - uta->y0; - xt1 = (xmaxf >> ART_UTILE_SHIFT) - uta->x0; - yt1 = (ymaxf >> ART_UTILE_SHIFT) - uta->y0; - if (xt0 == xt1 && yt0 == yt1) - { - /* entirely inside a microtile, this is easy! */ - xf0 = xmin & (ART_UTILE_SIZE - 1); - yf0 = ymin & (ART_UTILE_SIZE - 1); - xf1 = (xmaxf & (ART_UTILE_SIZE - 1)) + xmaxc - xmaxf; - yf1 = (ymaxf & (ART_UTILE_SIZE - 1)) + ymaxc - ymaxf; - - ix = yt0 * uta->width + xt0; - bb = uta->utiles[ix]; - if (bb == 0) - bb = ART_UTA_BBOX_CONS (xf0, yf0, xf1, yf1); - else - bb = ART_UTA_BBOX_CONS (MIN (ART_UTA_BBOX_X0 (bb), xf0), - MIN (ART_UTA_BBOX_Y0 (bb), yf0), - MAX (ART_UTA_BBOX_X1 (bb), xf1), - MAX (ART_UTA_BBOX_Y1 (bb), yf1)); - uta->utiles[ix] = bb; - } - else - { - gdouble dx, dy; - gint sx, sy; - - dx = x1 - x0; - dy = y1 - y0; - sx = dx > 0 ? 1 : dx < 0 ? -1 : 0; - sy = dy > 0 ? 1 : dy < 0 ? -1 : 0; - if (ymin == ymaxf) - { - /* special case horizontal (dx/dy slope would be infinite) */ - xf0 = xmin & (ART_UTILE_SIZE - 1); - yf0 = ymin & (ART_UTILE_SIZE - 1); - xf1 = (xmaxf & (ART_UTILE_SIZE - 1)) + xmaxc - xmaxf; - yf1 = (ymaxf & (ART_UTILE_SIZE - 1)) + ymaxc - ymaxf; - - ix = yt0 * uta->width + xt0; - ix1 = yt0 * uta->width + xt1; - while (ix != ix1) - { - bb = uta->utiles[ix]; - if (bb == 0) - bb = ART_UTA_BBOX_CONS (xf0, yf0, ART_UTILE_SIZE, yf1); - else - bb = ART_UTA_BBOX_CONS (MIN (ART_UTA_BBOX_X0 (bb), xf0), - MIN (ART_UTA_BBOX_Y0 (bb), yf0), - ART_UTILE_SIZE, - MAX (ART_UTA_BBOX_Y1 (bb), yf1)); - uta->utiles[ix] = bb; - xf0 = 0; - ix++; - } - bb = uta->utiles[ix]; - if (bb == 0) - bb = ART_UTA_BBOX_CONS (0, yf0, xf1, yf1); - else - bb = ART_UTA_BBOX_CONS (0, - MIN (ART_UTA_BBOX_Y0 (bb), yf0), - MAX (ART_UTA_BBOX_X1 (bb), xf1), - MAX (ART_UTA_BBOX_Y1 (bb), yf1)); - uta->utiles[ix] = bb; - } - else - { - /* Do a Bresenham-style traversal of the line */ - gdouble dx_dy; - gdouble x, y; - gdouble xn, yn; - - /* normalize coordinates to uta origin */ - x0 -= uta->x0 << ART_UTILE_SHIFT; - y0 -= uta->y0 << ART_UTILE_SHIFT; - x1 -= uta->x0 << ART_UTILE_SHIFT; - y1 -= uta->y0 << ART_UTILE_SHIFT; - if (dy < 0) - { - gdouble tmp; - - tmp = x0; - x0 = x1; - x1 = tmp; - - tmp = y0; - y0 = y1; - y1 = tmp; - - dx = -dx; - sx = -sx; - dy = -dy; - /* we leave sy alone, because it would always be 1, - and we need it for the rbuf stuff. */ - } - xt0 = ((gint)floor (x0) >> ART_UTILE_SHIFT); - xt1 = ((gint)floor (x1) >> ART_UTILE_SHIFT); - /* now [xy]0 is above [xy]1 */ - - ix = yt0 * uta->width + xt0; - ix1 = yt1 * uta->width + xt1; - - dx_dy = dx / dy; - x = x0; - y = y0; - while (ix != ix1) - { - gint dix; - - /* figure out whether next crossing is horizontal or vertical */ - yn = (yt0 + 1) << ART_UTILE_SHIFT; - - /* xn is the intercept with bottom edge of this tile. The - following expression is careful to result in exactly - x1 when yn = y1. */ - xn = x1 + dx_dy * (yn - y1); - - if (xt0 != (gint)floor (xn) >> ART_UTILE_SHIFT) - { - /* horizontal crossing */ - xt0 += sx; - dix = sx; - if (dx > 0) - { - xn = xt0 << ART_UTILE_SHIFT; - yn = y0 + (xn - x0) / dx_dy; - - xf0 = (gint)floor (x) & (ART_UTILE_SIZE - 1); - xf1 = ART_UTILE_SIZE; - } - else - { - xn = (xt0 + 1) << ART_UTILE_SHIFT; - yn = y0 + (xn - x0) / dx_dy; - - xf0 = 0; - xmaxc = (gint)ceil (x); - xf1 = xmaxc - ((xt0 + 1) << ART_UTILE_SHIFT); - } - ymaxf = (gint)floor (yn); - ymaxc = (gint)ceil (yn); - yf1 = (ymaxf & (ART_UTILE_SIZE - 1)) + ymaxc - ymaxf; - } - else - { - /* vertical crossing */ - dix = uta->width; - xf0 = (gint)floor (MIN (x, xn)) & (ART_UTILE_SIZE - 1); - xmax = MAX (x, xn); - xmaxc = (gint)ceil (xmax); - xf1 = xmaxc - (xt0 << ART_UTILE_SHIFT); - yf1 = ART_UTILE_SIZE; - - if (rbuf != NULL) - rbuf[yt0 * rbuf_rowstride + xt0] += sy; - - yt0++; - } - yf0 = (gint)floor (y) & (ART_UTILE_SIZE - 1); - bb = uta->utiles[ix]; - if (bb == 0) - bb = ART_UTA_BBOX_CONS (xf0, yf0, xf1, yf1); - else - bb = ART_UTA_BBOX_CONS (MIN (ART_UTA_BBOX_X0 (bb), xf0), - MIN (ART_UTA_BBOX_Y0 (bb), yf0), - MAX (ART_UTA_BBOX_X1 (bb), xf1), - MAX (ART_UTA_BBOX_Y1 (bb), yf1)); - uta->utiles[ix] = bb; - - x = xn; - y = yn; - ix += dix; - } - xmax = MAX (x, x1); - xmaxc = ceil (xmax); - ymaxc = ceil (y1); - xf0 = (gint)floor (MIN (x1, x)) & (ART_UTILE_SIZE - 1); - yf0 = (gint)floor (y) & (ART_UTILE_SIZE - 1); - xf1 = xmaxc - (xt0 << ART_UTILE_SHIFT); - yf1 = ymaxc - (yt0 << ART_UTILE_SHIFT); - bb = uta->utiles[ix]; - if (bb == 0) - bb = ART_UTA_BBOX_CONS (xf0, yf0, xf1, yf1); - else - bb = ART_UTA_BBOX_CONS (MIN (ART_UTA_BBOX_X0 (bb), xf0), - MIN (ART_UTA_BBOX_Y0 (bb), yf0), - MAX (ART_UTA_BBOX_X1 (bb), xf1), - MAX (ART_UTA_BBOX_Y1 (bb), yf1)); - uta->utiles[ix] = bb; - } - } -} - -/** - * art_uta_from_vpath: Generate uta covering a vpath. - * @vec: The source vpath. - * - * Generates a uta covering @vec. The resulting uta is of course - * approximate, ie it may cover more pixels than covered by @vec. - * - * Return value: the new uta. - **/ -ArtUta * -art_uta_from_vpath (const ArtVpath *vec) -{ - ArtUta *uta; - ArtIRect bbox; - gint *rbuf; - gint i; - gdouble x, y; - gint sum; - gint xt, yt; - ArtUtaBbox *utiles; - ArtUtaBbox bb; - gint width; - gint height; - gint ix; - - art_vpath_bbox_irect (vec, &bbox); - - uta = art_uta_new_coords (bbox.x0, bbox.y0, bbox.x1, bbox.y1); - - width = uta->width; - height = uta->height; - utiles = uta->utiles; - - rbuf = art_new (int, width * height); - for (i = 0; i < width * height; i++) - rbuf[i] = 0; - - x = 0; - y = 0; - for (i = 0; vec[i].code != ART_END; i++) - { - switch (vec[i].code) - { - case ART_MOVETO: - x = vec[i].x; - y = vec[i].y; - break; - case ART_LINETO: - art_uta_add_line (uta, vec[i].x, vec[i].y, x, y, rbuf, width); - x = vec[i].x; - y = vec[i].y; - break; - default: - /* this shouldn't happen */ - art_free (rbuf); - art_free (uta); - return NULL; - } - } - - /* now add in the filling from rbuf */ - ix = 0; - for (yt = 0; yt < height; yt++) - { - sum = 0; - for (xt = 0; xt < width; xt++) - { - sum += rbuf[ix]; - /* Nonzero winding rule - others are possible, but hardly - worth it. */ - if (sum != 0) - { - bb = utiles[ix]; - bb &= 0xffff0000; - bb |= (ART_UTILE_SIZE << 8) | ART_UTILE_SIZE; - utiles[ix] = bb; - if (xt != width - 1) - { - bb = utiles[ix + 1]; - bb &= 0xffff00; - bb |= ART_UTILE_SIZE; - utiles[ix + 1] = bb; - } - if (yt != height - 1) - { - bb = utiles[ix + width]; - bb &= 0xff0000ff; - bb |= ART_UTILE_SIZE << 8; - utiles[ix + width] = bb; - if (xt != width - 1) - { - utiles[ix + width + 1] &= 0xffff; - } - } - } - ix++; - } - } - - art_free (rbuf); - - return uta; -} diff --git a/libart_lgpl/art_uta_vpath.h b/libart_lgpl/art_uta_vpath.h deleted file mode 100644 index 3f50e3a746..0000000000 --- a/libart_lgpl/art_uta_vpath.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_UTA_VPATH_H__ -#define __ART_UTA_VPATH_H__ - -/* Basic data structures and constructors for microtile arrays */ - -#include <libart_lgpl/art_uta.h> -#include <libart_lgpl/art_vpath.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -ArtUta * -art_uta_from_vpath (const ArtVpath *vec); - -/* This is a private function: */ -void -art_uta_add_line (ArtUta *uta, gdouble x0, gdouble y0, gdouble x1, gdouble y1, - gint *rbuf, gint rbuf_rowstride); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_UTA_VPATH_H__ */ - diff --git a/libart_lgpl/art_vpath.c b/libart_lgpl/art_vpath.c deleted file mode 100644 index 395917915b..0000000000 --- a/libart_lgpl/art_vpath.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Basic constructors and operations for vector paths */ - -#include "config.h" -#include "art_vpath.h" - -#include <math.h> -#include <stdlib.h> - -#include "art_misc.h" - -#include "art_rect.h" - -/** - * art_vpath_add_point: Add point to vpath. - * @p_vpath: Where the pointer to the #ArtVpath structure is stored. - * @pn_points: Pointer to the number of points in *@p_vpath. - * @pn_points_max: Pointer to the number of points allocated. - * @code: The pathcode for the new point. - * @x: The X coordinate of the new point. - * @y: The Y coordinate of the new point. - * - * Adds a new point to *@p_vpath, reallocating and updating *@p_vpath - * and *@pn_points_max as necessary. *@pn_points is incremented. - * - * This routine always adds the point after all points already in the - * vpath. Thus, it should be called in the order the points are - * desired. - **/ -void -art_vpath_add_point (ArtVpath **p_vpath, gint *pn_points, gint *pn_points_max, - ArtPathcode code, gdouble x, gdouble y) -{ - gint i; - - i = (*pn_points)++; - if (i == *pn_points_max) - art_expand (*p_vpath, ArtVpath, *pn_points_max); - (*p_vpath)[i].code = code; - (*p_vpath)[i].x = x; - (*p_vpath)[i].y = y; -} - -/** - * art_vpath_bbox_drect: Determine bounding box of vpath. - * @vec: Source vpath. - * @drect: Where to store bounding box. - * - * Determines bounding box of @vec, and stores it in @drect. - **/ -void -art_vpath_bbox_drect (const ArtVpath *vec, ArtDRect *drect) -{ - gint i; - gdouble x0, y0, x1, y1; - - if (vec[0].code == ART_END) - { - x0 = y0 = x1 = y1 = 0; - } - else - { - x0 = x1 = vec[0].x; - y0 = y1 = vec[0].y; - for (i = 1; vec[i].code != ART_END; i++) - { - if (vec[i].x < x0) x0 = vec[i].x; - if (vec[i].x > x1) x1 = vec[i].x; - if (vec[i].y < y0) y0 = vec[i].y; - if (vec[i].y > y1) y1 = vec[i].y; - } - } - drect->x0 = x0; - drect->y0 = y0; - drect->x1 = x1; - drect->y1 = y1; -} - -/** - * art_vpath_bbox_irect: Determine integer bounding box of vpath. - * @vec: Source vpath. - * idrect: Where to store bounding box. - * - * Determines integer bounding box of @vec, and stores it in @irect. - **/ -void -art_vpath_bbox_irect (const ArtVpath *vec, ArtIRect *irect) -{ - ArtDRect drect; - - art_vpath_bbox_drect (vec, &drect); - art_drect_to_irect (irect, &drect); -} - diff --git a/libart_lgpl/art_vpath.h b/libart_lgpl/art_vpath.h deleted file mode 100644 index 7dadd2865d..0000000000 --- a/libart_lgpl/art_vpath.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_VPATH_H__ -#define __ART_VPATH_H__ - -#include <libart_lgpl/art_rect.h> -#include <libart_lgpl/art_pathcode.h> - -/* Basic data structures and constructors for simple vector paths */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct _ArtVpath ArtVpath; - -/* CURVETO is not allowed! */ -struct _ArtVpath { - ArtPathcode code; - gdouble x; - gdouble y; -}; - -/* Some of the functions need to go into their own modules */ - -void -art_vpath_add_point (ArtVpath **p_vpath, gint *pn_points, gint *pn_points_max, - ArtPathcode code, gdouble x, gdouble y); - -void -art_vpath_bbox_drect (const ArtVpath *vec, ArtDRect *drect); - -void -art_vpath_bbox_irect (const ArtVpath *vec, ArtIRect *irect); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_VPATH_H__ */ diff --git a/libart_lgpl/art_vpath_bpath.c b/libart_lgpl/art_vpath_bpath.c deleted file mode 100644 index b662051e85..0000000000 --- a/libart_lgpl/art_vpath_bpath.c +++ /dev/null @@ -1,298 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Basic constructors and operations for bezier paths */ - -#include "config.h" -#include "art_vpath_bpath.h" - -#include <math.h> - -#include "art_misc.h" - -#include "art_bpath.h" -#include "art_vpath.h" - -/* p must be allocated 2^level points. */ - -/* level must be >= 1 */ -ArtPoint * -art_bezier_to_vec (gdouble x0, gdouble y0, - gdouble x1, gdouble y1, - gdouble x2, gdouble y2, - gdouble x3, gdouble y3, - ArtPoint *p, - gint level) -{ - gdouble x_m, y_m; - - if (level == 1) { - x_m = (x0 + 3 * (x1 + x2) + x3) * 0.125; - y_m = (y0 + 3 * (y1 + y2) + y3) * 0.125; - p->x = x_m; - p->y = y_m; - p++; - p->x = x3; - p->y = y3; - p++; - } else { - gdouble xa1, ya1; - gdouble xa2, ya2; - gdouble xb1, yb1; - gdouble xb2, yb2; - - xa1 = (x0 + x1) * 0.5; - ya1 = (y0 + y1) * 0.5; - xa2 = (x0 + 2 * x1 + x2) * 0.25; - ya2 = (y0 + 2 * y1 + y2) * 0.25; - xb1 = (x1 + 2 * x2 + x3) * 0.25; - yb1 = (y1 + 2 * y2 + y3) * 0.25; - xb2 = (x2 + x3) * 0.5; - yb2 = (y2 + y3) * 0.5; - x_m = (xa2 + xb1) * 0.5; - y_m = (ya2 + yb1) * 0.5; - p = art_bezier_to_vec (x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, p, level - 1); - p = art_bezier_to_vec (x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, p, level - 1); - } - return p; -} - -#define RENDER_LEVEL 4 -#define RENDER_SIZE (1 << (RENDER_LEVEL)) - -/** - * art_vpath_render_bez: Render a bezier segment into the vpath. - * @p_vpath: Where the pointer to the #ArtVpath structure is stored. - * @pn_points: Pointer to the number of points in *@p_vpath. - * @pn_points_max: Pointer to the number of points allocated. - * @x0: X coordinate of starting bezier point. - * @y0: Y coordinate of starting bezier point. - * @x1: X coordinate of first bezier control point. - * @y1: Y coordinate of first bezier control point. - * @x2: X coordinate of second bezier control point. - * @y2: Y coordinate of second bezier control point. - * @x3: X coordinate of ending bezier point. - * @y3: Y coordinate of ending bezier point. - * @flatness: Flatness control. - * - * Renders a bezier segment into the vector path, reallocating and - * updating *@p_vpath and *@pn_vpath_max as necessary. *@pn_vpath is - * incremented by the number of vector points added. - * - * This step includes (@x0, @y0) but not (@x3, @y3). - * - * The @flatness argument guides the amount of subdivision. The Adobe - * PostScript reference manual defines flatness as the maximum - * deviation between the any point on the vpath approximation and the - * corresponding point on the "true" curve, and we follow this - * definition here. A value of 0.25 should ensure high quality for aa - * rendering. -**/ -static void -art_vpath_render_bez (ArtVpath **p_vpath, gint *pn, gint *pn_max, - gdouble x0, gdouble y0, - gdouble x1, gdouble y1, - gdouble x2, gdouble y2, - gdouble x3, gdouble y3, - gdouble flatness) -{ - gdouble x3_0, y3_0; - gdouble z3_0_dot; - gdouble z1_dot, z2_dot; - gdouble z1_perp, z2_perp; - gdouble max_perp_sq; - - gdouble x_m, y_m; - gdouble xa1, ya1; - gdouble xa2, ya2; - gdouble xb1, yb1; - gdouble xb2, yb2; - - /* It's possible to optimize this routine a fair amount. - - First, once the _dot conditions are met, they will also be met in - all further subdivisions. So we might recurse to a different - routine that only checks the _perp conditions. - - Second, the distance _should_ decrease according to fairly - predictable rules (a factor of 4 with each subdivision). So it might - be possible to note that the distance is within a factor of 4 of - acceptable, and subdivide once. But proving this might be hard. - - Third, at the last subdivision, x_m and y_m can be computed more - expeditiously (as in the routine above). - - Finally, if we were able to subdivide by, say 2 or 3, this would - allow considerably finer-grain control, i.e. fewer points for the - same flatness tolerance. This would speed things up downstream. - - In any case, this routine is unlikely to be the bottleneck. It's - just that I have this undying quest for more speed... - - */ - - x3_0 = x3 - x0; - y3_0 = y3 - y0; - - /* z3_0_dot is dist z0-z3 squared */ - z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0; - - if (z3_0_dot < 0.001) - { - /* if start and end point are almost identical, the flatness tests - * don't work properly, so fall back on testing whether both of - * the other two control points are the same as the start point, - * too. - */ - if (hypot (x1 - x0, y1 - y0) < 0.001 - && hypot (x2 - x0, y2 - y0) < 0.001) - goto nosubdivide; - else - goto subdivide; - } - - /* we can avoid subdivision if: - - z1 has distance no more than flatness from the z0-z3 line - - z1 is no more z0'ward than flatness past z0-z3 - - z1 is more z0'ward than z3'ward on the line traversing z0-z3 - - and correspondingly for z2 */ - - /* perp is distance from line, multiplied by dist z0-z3 */ - max_perp_sq = flatness * flatness * z3_0_dot; - - z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0; - if (z1_perp * z1_perp > max_perp_sq) - goto subdivide; - - z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0; - if (z2_perp * z2_perp > max_perp_sq) - goto subdivide; - - z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0; - if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq) - goto subdivide; - - z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0; - if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq) - goto subdivide; - - if (z1_dot + z1_dot > z3_0_dot) - goto subdivide; - - if (z2_dot + z2_dot > z3_0_dot) - goto subdivide; - - nosubdivide: - /* don't subdivide */ - art_vpath_add_point (p_vpath, pn, pn_max, - ART_LINETO, x3, y3); - return; - - subdivide: - - xa1 = (x0 + x1) * 0.5; - ya1 = (y0 + y1) * 0.5; - xa2 = (x0 + 2 * x1 + x2) * 0.25; - ya2 = (y0 + 2 * y1 + y2) * 0.25; - xb1 = (x1 + 2 * x2 + x3) * 0.25; - yb1 = (y1 + 2 * y2 + y3) * 0.25; - xb2 = (x2 + x3) * 0.5; - yb2 = (y2 + y3) * 0.5; - x_m = (xa2 + xb1) * 0.5; - y_m = (ya2 + yb1) * 0.5; - art_vpath_render_bez (p_vpath, pn, pn_max, - x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, flatness); - art_vpath_render_bez (p_vpath, pn, pn_max, - x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, flatness); -} - -/** - * art_bez_path_to_vec: Create vpath from bezier path. - * @bez: Bezier path. - * @flatness: Flatness control. - * - * Creates a vector path closely approximating the bezier path defined by - * @bez. The @flatness argument controls the amount of subdivision. In - * general, the resulting vpath deviates by at most @flatness pixels - * from the "ideal" path described by @bez. - * - * Return value: Newly allocated vpath. - **/ -ArtVpath * -art_bez_path_to_vec (const ArtBpath *bez, gdouble flatness) -{ - ArtVpath *vec; - gint vec_n, vec_n_max; - gint bez_index; - gdouble x, y; - - vec_n = 0; - vec_n_max = RENDER_SIZE; - vec = art_new (ArtVpath, vec_n_max); - - /* Initialization is unnecessary because of the precondition that the - bezier path does not begin with LINETO or CURVETO, but is here - to make the code warning-free. */ - x = 0; - y = 0; - - bez_index = 0; - do - { - /* make sure space for at least one more code */ - if (vec_n >= vec_n_max) - art_expand (vec, ArtVpath, vec_n_max); - switch (bez[bez_index].code) - { - case ART_MOVETO_OPEN: - case ART_MOVETO: - case ART_LINETO: - x = bez[bez_index].x3; - y = bez[bez_index].y3; - vec[vec_n].code = bez[bez_index].code; - vec[vec_n].x = x; - vec[vec_n].y = y; - vec_n++; - break; - case ART_END: - vec[vec_n].code = bez[bez_index].code; - vec[vec_n].x = 0; - vec[vec_n].y = 0; - vec_n++; - break; - case ART_CURVETO: - art_vpath_render_bez (&vec, &vec_n, &vec_n_max, - x, y, - bez[bez_index].x1, bez[bez_index].y1, - bez[bez_index].x2, bez[bez_index].y2, - bez[bez_index].x3, bez[bez_index].y3, - flatness); - x = bez[bez_index].x3; - y = bez[bez_index].y3; - break; - } - } - while (bez[bez_index++].code != ART_END); - return vec; -} - diff --git a/libart_lgpl/art_vpath_bpath.h b/libart_lgpl/art_vpath_bpath.h deleted file mode 100644 index 5115ee58cf..0000000000 --- a/libart_lgpl/art_vpath_bpath.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_VPATH_BPATH_H__ -#define __ART_VPATH_BPATH_H__ - -#include <libart_lgpl/art_bpath.h> -#include <libart_lgpl/art_vpath.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -ArtPoint *art_bezier_to_vec (gdouble x0, gdouble y0, - gdouble x1, gdouble y1, - gdouble x2, gdouble y2, - gdouble x3, gdouble y3, - ArtPoint *p, - gint level); - -ArtVpath *art_bez_path_to_vec (const ArtBpath *bez, gdouble flatness); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_VPATH_BPATH_H__ */ diff --git a/libart_lgpl/art_vpath_dash.c b/libart_lgpl/art_vpath_dash.c deleted file mode 100644 index 2c54aca4a6..0000000000 --- a/libart_lgpl/art_vpath_dash.c +++ /dev/null @@ -1,199 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1999-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* Apply a dash style to a vector path. */ - -#include "config.h" -#include "art_vpath_dash.h" - -#include <math.h> -#include <stdlib.h> - -#include "art_misc.h" - -#include "art_vpath.h" - -/* Return the length of the largest subpath within vpath */ -static gint -art_vpath_dash_max_subpath (const ArtVpath *vpath) -{ - gint max_subpath; - gint i; - gint start; - - max_subpath = 0; - start = 0; - for (i = 0; vpath[i].code != ART_END; i++) - { - if (vpath[i].code == ART_MOVETO || vpath[i].code == ART_MOVETO_OPEN) - { - if (i - start > max_subpath) - max_subpath = i - start; - start = i; - } - } - if (i - start > max_subpath) - max_subpath = i - start; - - return max_subpath; -} - -/** - * art_vpath_dash: Add dash style to vpath. - * @vpath: Original vpath. - * @dash: Dash style. - * - * Creates a new vpath that is the result of applying dash style @dash - * to @vpath. - * - * This implementation has two known flaws: - * - * First, it adds a spurious break at the beginning of the vpath. The - * only way I see to resolve this flaw is to run the state forward one - * dash break at the beginning, and fix up by looping back to the - * first dash break at the end. This is doable but of course adds some - * complexity. - * - * Second, it does not suppress output points that are within epsilon - * of each other. - * - * Return value: Newly created vpath. - **/ -ArtVpath * -art_vpath_dash (const ArtVpath *vpath, const ArtVpathDash *dash) -{ - gint max_subpath; - gdouble *dists; - ArtVpath *result; - gint n_result, n_result_max; - gint start, end; - gint i; - gdouble total_dist; - - /* state while traversing dasharray - offset is offset of current dash - value, toggle is 0 for "off" and 1 for "on", and phase is the distance - in, >= 0, < dash->dash[offset]. */ - gint offset, toggle; - gdouble phase; - - /* initial values */ - gint offset_init, toggle_init; - gdouble phase_init; - - max_subpath = art_vpath_dash_max_subpath (vpath); - dists = art_new (double, max_subpath); - - n_result = 0; - n_result_max = 16; - result = art_new (ArtVpath, n_result_max); - - /* determine initial values of dash state */ - toggle_init = 1; - offset_init = 0; - phase_init = dash->offset; - while (phase_init >= dash->dash[offset_init]) - { - toggle_init = !toggle_init; - phase_init -= dash->dash[offset_init]; - offset_init++; - if (offset_init == dash->n_dash) - offset_init = 0; - } - - for (start = 0; vpath[start].code != ART_END; start = end) - { - for (end = start + 1; vpath[end].code == ART_LINETO; end++); - /* subpath is [start..end) */ - total_dist = 0; - for (i = start; i < end - 1; i++) - { - gdouble dx, dy; - - dx = vpath[i + 1].x - vpath[i].x; - dy = vpath[i + 1].y - vpath[i].y; - dists[i - start] = sqrt (dx * dx + dy * dy); - total_dist += dists[i - start]; - } - if (total_dist <= dash->dash[offset_init] - phase_init) - { - /* subpath fits entirely within first dash */ - if (toggle_init) - { - for (i = start; i < end; i++) - art_vpath_add_point (&result, &n_result, &n_result_max, - vpath[i].code, vpath[i].x, vpath[i].y); - } - } - else - { - /* subpath is composed of at least one dash - thus all - generated pieces are open */ - gdouble dist; - - phase = phase_init; - offset = offset_init; - toggle = toggle_init; - dist = 0; - i = start; - if (toggle) - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_MOVETO_OPEN, vpath[i].x, vpath[i].y); - while (i != end - 1) - { - if (dists[i - start] - dist > dash->dash[offset] - phase) - { - /* dash boundary is next */ - gdouble a; - gdouble x, y; - - dist += dash->dash[offset] - phase; - a = dist / dists[i - start]; - x = vpath[i].x + a * (vpath[i + 1].x - vpath[i].x); - y = vpath[i].y + a * (vpath[i + 1].y - vpath[i].y); - art_vpath_add_point (&result, &n_result, &n_result_max, - toggle ? ART_LINETO : ART_MOVETO_OPEN, - x, y); - /* advance to next dash */ - toggle = !toggle; - phase = 0; - offset++; - if (offset == dash->n_dash) - offset = 0; - } - else - { - /* end of line in vpath is next */ - phase += dists[i - start] - dist; - i++; - dist = 0; - if (toggle) - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_LINETO, vpath[i].x, vpath[i].y); - } - } - } - } - - art_vpath_add_point (&result, &n_result, &n_result_max, - ART_END, 0, 0); - - art_free (dists); - - return result; -} diff --git a/libart_lgpl/art_vpath_dash.h b/libart_lgpl/art_vpath_dash.h deleted file mode 100644 index 93ecea5e32..0000000000 --- a/libart_lgpl/art_vpath_dash.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1999 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_VPATH_DASH_H__ -#define __ART_VPATH_DASH_H__ - -/* Apply a dash style to a vector path. */ - -#include <libart_lgpl/art_vpath.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct _ArtVpathDash ArtVpathDash; - -struct _ArtVpathDash { - gdouble offset; - gint n_dash; - gdouble *dash; -}; - -ArtVpath * -art_vpath_dash (const ArtVpath *vpath, const ArtVpathDash *dash); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_VPATH_DASH_H__ */ diff --git a/libart_lgpl/art_vpath_svp.c b/libart_lgpl/art_vpath_svp.c deleted file mode 100644 index ceeea0ac4b..0000000000 --- a/libart_lgpl/art_vpath_svp.c +++ /dev/null @@ -1,196 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998-2000 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* "Unsort" a sorted vector path into an ordinary vector path. */ - -#include "config.h" -#include "art_vpath_svp.h" - -#include <stdio.h> /* for printf - debugging */ -#include "art_misc.h" - -#include "art_vpath.h" -#include "art_svp.h" - -typedef struct _ArtVpathSVPEnd ArtVpathSVPEnd; - -struct _ArtVpathSVPEnd { - gint seg_num; - gint which; /* 0 = top, 1 = bottom */ - gdouble x, y; -}; - -#define EPSILON 1e-6 - -static gint -art_vpath_svp_point_compare (gdouble x1, gdouble y1, gdouble x2, gdouble y2) -{ - if (y1 - EPSILON > y2) return 1; - if (y1 + EPSILON < y2) return -1; - if (x1 - EPSILON > x2) return 1; - if (x1 + EPSILON < x2) return -1; - return 0; -} - -static gint -art_vpath_svp_compare (gconstpointer s1, gconstpointer s2) -{ - const ArtVpathSVPEnd *e1 = s1; - const ArtVpathSVPEnd *e2 = s2; - - return art_vpath_svp_point_compare (e1->x, e1->y, e2->x, e2->y); -} - -/* Convert from sorted vector path representation into regular - vector path representation. - - Status of this routine: - - Basic correctness: Only works with closed paths. - - Numerical stability: Not known to work when more than two segments - meet at a point. - - Speed: Should be pretty good. - - Precision: Does not degrade precision. - -*/ -/** - * art_vpath_from_svp: Convert from svp to vpath form. - * @svp: Original #ArtSVP. - * - * Converts the sorted vector path @svp into standard vpath form. - * - * Return value: the newly allocated vpath. - **/ -ArtVpath * -art_vpath_from_svp (const ArtSVP *svp) -{ - gint n_segs = svp->n_segs; - ArtVpathSVPEnd *ends; - ArtVpath *new; - gint *visited; - gint n_new, n_new_max; - gint i, k; - gint j = 0; /* Quiet compiler */ - gint seg_num; - gint first; - gdouble last_x, last_y; - gint n_points; - gint pt_num; - - last_x = 0; /* to eliminate "uninitialized" warning */ - last_y = 0; - - ends = art_new (ArtVpathSVPEnd, n_segs * 2); - for (i = 0; i < svp->n_segs; i++) - { - gint lastpt; - - ends[i * 2].seg_num = i; - ends[i * 2].which = 0; - ends[i * 2].x = svp->segs[i].points[0].x; - ends[i * 2].y = svp->segs[i].points[0].y; - - lastpt = svp->segs[i].n_points - 1; - ends[i * 2 + 1].seg_num = i; - ends[i * 2 + 1].which = 1; - ends[i * 2 + 1].x = svp->segs[i].points[lastpt].x; - ends[i * 2 + 1].y = svp->segs[i].points[lastpt].y; - } - qsort (ends, n_segs * 2, sizeof (ArtVpathSVPEnd), art_vpath_svp_compare); - - n_new = 0; - n_new_max = 16; /* I suppose we _could_ estimate this from traversing - the svp, so we don't have to reallocate */ - new = art_new (ArtVpath, n_new_max); - - visited = art_new (int, n_segs); - for (i = 0; i < n_segs; i++) - visited[i] = 0; - - first = 1; - for (i = 0; i < n_segs; i++) - { - if (!first) - { - /* search for the continuation of the existing subpath */ - /* This could be a binary search (which is why we sorted, above) */ - for (j = 0; j < n_segs * 2; j++) - { - if (!visited[ends[j].seg_num] && - art_vpath_svp_point_compare (last_x, last_y, - ends[j].x, ends[j].y) == 0) - break; - } - if (j == n_segs * 2) - first = 1; - } - if (first) - { - /* start a new subpath */ - for (j = 0; j < n_segs * 2; j++) - if (!visited[ends[j].seg_num]) - break; - } - if (j == n_segs * 2) - { - printf ("failure\n"); - } - seg_num = ends[j].seg_num; - n_points = svp->segs[seg_num].n_points; - for (k = 0; k < n_points; k++) - { - pt_num = svp->segs[seg_num].dir ? k : n_points - (1 + k); - if (k == 0) - { - if (first) - { - art_vpath_add_point (&new, &n_new, &n_new_max, - ART_MOVETO, - svp->segs[seg_num].points[pt_num].x, - svp->segs[seg_num].points[pt_num].y); - } - } - else - { - art_vpath_add_point (&new, &n_new, &n_new_max, - ART_LINETO, - svp->segs[seg_num].points[pt_num].x, - svp->segs[seg_num].points[pt_num].y); - if (k == n_points - 1) - { - last_x = svp->segs[seg_num].points[pt_num].x; - last_y = svp->segs[seg_num].points[pt_num].y; - /* to make more robust, check for meeting first_[xy], - set first if so */ - } - } - first = 0; - } - visited[seg_num] = 1; - } - - art_vpath_add_point (&new, &n_new, &n_new_max, - ART_END, 0, 0); - art_free (visited); - art_free (ends); - return new; -} diff --git a/libart_lgpl/art_vpath_svp.h b/libart_lgpl/art_vpath_svp.h deleted file mode 100644 index 2df9641f58..0000000000 --- a/libart_lgpl/art_vpath_svp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Libart_LGPL - library of basic graphic primitives - * Copyright (C) 1998 Raph Levien - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __ART_VPATH_SVP_H__ -#define __ART_VPATH_SVP_H__ - -/* "Unsort" a sorted vector path into an ordinary vector path. */ - -#include <libart_lgpl/art_svp.h> -#include <libart_lgpl/art_vpath.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -ArtVpath *art_vpath_from_svp (const ArtSVP *svp); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __ART_VPATH_SVP_H__ */ diff --git a/libart_lgpl/libart.h b/libart_lgpl/libart.h deleted file mode 100644 index 7ab8fb384c..0000000000 --- a/libart_lgpl/libart.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef LIBART_H -#define LIBART_H 1 - -#include <libart_lgpl/art_affine.h> -#include <libart_lgpl/art_alphagamma.h> -#include <libart_lgpl/art_bpath.h> -#include <libart_lgpl/art_filterlevel.h> -#include <libart_lgpl/art_gray_svp.h> -#include <libart_lgpl/art_misc.h> -#include <libart_lgpl/art_pathcode.h> -#include <libart_lgpl/art_point.h> -#include <libart_lgpl/art_rect.h> -#include <libart_lgpl/art_rect_svp.h> -#include <libart_lgpl/art_rect_uta.h> -#include <libart_lgpl/art_rgb.h> -#include <libart_lgpl/art_rgb_affine.h> -#include <libart_lgpl/art_rgb_bitmap_affine.h> -#include <libart_lgpl/art_rgb_pixbuf_affine.h> -#include <libart_lgpl/art_rgb_rgba_affine.h> -#include <libart_lgpl/art_rgb_svp.h> -#include <libart_lgpl/art_svp.h> -#include <libart_lgpl/art_svp_ops.h> -#include <libart_lgpl/art_svp_point.h> -#include <libart_lgpl/art_svp_render_aa.h> -#include <libart_lgpl/art_svp_vpath.h> -#include <libart_lgpl/art_svp_vpath_stroke.h> -#include <libart_lgpl/art_svp_wind.h> -#include <libart_lgpl/art_uta.h> -#include <libart_lgpl/art_uta_rect.h> -#include <libart_lgpl/art_uta_svp.h> -#include <libart_lgpl/art_uta_vpath.h> -#include <libart_lgpl/art_vpath.h> -#include <libart_lgpl/art_vpath_bpath.h> -#include <libart_lgpl/art_vpath_dash.h> -#include <libart_lgpl/art_vpath_svp.h> - -#endif diff --git a/libart_lgpl/libart.m4 b/libart_lgpl/libart.m4 deleted file mode 100644 index 9380a222de..0000000000 --- a/libart_lgpl/libart.m4 +++ /dev/null @@ -1,165 +0,0 @@ -# Configure paths for LIBART -# Raph Levien 98-11-18 -# stolen from Manish Singh 98-9-30 -# stolen back from Frank Belew -# stolen from Manish Singh -# Shamelessly stolen from Owen Taylor - -dnl AM_PATH_LIBART([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for LIBART, and define LIBART_CFLAGS and LIBART_LIBS -dnl -AC_DEFUN(AM_PATH_LIBART, -[dnl -dnl Get the cflags and libraries from the libart-config script -dnl -AC_ARG_WITH(libart-prefix,[ --with-libart-prefix=PFX Prefix where LIBART is installed (optional)], - libart_prefix="$withval", libart_prefix="") -AC_ARG_WITH(libart-exec-prefix,[ --with-libart-exec-prefix=PFX Exec prefix where LIBART is installed (optional)], - libart_exec_prefix="$withval", libart_exec_prefix="") -AC_ARG_ENABLE(libarttest, [ --disable-libarttest Do not try to compile and run a test LIBART program], - , enable_libarttest=yes) - - if test x$libart_exec_prefix != x ; then - libart_args="$libart_args --exec-prefix=$libart_exec_prefix" - if test x${LIBART_CONFIG+set} != xset ; then - LIBART_CONFIG=$libart_exec_prefix/bin/libart-config - fi - fi - if test x$libart_prefix != x ; then - libart_args="$libart_args --prefix=$libart_prefix" - if test x${LIBART_CONFIG+set} != xset ; then - LIBART_CONFIG=$libart_prefix/bin/libart-config - fi - fi - - AC_PATH_PROG(LIBART_CONFIG, libart-config, no) - min_libart_version=ifelse([$1], ,0.2.5,$1) - AC_MSG_CHECKING(for LIBART - version >= $min_libart_version) - no_libart="" - if test "$LIBART_CONFIG" = "no" ; then - no_libart=yes - else - LIBART_CFLAGS=`$LIBART_CONFIG $libartconf_args --cflags` - LIBART_LIBS=`$LIBART_CONFIG $libartconf_args --libs` - - libart_major_version=`$LIBART_CONFIG $libart_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - libart_minor_version=`$LIBART_CONFIG $libart_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - libart_micro_version=`$LIBART_CONFIG $libart_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_libarttest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $LIBART_CFLAGS" - LIBS="$LIBS $LIBART_LIBS" -dnl -dnl Now check if the installed LIBART is sufficiently new. (Also sanity -dnl checks the results of libart-config to some extent -dnl - rm -f conf.libarttest - AC_TRY_RUN([ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <libart_lgpl/libart.h> - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main () -{ - int major, minor, micro; - char *tmp_version; - - system ("touch conf.libarttest"); - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_libart_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_libart_version"); - exit(1); - } - - if (($libart_major_version > major) || - (($libart_major_version == major) && ($libart_minor_version > minor)) || - (($libart_major_version == major) && ($libart_minor_version == minor) && ($libart_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'libart-config --version' returned %d.%d.%d, but the minimum version\n", $libart_major_version, $libart_minor_version, $libart_micro_version); - printf("*** of LIBART required is %d.%d.%d. If libart-config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If libart-config was wrong, set the environment variable LIBART_CONFIG\n"); - printf("*** to point to the correct copy of libart-config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - -],, no_libart=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_libart" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$LIBART_CONFIG" = "no" ; then - echo "*** The libart-config script installed by LIBART could not be found" - echo "*** If LIBART was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the LIBART_CONFIG environment variable to the" - echo "*** full path to libart-config." - else - if test -f conf.libarttest ; then - : - else - echo "*** Could not run LIBART test program, checking why..." - CFLAGS="$CFLAGS $LIBART_CFLAGS" - LIBS="$LIBS $LIBART_LIBS" - AC_TRY_LINK([ -#include <stdio.h> -#include <libart_lgpl/libart.h> -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding LIBART or finding the wrong" - echo "*** version of LIBART. If it is not finding LIBART, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means LIBART was incorrectly installed" - echo "*** or that you have moved LIBART since it was installed. In the latter case, you" - echo "*** may want to edit the libart-config script: $LIBART_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - LIBART_CFLAGS="" - LIBART_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(LIBART_CFLAGS) - AC_SUBST(LIBART_LIBS) - rm -f conf.libarttest -]) |